Files
agentic-dev/docs/superpowers/plans/2026-05-12-conformance-milestone-v-generator-updates.md

7.2 KiB

Conformance Milestone v — Generator updates

Goal: pnpm turbo gen feature <name> 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 + <name>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:

---
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 <name>` 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` +
  `<name>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
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:

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):

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 // <gen:event-handlers>, // <gen:jobs>, // <gen:realtime-handlers> anchor comments and BEFORE the closing } — add:

  // 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:

{
  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:

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:

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-progressdone
  • All - [ ]- [x]

Update docs/work/conformance-system-v1/_epic.md. Find:

- [ ] 05 — Generator emits manifest + contracts + test stubs (later plan)

Replace with:

- [x] [05 — Generator updates](05-generator-updates/_story.md)

Commit: docs(work): close story 05 — generator updates.