docs(work): archive shipped template epics and PRDs

Move the 8 shipped template epics and their 9 PRDs (incl.
coverage-architecture) to docs/work/archive/{epics,prds}/ so dispatch
context and prioritization only see live Veect work. The state builder
already walks docs/work/epics/ + docs/work/prds/ only; the one work-CLI
script that matched archive paths (bump-updated-timestamps.mjs, staged
docs/work/**/*.md) now excludes docs/work/archive/ so archived content
stays byte-identical.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016j8z4VHjedXDTjEDNg7qHK
This commit is contained in:
2026-07-12 17:28:21 +02:00
parent 2126fda6f8
commit 2b39ae8c0a
86 changed files with 5 additions and 757 deletions

View File

@@ -0,0 +1,45 @@
---
id: 01-wire-use-case-helper
epic: binder-wrap-helper
title: Introduce wireUseCase helper in core-shared
type: technical-story
status: done
feature: core-shared
depends-on: []
blocks: [02-migrate-feature-binders, 03-update-generator-templates]
created: 2026-05-13T19:17:10+02:00
updated: 2026-05-14T19:21:52.308Z
---
## Goal
Add `wire-use-case.ts` + `wire-use-case.test.ts` to `packages/core-shared/src/conformance/` and export the helper from the `@repo/core-shared/conformance` barrel. The helper encapsulates `withSpan(withCapture(withAudit?(factory(deps))))` composition and performs the container bind step, so callers pass options and get back a brand-stacked wired value.
## Why
Every feature binder currently inlines the same `withSpan + withCapture` wrapping per use case — 3079 lines of mechanical boilerplate per binder pair. A single helper in core-shared eliminates the structural clone groups and makes adjusting the wrapping shape a one-file change.
## Done when
- `packages/core-shared/src/conformance/wire-use-case.ts` exists and is exported from `packages/core-shared/src/conformance/index.ts`.
- `wire-use-case.test.ts` covers: no-audit path (Instrumented + Captured brands present), audit path (Instrumented + Captured + Audited brands present), span-name derivation (`<feature>.<name>`), capture-tag structure (`{ feature, layer, name }`), container binding (symbol resolves to wired value), idempotent re-bind (unbind + bind when symbol already bound).
- `pnpm typecheck && pnpm test && pnpm lint && pnpm conformance && pnpm fallow:audit && pnpm coverage:diff` all pass.
- `wire-use-case.ts` reaches 100% statement/branch coverage (file is small; exhaustive test coverage is achievable).
## In scope
- `packages/core-shared/src/conformance/wire-use-case.ts` — the helper and its exported types.
- `packages/core-shared/src/conformance/wire-use-case.test.ts` — unit tests using `RecordingTracer` / `RecordingLogger` / `RecordingAuditLog` (or equivalent mocks from core-shared/core-audit).
- Export line added to `packages/core-shared/src/conformance/index.ts`.
- No changes to `withSpan`, `withCapture`, or `withAudit` internals — the helper composes them as-is.
## Out of scope
- Feature binder changes (Story 02).
- Generator template changes (Story 03).
- `wireController` peer — the `layer` discriminator in `wireUseCase` covers controllers too if the shapes converge; a separate peer is a follow-up if needed.
- Repository or service binding patterns.
## Tasks
- [x] Add `wire-use-case.ts` + `wire-use-case.test.ts` to `packages/core-shared/src/conformance/` and export from the conformance index — implement the helper (options object: `container`, `symbol`, `factory`, `deps`, `feature`, `layer`, `name`, `tracer`, `logger`, optional `auditLog`) with full unit tests covering both audit and no-audit paths, brand presence assertions via `isInstrumented` / `isCaptured` / `isAudited`, container binding, and idempotent re-bind; all gates pass on this single commit.

View File

@@ -0,0 +1,50 @@
---
id: 02-migrate-feature-binders
epic: binder-wrap-helper
title: Migrate all five feature binders to wireUseCase
type: technical-story
status: done
feature: auth, blog, media, marketing-pages, navigation
depends-on: [01-wire-use-case-helper]
blocks: []
created: 2026-05-13T19:17:10+02:00
updated: 2026-05-14T19:21:52.308Z
---
## Goal
Replace every inline `withSpan + withCapture (+ withAudit)` block in each feature's `bind-production.ts` and `bind-dev-seed.ts` with a call to `wireUseCase`. Existing binder-level and integration tests must continue to pass unchanged. Each feature migrates in its own commit.
## Why
The five inline wrapping clone groups are the top source of duplication reported by `pnpm fallow`. Moving to `wireUseCase` eliminates all five clone groups and leaves each binder as decision content only (which adapter, which mode, which symbol).
## Done when
- All 10 binder files (`auth ×2`, `blog ×2`, `media ×2`, `marketing-pages ×2`, `navigation ×2`) call `wireUseCase` for every use case binding; no inline `withSpan + withCapture` blocks remain for use cases.
- `assertFeatureConformance` at the tail of each `bind-production.ts` continues to accept all wired use cases (brands present, manifest entries match).
- `pnpm typecheck && pnpm test && pnpm lint && pnpm conformance && pnpm fallow:audit && pnpm coverage:diff` pass after each per-feature commit.
- `pnpm fallow dupes` no longer shows the five binder-pair clone groups in its output.
## In scope
- `packages/auth/src/di/bind-production.ts` + `bind-dev-seed.ts` — 3 use cases (signIn, signUp, signOut).
- `packages/blog/src/di/bind-production.ts` + `bind-dev-seed.ts` — 3 use cases (getArticles, getArticleBySlug, createArticle).
- `packages/media/src/di/bind-production.ts` + `bind-dev-seed.ts` — 3 use cases (getMedia, listMedia, deleteMedia).
- `packages/marketing-pages/src/di/bind-production.ts` + `bind-dev-seed.ts` — 2 use cases (getPageBySlug, getSiteSettings).
- `packages/navigation/src/di/bind-production.ts` + `bind-dev-seed.ts` — 1 use case (getHeader).
- If any binder's existing tests assert on internal wrapping shape rather than observable behaviour, refactor those assertions to test through the helper's contract (same commit as the binder change).
## Out of scope
- Controller bindings — covered by the helper per the PRD but deferred to a follow-up if scope is a concern.
- Repository and service bindings — stay as direct `.toConstantValue()` calls.
- Apps' `bindAll()` dispatcher — untouched.
## Tasks
- [x] Migrate `auth` binders (`bind-production.ts` + `bind-dev-seed.ts`) to `wireUseCase` for all 3 use cases (signIn, signUp, signOut); all gates pass on this commit.
- [x] Migrate `blog` binders to `wireUseCase` for all 3 use cases (getArticles, getArticleBySlug, createArticle); all gates pass on this commit.
- [x] Migrate `media` binders to `wireUseCase` for all 3 use cases (getMedia, listMedia, deleteMedia); all gates pass on this commit.
- [x] Migrate `marketing-pages` binders to `wireUseCase` for both use cases (getPageBySlug, getSiteSettings); all gates pass on this commit.
- [x] Migrate `navigation` binders to `wireUseCase` for the single use case (getHeader); all gates pass on this commit; verify `pnpm fallow dupes` no longer surfaces the five binder-pair clone groups.

View File

@@ -0,0 +1,41 @@
---
id: 03-update-generator-templates
epic: binder-wrap-helper
title: Update feature generator templates to emit wireUseCase call shape
type: technical-story
status: done
feature: core-shared
depends-on: [01-wire-use-case-helper]
blocks: []
created: 2026-05-13T19:17:10+02:00
updated: 2026-05-14T19:21:52.308Z
---
## Goal
Update `turbo/generators/templates/feature/src/di/bind-production.ts.hbs` and `bind-dev-seed.ts.hbs` so that `pnpm turbo gen feature` scaffolds new features with `wireUseCase` calls instead of the longhand inline `withSpan + withCapture` form.
## Why
New features scaffolded after the migration would otherwise drift back to the inline form, re-introducing the clone group. The generator is the canonical source for scaffolded binder shape; updating it closes the loop.
## Done when
- `turbo/generators/templates/feature/src/di/bind-production.ts.hbs` emits `wireUseCase(...)` calls (not inline `withSpan + withCapture`) for the placeholder use case.
- `turbo/generators/templates/feature/src/di/bind-dev-seed.ts.hbs` emits `wireUseCase(...)` calls for the placeholder use case.
- Running `pnpm turbo gen feature testfeature` produces binder files that call `wireUseCase` and pass `pnpm typecheck && pnpm lint && pnpm test && pnpm conformance && pnpm fallow:audit && pnpm coverage:diff` (or the generated feature is cleaned up after verification).
## In scope
- `turbo/generators/templates/feature/src/di/bind-production.ts.hbs`
- `turbo/generators/templates/feature/src/di/bind-dev-seed.ts.hbs`
- Any supporting type imports in the templates that change as a result (e.g. dropping `ProductionUseCase` intermediate type if the helper absorbs it).
## Out of scope
- Generator templates for events, jobs, realtime, or core-packages — those do not produce binder files with use-case wrapping.
- Runtime behaviour changes — the generated output must be semantically equivalent to the old inline form.
## Tasks
- [x] Update `bind-production.ts.hbs` and `bind-dev-seed.ts.hbs` in `turbo/generators/templates/feature/src/di/` to emit `wireUseCase` calls; verify a test-scaffold of a new feature produces correct binder output and all gates pass on this commit.

View File

@@ -0,0 +1,24 @@
---
id: binder-wrap-helper
prd: docs/work/prds/binder-wrap-helper.prd.md
title: Collapse binder duplication via wireUseCase helper
type: epic
status: done
features: [core-shared, auth, blog, media, marketing-pages, navigation]
created: 2026-05-13T00:00:00Z
updated: 2026-05-14T19:21:52.308Z
---
## Goal
Introduce a `wireUseCase(...)` helper in `@repo/core-shared/conformance/` that encapsulates the `withSpan + withCapture (+ optional withAudit)` composition. Refactor all five features' binders to call the helper. Update the feature generator templates to emit the new call shape by default.
## Why
Five of `pnpm fallow`'s top-ten clone groups come from binder pairs across features. The inline wrapping runs 3079 duplicated lines per binder pair. The helper becomes the single source of truth for the wrapping shape; per-feature binders shrink to their decision content plus a list of `wireUseCase` calls.
## Stories
- [x] [01 — Introduce `wireUseCase` helper in core-shared](01-wire-use-case-helper/_story.md)
- [x] [02 — Migrate all five feature binders to `wireUseCase`](02-migrate-feature-binders/_story.md)
- [x] [03 — Update generator templates to emit `wireUseCase` call shape](03-update-generator-templates/_story.md)