feat(conformance): implement ReadOnly brand and reader generator

- Add ReadOnly<F> phantom brand to core-shared/conformance (compile-time
  enforcement that readers only wrap non-mutating use cases)
- Add isReadOnly runtime predicate for boot-time assertReaderPurity
- Scaffold pnpm turbo gen reader: creates integrations/readers/ with
  interface, implementation, test, barrel, and adds ./reader export
  subpath to package.json
This commit is contained in:
danijel-lf
2026-05-28 22:01:51 +02:00
parent b97e6105d3
commit 5b74939a51
8 changed files with 187 additions and 2 deletions

View File

@@ -13,7 +13,7 @@
* commitment, not a mutable flag.
*/
import type { Analyzed, ConsentChecked, RateLimited } from "./brands";
import type { Analyzed, ConsentChecked, RateLimited, ReadOnly } from "./brands";
type Brand =
| "__instrumented"
@@ -21,7 +21,8 @@ type Brand =
| "__audited"
| "__analyzed"
| "__consentChecked"
| "__rateLimited";
| "__rateLimited"
| "__readonly";
/**
* Attaches the brand as a non-enumerable property on the given function.
@@ -75,3 +76,7 @@ export function isRateLimited<F extends object>(
): fn is RateLimited<F> {
return hasBrand(fn, "__rateLimited");
}
export function isReadOnly<F extends object>(fn: unknown): fn is ReadOnly<F> {
return hasBrand(fn, "__readonly");
}

View File

@@ -12,3 +12,9 @@ export type Captured<F> = F & { readonly __captured: true };
export type Analyzed<F> = F & { readonly __analyzed: true };
export type ConsentChecked<F> = F & { readonly __consentChecked: true };
export type RateLimited<F> = F & { readonly __rateLimited: true };
/**
* Brand for use cases declared `mutates: false`. Readers only accept
* `ReadOnly`-branded use cases in their constructor — prevents mutating
* use cases from being wired into a reader at compile time.
*/
export type ReadOnly<F> = F & { readonly __readonly: true };

View File

@@ -4,6 +4,7 @@ export type {
Analyzed,
ConsentChecked,
RateLimited,
ReadOnly,
} from "./brands";
export type { FeatureManifest, UseCaseManifest } from "./define-feature";
export { defineFeature } from "./define-feature";
@@ -31,6 +32,7 @@ export {
isAnalyzed,
isConsentChecked,
isRateLimited,
isReadOnly,
} from "./brand-runtime";
export { ConformanceError } from "./conformance-error";
export { assertFeatureConformance } from "./assert-bindings";