From 19611fb92c8ee92ea0bb2be0e0f9f15aec5b3a10 Mon Sep 17 00:00:00 2001 From: Danijel Martinek Date: Wed, 13 May 2026 00:00:32 +0200 Subject: [PATCH] =?UTF-8?q?plan(conformance):=20milestone=20v=20=E2=80=94?= =?UTF-8?q?=20generator=20updates?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...nformance-milestone-v-generator-updates.md | 213 ++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 docs/superpowers/plans/2026-05-12-conformance-milestone-v-generator-updates.md diff --git a/docs/superpowers/plans/2026-05-12-conformance-milestone-v-generator-updates.md b/docs/superpowers/plans/2026-05-12-conformance-milestone-v-generator-updates.md new file mode 100644 index 0000000..9f21be8 --- /dev/null +++ b/docs/superpowers/plans/2026-05-12-conformance-milestone-v-generator-updates.md @@ -0,0 +1,213 @@ +# Conformance Milestone v — Generator updates + +**Goal:** `pnpm turbo gen feature ` now emits a `feature.manifest.ts` declaring the scaffolded use case, and the scaffolded `bind-production.ts` calls `assertFeatureConformance` at its tail. New features are conformance-compliant from creation. + +**Architecture:** Two template additions/changes in `turbo/generators/templates/feature/`: +1. NEW: `src/feature.manifest.ts.hbs` — emits `defineFeature({...})` with the scaffolded use case declared +2. UPDATE: `src/di/bind-production.ts.hbs` — adds imports for `assertFeatureConformance` + `Manifest` and calls the assertion at the tail + +Plus one `config.ts` action to emit the manifest template, and snapshot regeneration if the existing tests snapshot the full file tree. + +--- + +## Tasks + +### Task 1: Story 05 scaffold + +Create `docs/work/conformance-system-v1/05-generator-updates/_story.md`: + +```markdown +--- +id: 05-generator-updates +epic: conformance-system-v1 +title: Generator updates — emit feature.manifest.ts + self-asserting bind-production +type: technical-story +status: in-progress +feature: turbo-generators +depends-on: [04-ci-drift-gate] +blocks: [06-feature-migrations] +--- + +## Goal +`pnpm turbo gen feature ` produces a feature that's conformance- +compliant out of the box: ships a `feature.manifest.ts` declaring the +scaffolded use case, and the scaffolded `bind-production.ts` calls +`assertFeatureConformance` at its tail. + +## Why +Today, generating a new feature does NOT emit a manifest, so +`feature-must-have-manifest` would warn the moment the developer saves. +And `bindProductionX` doesn't self-assert. New features should be +conformance-ready by default. + +## Done when +- `feature.manifest.ts.hbs` template exists, declaring the scaffolded + `getX` use case with mutates: false / empty arrays +- `bind-production.ts.hbs` imports `assertFeatureConformance` + + `Manifest` and calls the assertion at the tail +- `config.ts` action emits the manifest file +- Running `pnpm turbo gen feature demo` into a tmp dir produces a + feature directory containing a valid `feature.manifest.ts` +- Existing snapshot tests pass (regenerate snapshots if needed) + +## In scope +- Manifest template +- bind-production template update +- config.ts action wiring +- Snapshot regen + +## Out of scope +- Multi-use-case feature scaffolding +- Generator changes to other generators (event/job/realtime) +- Backfilling manifests for existing features (milestone vi) + +## Tasks +- [ ] Story scaffold +- [ ] feature.manifest.ts.hbs template +- [ ] bind-production.ts.hbs update +- [ ] config.ts action wiring +- [ ] Run generator into tmp; verify shape +- [ ] Snapshot regen (if needed) + verify tests pass +- [ ] Final verification + closeout +``` + +```bash +git add docs/work/conformance-system-v1/05-generator-updates/_story.md +git commit -m "docs(work): story 05 — generator updates" +``` + +### Task 2: `feature.manifest.ts.hbs` template + +Create `turbo/generators/templates/feature/src/feature.manifest.ts.hbs`: + +```hbs +import { defineFeature } from "@repo/core-shared/conformance"; + +/** + * The {{camelCase name}} feature's conformance manifest. Drives binding-slot + * types in `di/bind-production.ts` and is read by ESLint, the boot + * assertion, and the CI drift gate. + * + * Conventions: + * - `mutates: true` for any use case that creates, updates, or deletes state + * - `audits` lists every audit event the use case emits (must match calls + * to `auditLog.record(...)` in the factory body — ESLint enforces this) + * - `publishes` / `consumes` cover cross-feature events through `IEventBus` + */ +export const {{camelCase name}}Manifest = defineFeature({ + name: "{{kebabCase name}}", + requiredCores: [], + useCases: { + get{{pascalCase entity}}: { + mutates: false, + audits: [], + publishes: [], + consumes: [], + }, + }, + realtimeChannels: [], + jobs: [], +} as const); + +export type {{pascalCase name}}Manifest = typeof {{camelCase name}}Manifest; +``` + +(No test file for the template itself; the generator's existing snapshot tests will cover that the file is emitted with expected content.) + +### Task 3: `bind-production.ts.hbs` update — call assertFeatureConformance at tail + +Modify `turbo/generators/templates/feature/src/di/bind-production.ts.hbs`. Add three new imports at the top (after the existing imports): + +```hbs +import { assertFeatureConformance } from "@repo/core-shared/conformance"; +import { {{camelCase name}}Manifest } from "../feature.manifest"; +``` + +At the very end of the `bindProduction{{pascalCase name}}` function body — AFTER the `// `, `// `, `// ` anchor comments and BEFORE the closing `}` — add: + +```hbs + // Boot-time conformance check: refuses to start if any use-case binding + // is missing a required brand (withSpan / withCapture / withAudit). + assertFeatureConformance( + {{camelCase name}}Container, + {{camelCase name}}Manifest, + { + get{{pascalCase entity}}: {{constantCase name}}_SYMBOLS.IGet{{pascalCase entity}}UseCase, + }, + ctx, + ); +``` + +### Task 4: `config.ts` action wiring — emit the manifest + +Open `turbo/generators/config.ts`. Find the `actions` array for the `feature` generator. After the action that emits `src/index.ts` (or in the appropriate position with other `src/` files), add an action to emit `src/feature.manifest.ts` from the new template: + +```ts +{ + type: "add", + path: "{{ turbo_paths.root }}/packages/{{kebabCase name}}/src/feature.manifest.ts", + templateFile: "templates/feature/src/feature.manifest.ts.hbs", +}, +``` + +If the existing actions use a different path-resolution pattern (e.g., `path.join(...)`), match that pattern. Read the surrounding actions before adding. + +### Task 5: Run the generator into tmp + verify + +Run a generator invocation against a tmp dir to confirm the output: + +```bash +cd /tmp && rm -rf gen-test && mkdir gen-test && cd gen-test +# Initialize an empty turbo repo-like structure: +mkdir -p packages +ln -s /Users/danijel/Documents/Projects/template-vertical/.claude/worktrees/conformance-milestone-v/turbo . +``` + +Actually, the simpler path: run the existing snapshot tests, which already exercise the generator: + +``` +pnpm --filter @repo/turbo-generators test +``` + +If they pass (likely with snapshot mismatches because we added a new file), regenerate snapshots: + +``` +pnpm --filter @repo/turbo-generators test -- -u +``` + +Verify the regenerated snapshots include `src/feature.manifest.ts` and the updated bind-production with the assertion at the tail. + +Commit the regenerated snapshots: +```bash +git add turbo/generators/__snapshots__/ turbo/generators/templates/ turbo/generators/config.ts +git commit -m "feat(generators): emit feature.manifest.ts + self-asserting bind-production" +``` + +### Task 6: Final verification + closeout + +Run: +``` +pnpm typecheck +pnpm test +pnpm lint +pnpm conformance +pnpm turbo boundaries +``` + +All five pass. + +Update `docs/work/conformance-system-v1/05-generator-updates/_story.md`: +- frontmatter `status: in-progress` → `done` +- All `- [ ]` → `- [x]` + +Update `docs/work/conformance-system-v1/_epic.md`. Find: +```markdown +- [ ] 05 — Generator emits manifest + contracts + test stubs (later plan) +``` + +Replace with: +```markdown +- [x] [05 — Generator updates](05-generator-updates/_story.md) +``` + +Commit: `docs(work): close story 05 — generator updates`.