diff --git a/docs/work/conformance-system-v1/02-boot-assertions/_story.md b/docs/work/conformance-system-v1/02-boot-assertions/_story.md new file mode 100644 index 0000000..e9e81f8 --- /dev/null +++ b/docs/work/conformance-system-v1/02-boot-assertions/_story.md @@ -0,0 +1,65 @@ +--- +id: 02-boot-assertions +epic: conformance-system-v1 +title: assertFeatureConformance + boot wiring +type: technical-story +status: in-progress +feature: core-shared +depends-on: [01-define-feature-helper] +blocks: [03-eslint-rules] +--- + +## Goal +Runtime boot-time verification that every manifest-declared use case is bound +through the brand-attaching wrappers. Each feature's `bindProductionX(ctx)` +self-asserts at the tail; `pnpm dev` refuses to boot on drift. + +## Why +Type casts can mask unwrapped factories; manifest edits can drift from +binders without TypeScript noticing. Boot assertions catch what the type +system can't see — at zero cost during the inner agent feedback loop, and +synchronously at startup so failures fire loudly. + +## Done when +- `withSpan`, `withCapture`, `withAudit` attach non-enumerable runtime markers + matching the type-level brand names +- `assertFeatureConformance(container, manifest, symbols, ctx)` resolves each + manifest use case and throws `ConformanceError` on a missing brand +- `auth.bindProductionAuth(ctx)` self-asserts at the tail +- `pnpm dev` boots cleanly for the existing `auth` wiring; rebinding `signIn` + with an unwrapped factory causes `pnpm dev` to throw at startup + +## In scope +- Runtime marker attachment via `Object.defineProperty(fn, "__brand", { … })` + (non-enumerable, non-writable, non-configurable) +- `isInstrumented` / `isCaptured` / `isAudited` predicates +- `ConformanceError` class (extends `Error`) +- `assertFeatureConformance(container, manifest, symbols, ctx)` helper +- Wiring into `packages/auth/src/di/bind-production.ts` (tail-of-binder + self-assertion) +- `withAudit` upgraded from passthrough to a thin wrapper that attaches its + runtime brand without changing observable behaviour + +## Out of scope +- `assertConformance` over a multi-feature container collection at the app's + `bindAll()` (current per-feature self-assertion is sufficient and + forward-compatible) +- Wiring boot assertions into `cms` and `web-tanstack` — neither has a + `bind-production.ts` yet; they'll inherit the check whenever they grow one +- Manifests for `blog`, `media`, `navigation`, `marketing-pages` (their + `bindProductionX` stays unchanged in this story) +- Automated audit recording driven by manifest `audits[]` declarations + (deferred to a later story) + +## Tasks +- [ ] Re-export `authManifest` from auth root barrel +- [ ] TODO breadcrumb in `withAudit` pointing at future automation +- [ ] Runtime marker helpers (`attachBrand`, `isInstrumented`, `isCaptured`, `isAudited`) +- [ ] `withSpan` attaches runtime `__instrumented` marker +- [ ] `withCapture` attaches runtime `__captured` marker +- [ ] `withAudit` wraps + attaches runtime `__audited` marker +- [ ] `ConformanceError` class +- [ ] `assertFeatureConformance` helper + tests +- [ ] Conformance barrel + subpath exports updated +- [ ] `bindProductionAuth` self-asserts at the tail +- [ ] Final verification + story closeout