From 5cc59e79db5259d97a0577d3ca37f46a0206cc15 Mon Sep 17 00:00:00 2001 From: Danijel Martinek Date: Wed, 13 May 2026 07:27:04 +0200 Subject: [PATCH 1/8] docs(work): scaffold agent-workflow-docs-v1 epic + story 01 --- .../01-docs-rewrite/_story.md | 42 +++++++++++++++++++ docs/work/agent-workflow-docs-v1/_epic.md | 36 ++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 docs/work/agent-workflow-docs-v1/01-docs-rewrite/_story.md create mode 100644 docs/work/agent-workflow-docs-v1/_epic.md diff --git a/docs/work/agent-workflow-docs-v1/01-docs-rewrite/_story.md b/docs/work/agent-workflow-docs-v1/01-docs-rewrite/_story.md new file mode 100644 index 0000000..8b3c3d3 --- /dev/null +++ b/docs/work/agent-workflow-docs-v1/01-docs-rewrite/_story.md @@ -0,0 +1,42 @@ +--- +id: 01-docs-rewrite +epic: agent-workflow-docs-v1 +title: Surface conformance system across top-level docs +type: technical-story +status: in-progress +feature: docs +depends-on: [] +blocks: [] +--- + +## Goal +Update CLAUDE.md, AGENTS.md, and four guides so agents picking up this +repo discover and follow the manifest-first workflow by default. + +## Done when +- CLAUDE.md has a "Conformance system" section + manifest-first ordering + added to Key Conventions +- AGENTS.md's per-feature conventions mention the manifest contract +- adding-a-feature.md updated to the 4-step ordering +- scaffolding-a-feature.md notes the manifest emission + boot assertion +- tdd-workflow.md links to the conformance enforcement +- New conformance-quickref.md exists as a single-page agent reference + +## In scope +Mechanical doc updates pointing at existing artifacts (the design doc, the +feature-conformance-explainer.html, the actual rules / wrappers / script +already merged). + +## Out of scope +- Rewriting the existing architecture docs (already in place) +- Updating per-package AGENTS.md inside packages/* + +## Tasks +- [ ] Epic + story scaffold +- [ ] CLAUDE.md update +- [ ] AGENTS.md update +- [ ] adding-a-feature.md update +- [ ] scaffolding-a-feature.md update +- [ ] tdd-workflow.md update +- [ ] conformance-quickref.md (new) +- [ ] Final verification + closeout diff --git a/docs/work/agent-workflow-docs-v1/_epic.md b/docs/work/agent-workflow-docs-v1/_epic.md new file mode 100644 index 0000000..5f4a45f --- /dev/null +++ b/docs/work/agent-workflow-docs-v1/_epic.md @@ -0,0 +1,36 @@ +--- +id: agent-workflow-docs-v1 +prd: null +title: Agent-workflow docs rollout +type: epic +status: in-progress +features: [docs] +created: 2026-05-13 +--- + +## Goal +Surface the conformance-system-v1 mechanics across CLAUDE.md, AGENTS.md, +and the feature-development guides so agents picking up this codebase +follow the manifest-first workflow by default. + +## Why +The conformance system is the substrate, but agents read the top-level +docs first. Until the docs say "feature.manifest.ts exists, here's what +it does, here's how the gates fire," the system stays invisible to +agents iterating on this repo for the first time. + +## In scope +- CLAUDE.md: add conformance system section + manifest-first ordering +- AGENTS.md: add manifest convention to per-package conventions +- docs/guides/adding-a-feature.md: update workflow to manifest → contracts → tests → code +- docs/guides/scaffolding-a-feature.md: note that generator now emits manifest + boot assertion +- docs/guides/tdd-workflow.md: link conformance system as the enforcement layer +- New docs/guides/conformance-quickref.md: ~80-line agent-facing reference + +## Out of scope +- Frontend-conformance docs (next epic) +- Work-system-v1 docs (those land with the work-system epic) +- Editing the original conformance design docs (already in place) + +## Stories +- [ ] [01 — Surface conformance system across CLAUDE.md / AGENTS.md / guides](01-docs-rewrite/_story.md) From 3c810decb2482e95cd58a4ca15cf2689618f3e8b Mon Sep 17 00:00:00 2001 From: Danijel Martinek Date: Wed, 13 May 2026 07:27:26 +0200 Subject: [PATCH 2/8] docs: CLAUDE.md surfaces conformance system + manifest-first ordering --- CLAUDE.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/CLAUDE.md b/CLAUDE.md index 91d753a..368d9f0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -44,6 +44,21 @@ Turborepo + pnpm monorepo organized by vertical features. Each feature (`auth`, - `docs/guides/audit-and-compliance.md` — DPA-compliant audit logging cookbook (*requires `gen core-package audit`*) - `docs/architecture/template-tiers.md` — must-have vs optional packages and how to scaffold the optionals +## Conformance system + +Every feature has a `src/feature.manifest.ts` declaring its use cases, audits, publishes, consumes, and required cores. Drift is caught at four latencies: + +| Layer | Latency | Catches | +|---|---|---| +| **TypeScript brands** | 0s | forgotten `withSpan` / `withCapture` / `withAudit` at bind time | +| **ESLint rules** | <1s | manifest ↔ code drift; undeclared `bus.publish` / `auditLog.record`; missing manifest; missing sibling test | +| **Boot assertion** (`pnpm dev`) | ~3s | binding without required brand at runtime; manifest edited without rebinder | +| **CI drift gate** (`pnpm conformance`) | ~120s | orphan event consumers across features | + +The five conformance ESLint rules: `feature-must-have-manifest` (error), `usecase-must-have-test-file` (error), `required-cores-installed` (error), `no-undeclared-event-publish` (warn), `no-undeclared-audit` (warn). + +See `docs/architecture/agent-first-workflow-and-conformance.md` for the full design and `docs/guides/conformance-quickref.md` for the day-to-day reference. + ## Key Conventions - **Relative imports in `src/`** — Source files use relative paths (`../repositories/...`), not `@/` alias @@ -74,6 +89,9 @@ Turborepo + pnpm monorepo organized by vertical features. Each feature (`auth`, - **Realtime is for state delivery, not for replacing tRPC (R0)** — Persistent request/response operations belong on tRPC procedures. Use realtime when the server needs to push without a request or the data is too high-frequency for HTTP - **Realtime channel descriptors are exported; handlers are private (R1)** — A feature's `realtime/.channel.ts` is re-exported from the root barrel; `realtime/handlers/*.handler.ts` is wired only in bind-* files and never re-exported (ESLint-enforced via `no-realtime-handler-reexport`) - **`socket.io` lives in `@repo/core-realtime` only (R2)** — Feature packages MUST NOT import `socket.io` or `socket.io-client`. ESLint rule `no-direct-socket-io` enforces this; allowlist covers `core-realtime/src/socket-io-*.ts` and `apps/*/server.ts` +- **Manifest-first ordering** — for any new use case, the workflow is **(1) manifest entry** → **(2) contracts** (`xInputSchema`, `xOutputSchema`, `IXUseCase`) → **(3) tests (red)** → **(4) implementation (green)**. The generator emits the manifest + a self-asserting `bind-production.ts` so new features are conformance-compliant by default +- **Self-asserting `bindProductionX(ctx)`** — every feature's bind-production calls `assertFeatureConformance(container, manifest, symbols, ctx)` at its tail. `pnpm dev` refuses to boot on drift +- **`pnpm conformance`** — cross-feature event-closure check; fails CI on orphan consumers ## MCP Servers From 0a2c570a691a2bebbe06f8d5f2a96f0d9be770a3 Mon Sep 17 00:00:00 2001 From: Danijel Martinek Date: Wed, 13 May 2026 07:27:37 +0200 Subject: [PATCH 3/8] docs: AGENTS.md notes per-feature manifest contract --- AGENTS.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index 3e62041..5e76dc9 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -366,6 +366,22 @@ Each feature binder signature is `(ctx: BindProductionContext): void` for produc --- +### Conformance contract (every feature) + +Every feature package MUST declare a `src/feature.manifest.ts` using `defineFeature` from `@repo/core-shared/conformance`. The manifest declares the use cases, what they audit/publish/consume, and which optional cores they require. + +The feature's `src/di/bind-production.ts` MUST call `assertFeatureConformance(container, manifest, symbols, ctx)` at the tail of `bindProduction` so `pnpm dev` refuses to boot if a binding loses its brand. + +Re-export the manifest from `src/index.ts`: + +```ts +export { fooManifest, type FooManifest } from "./feature.manifest"; +``` + +See `docs/guides/conformance-quickref.md` for the canonical pattern; the generator (`pnpm turbo gen feature `) emits all of this correctly by default. + +--- + ### Cross-feature events and background jobs (Plan 10, ADR-015) Three rules: From cc6f87e6e2ce713fe48464c2ab7183a65bea6865 Mon Sep 17 00:00:00 2001 From: Danijel Martinek Date: Wed, 13 May 2026 07:27:52 +0200 Subject: [PATCH 4/8] docs(guides): adding-a-feature reflects manifest-first ordering --- docs/guides/adding-a-feature.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/guides/adding-a-feature.md b/docs/guides/adding-a-feature.md index 3316083..74c525c 100644 --- a/docs/guides/adding-a-feature.md +++ b/docs/guides/adding-a-feature.md @@ -25,6 +25,21 @@ per-use-case patterns below. --- +## Workflow ordering + +For any new use case, follow these four steps in order: + +1. **Manifest entry** — declare the use case in `src/feature.manifest.ts` with its `mutates` flag and (initially empty) `audits` / `publishes` / `consumes` arrays. +2. **Contracts** — export `xInputSchema`, `xOutputSchema`, and the `IXUseCase` type alias from the use-case file. Factory body starts as `throw new Error("not implemented")`. +3. **Tests (red)** — write the failing test that exercises the contract via the factory + a mock repository. +4. **Implementation (green)** — fill the factory body until the tests pass. + +The `feature-must-have-manifest` ESLint rule will catch step 1 omissions; `usecase-must-have-test-file` catches step 3. The boot assertion (`assertFeatureConformance` at the tail of `bindProductionX`) catches forgotten wrappers at startup. + +For the fast path, run `pnpm turbo gen feature ` — the generator emits the manifest + contracts + bind-production with the assertion already wired in. + +--- + ## 1. Overview Every feature package owns: From efcb65e726c73fd83c63d3052521804aad8145ba Mon Sep 17 00:00:00 2001 From: Danijel Martinek Date: Wed, 13 May 2026 07:28:02 +0200 Subject: [PATCH 5/8] docs(guides): scaffolding-a-feature notes conformance-ready output --- docs/guides/scaffolding-a-feature.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/guides/scaffolding-a-feature.md b/docs/guides/scaffolding-a-feature.md index 500f0bc..8786747 100644 --- a/docs/guides/scaffolding-a-feature.md +++ b/docs/guides/scaffolding-a-feature.md @@ -32,6 +32,17 @@ pnpm install # link the new workspace package pnpm --filter @repo/widgets lint typecheck test ``` +## Conformance-ready by default + +Since milestone v of the conformance system, `pnpm turbo gen feature ` emits two conformance artefacts: + +- **`src/feature.manifest.ts`** declaring the scaffolded `getX` use case +- **`src/di/bind-production.ts`** with `assertFeatureConformance(...)` called at the tail + +Run `pnpm conformance` after generating a feature — it should pass cleanly. If you add `bus.publish("X")` calls in a factory body, you'll also need to add `"X"` to the manifest's `publishes[]` array for that use case, or the `no-undeclared-event-publish` ESLint rule will warn. + +See `docs/guides/conformance-quickref.md` for the manifest field reference. + ## What it generates - Package files: `package.json`, `tsconfig.json`, `vitest.config.ts`, From 798281dd144acea8009b9d4821bb64a7c99d9068 Mon Sep 17 00:00:00 2001 From: Danijel Martinek Date: Wed, 13 May 2026 07:28:16 +0200 Subject: [PATCH 6/8] docs(guides): tdd-workflow links conformance gates --- docs/guides/tdd-workflow.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/guides/tdd-workflow.md b/docs/guides/tdd-workflow.md index d450120..265ab34 100644 --- a/docs/guides/tdd-workflow.md +++ b/docs/guides/tdd-workflow.md @@ -704,3 +704,16 @@ expect(logger.captures[0]).toMatchObject({ For an end-to-end example (controller → use case → repo, all wrapped, asserting no double-capture across layers), see `packages/blog/tests/r44-no-double-capture.test.ts`. **Default mocks** (when you don't need assertions): construct `new MockArticlesRepository()` with no args — the constructor defaults bind `NoopTracer` + `NoopLogger`. + +--- + +## Conformance gates (post-TDD) + +After your tests are green and the impl is committed, four gates check that the new code stays consistent with the feature's manifest: + +1. **TypeScript brands** — the `ProductionUseCase` slot in `bind-production.ts` only accepts factories wrapped through `withSpan` + `withCapture` + (if mutating with audits) `withAudit`. +2. **ESLint rules** — five `conformance/*` rules check manifest ↔ code drift; see `docs/guides/conformance-quickref.md`. +3. **Boot assertion** — `assertFeatureConformance` runs at the tail of every `bindProductionX(ctx)`; `pnpm dev` refuses to start on drift. +4. **CI drift gate** — `pnpm conformance` runs after `pnpm lint` in CI; fails on orphan event consumers across features. + +The TDD red-green cycle covers behavioural correctness; the conformance gates cover architectural correctness. From 4966191c8bbc91ad0cdc5044be88fbb24cc36564 Mon Sep 17 00:00:00 2001 From: Danijel Martinek Date: Wed, 13 May 2026 07:28:46 +0200 Subject: [PATCH 7/8] docs(guides): conformance-quickref single-page agent reference --- docs/guides/conformance-quickref.md | 124 ++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 docs/guides/conformance-quickref.md diff --git a/docs/guides/conformance-quickref.md b/docs/guides/conformance-quickref.md new file mode 100644 index 0000000..8d6847b --- /dev/null +++ b/docs/guides/conformance-quickref.md @@ -0,0 +1,124 @@ +# Conformance system — quick reference + +Day-to-day reference for the manifest-first workflow. For design rationale see `docs/architecture/agent-first-workflow-and-conformance.md` and the interactive `feature-conformance-explainer.html`. + +--- + +## The manifest + +Every feature has one at `src/feature.manifest.ts`: + +```ts +import { defineFeature } from "@repo/core-shared/conformance"; + +export const fooManifest = defineFeature({ + name: "foo", + requiredCores: [], + useCases: { + getThing: { mutates: false, audits: [], publishes: [], consumes: [] }, + createThing: { + mutates: true, + audits: ["thing.created"], + publishes: ["foo.thing-created"], + consumes: [], + }, + }, + realtimeChannels: [], + jobs: [], +} as const); + +export type FooManifest = typeof fooManifest; +``` + +Field reference: + +| Field | Type | Meaning | +|---|---|---| +| `name` | string literal | Feature name (kebab-case, matches package name) | +| `requiredCores` | string[] | Optional cores this feature requires (e.g. `["audit", "events"]`) | +| `useCases..mutates` | boolean | True for create/update/delete; drives whether `__audited` brand is required | +| `useCases..audits` | string[] | Audit event types this use case emits via `auditLog.record({ type: "X" })` | +| `useCases..publishes` | string[] | Cross-feature events this use case publishes via `bus.publish("X")` | +| `useCases..consumes` | string[] | Cross-feature events this use case consumes (via an event handler) | +| `realtimeChannels` | string[] | Realtime channels this feature owns | +| `jobs` | string[] | Job slugs this feature enqueues | + +Re-export from `src/index.ts`: + +```ts +export { fooManifest, type FooManifest } from "./feature.manifest"; +``` + +## bindProductionX self-assertion + +Every feature's `bind-production.ts` calls the assertion at the tail: + +```ts +import { assertFeatureConformance } from "@repo/core-shared/conformance"; +import { fooManifest } from "../feature.manifest"; + +export function bindProductionFoo(ctx: BindProductionContext): void { + // ... bind use cases, wrapped with withSpan + withCapture + (if mutating + audits) withAudit ... + + assertFeatureConformance( + fooContainer, + fooManifest, + { + getThing: FOO_SYMBOLS.IGetThingUseCase, + createThing: FOO_SYMBOLS.ICreateThingUseCase, + }, + ctx, + ); +} +``` + +The symbol map declares which container symbol each manifest use-case key resolves to. + +## The four gates + +| Gate | When it fires | What it catches | Severity | +|---|---|---|---| +| `tsc` | on save | forgotten wrappers; manifest-derived slot type rejects unwrapped factory | error | +| `eslint` | on save / `pnpm lint` | manifest ↔ code drift; missing sibling test; missing manifest | error or warn | +| `pnpm dev` | at boot | binding lost its runtime brand; manifest declares more than wired | throws synchronously | +| `pnpm conformance` | CI | orphan event consumers across features | exits non-zero | + +## ESLint rules + +| Rule | Severity | What it does | +|---|---|---| +| `conformance/feature-must-have-manifest` | error | Use-case files require a sibling manifest | +| `conformance/usecase-must-have-test-file` | error | Every `*.use-case.ts` has a sibling `*.use-case.test.ts` | +| `conformance/required-cores-installed` | error | Manifest's `requiredCores` must exist as `core-` packages in pnpm-workspace.yaml | +| `conformance/no-undeclared-event-publish` | warn | `bus.publish("X")` literal must match the manifest's `publishes` for the use case | +| `conformance/no-undeclared-audit` | warn | `auditLog.record({ type: "X" })` literal must match the manifest's `audits` | + +## Workflow ordering for new use cases + +1. **Manifest** — add the use case to `feature.manifest.ts` with empty `audits` / `publishes` / `consumes` +2. **Contracts** — export `xInputSchema`, `xOutputSchema`, `IXUseCase` from the use-case file (factory body throws "not implemented") +3. **Tests (red)** — write the test importing the contracts; verify it fails +4. **Implementation (green)** — fill the factory body until tests pass + +For the fast path: `pnpm turbo gen feature ` scaffolds steps 1 + 2 in a single command. + +## Common drift patterns and the gate that catches them + +- **Forgot `withSpan` at bind time** → tsc TS2322 + boot assertion +- **Manifest declares `audits: ["X"]` but factory doesn't call `auditLog.record({type:"X"})`** → no automatic catch yet; future story +- **Factory calls `bus.publish("Y")` but manifest doesn't declare it** → `conformance/no-undeclared-event-publish` (warn) +- **Feature has use cases but no manifest** → `conformance/feature-must-have-manifest` (error) +- **Manifest references `requiredCores: ["X"]` but no `core-X` package exists** → `conformance/required-cores-installed` (error) +- **One feature consumes `Y` but no feature publishes `Y`** → `pnpm conformance` orphan check (CI gate) + +## Pinning down a drift + +When a gate fires, the error message tells you what to run. For example: + +> `Feature blog has use cases but no feature.manifest.ts. Run 'pnpm turbo gen feature blog' or scaffold the manifest manually at packages/blog/src/feature.manifest.ts.` + +That's the "fix" line — follow it. + +--- + +For the deeper design rationale see `docs/architecture/agent-first-workflow-and-conformance.md` and the interactive `feature-conformance-explainer.html`. From 87da671432e0ad9838148a7c54104758ab95cf37 Mon Sep 17 00:00:00 2001 From: Danijel Martinek Date: Wed, 13 May 2026 07:29:06 +0200 Subject: [PATCH 8/8] docs(work): close story 01 + agent-workflow-docs-v1 epic --- .../01-docs-rewrite/_story.md | 18 +++++++++--------- docs/work/agent-workflow-docs-v1/_epic.md | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/work/agent-workflow-docs-v1/01-docs-rewrite/_story.md b/docs/work/agent-workflow-docs-v1/01-docs-rewrite/_story.md index 8b3c3d3..a13a8e2 100644 --- a/docs/work/agent-workflow-docs-v1/01-docs-rewrite/_story.md +++ b/docs/work/agent-workflow-docs-v1/01-docs-rewrite/_story.md @@ -3,7 +3,7 @@ id: 01-docs-rewrite epic: agent-workflow-docs-v1 title: Surface conformance system across top-level docs type: technical-story -status: in-progress +status: done feature: docs depends-on: [] blocks: [] @@ -32,11 +32,11 @@ already merged). - Updating per-package AGENTS.md inside packages/* ## Tasks -- [ ] Epic + story scaffold -- [ ] CLAUDE.md update -- [ ] AGENTS.md update -- [ ] adding-a-feature.md update -- [ ] scaffolding-a-feature.md update -- [ ] tdd-workflow.md update -- [ ] conformance-quickref.md (new) -- [ ] Final verification + closeout +- [x] Epic + story scaffold +- [x] CLAUDE.md update +- [x] AGENTS.md update +- [x] adding-a-feature.md update +- [x] scaffolding-a-feature.md update +- [x] tdd-workflow.md update +- [x] conformance-quickref.md (new) +- [x] Final verification + closeout diff --git a/docs/work/agent-workflow-docs-v1/_epic.md b/docs/work/agent-workflow-docs-v1/_epic.md index 5f4a45f..4ac6094 100644 --- a/docs/work/agent-workflow-docs-v1/_epic.md +++ b/docs/work/agent-workflow-docs-v1/_epic.md @@ -3,7 +3,7 @@ id: agent-workflow-docs-v1 prd: null title: Agent-workflow docs rollout type: epic -status: in-progress +status: done features: [docs] created: 2026-05-13 --- @@ -33,4 +33,4 @@ agents iterating on this repo for the first time. - Editing the original conformance design docs (already in place) ## Stories -- [ ] [01 — Surface conformance system across CLAUDE.md / AGENTS.md / guides](01-docs-rewrite/_story.md) +- [x] [01 — Surface conformance system across CLAUDE.md / AGENTS.md / guides](01-docs-rewrite/_story.md)