docs(work): drop binder-wrap-helper epic for re-decomposition
The stories were decomposed by the previous (unconstrained)
decomposer prompt — their Tasks lists were horizontal sub-steps
(read file → write impl → write test → export → run gates) instead
of the slice = task = PR = commit rule now enforced in fd8265c.
Removing the folder clears the way for a fresh `pnpm work
decompose 2026-05-13-binder-wrap-helper --execute` run under the
updated prompt. The PRD itself (status: approved) is unchanged.
This commit is contained in:
@@ -1,101 +1,6 @@
|
||||
{
|
||||
"updated_at": "2026-05-13T16:10:33.562Z",
|
||||
"updated_at": "2026-05-13T16:41:39.179Z",
|
||||
"epics": {
|
||||
"binder-wrap-helper": {
|
||||
"status": "in-progress",
|
||||
"title": "Collapse binder duplication via wireUseCase helper",
|
||||
"prd": "2026-05-13-binder-wrap-helper",
|
||||
"stories": {
|
||||
"01-wire-use-case-helper": {
|
||||
"status": "in-progress",
|
||||
"title": "wireUseCase helper + tests in core-shared/conformance",
|
||||
"ac_total": 8,
|
||||
"ac_completed": 0,
|
||||
"depends_on": [],
|
||||
"blocks": []
|
||||
},
|
||||
"02-migrate-auth-binders": {
|
||||
"status": "todo",
|
||||
"title": "Migrate auth feature binders to wireUseCase",
|
||||
"ac_total": 7,
|
||||
"ac_completed": 0,
|
||||
"depends_on": [
|
||||
"01-wire-use-case-helper"
|
||||
],
|
||||
"blocks": [
|
||||
"08-holistic-validation"
|
||||
]
|
||||
},
|
||||
"03-migrate-blog-binders": {
|
||||
"status": "todo",
|
||||
"title": "Migrate blog feature binders to wireUseCase",
|
||||
"ac_total": 7,
|
||||
"ac_completed": 0,
|
||||
"depends_on": [
|
||||
"01-wire-use-case-helper"
|
||||
],
|
||||
"blocks": [
|
||||
"08-holistic-validation"
|
||||
]
|
||||
},
|
||||
"04-migrate-media-binders": {
|
||||
"status": "todo",
|
||||
"title": "Migrate media feature binders to wireUseCase",
|
||||
"ac_total": 7,
|
||||
"ac_completed": 0,
|
||||
"depends_on": [
|
||||
"01-wire-use-case-helper"
|
||||
],
|
||||
"blocks": [
|
||||
"08-holistic-validation"
|
||||
]
|
||||
},
|
||||
"05-migrate-marketing-pages-binders": {
|
||||
"status": "todo",
|
||||
"title": "Migrate marketing-pages feature binders to wireUseCase",
|
||||
"ac_total": 7,
|
||||
"ac_completed": 0,
|
||||
"depends_on": [
|
||||
"01-wire-use-case-helper"
|
||||
],
|
||||
"blocks": [
|
||||
"08-holistic-validation"
|
||||
]
|
||||
},
|
||||
"06-migrate-navigation-binders": {
|
||||
"status": "todo",
|
||||
"title": "Migrate navigation feature binders to wireUseCase",
|
||||
"ac_total": 7,
|
||||
"ac_completed": 0,
|
||||
"depends_on": [
|
||||
"01-wire-use-case-helper"
|
||||
],
|
||||
"blocks": [
|
||||
"08-holistic-validation"
|
||||
]
|
||||
},
|
||||
"07-update-feature-generator": {
|
||||
"status": "todo",
|
||||
"title": "Update feature generator template to emit wireUseCase calls",
|
||||
"ac_total": 5,
|
||||
"ac_completed": 0,
|
||||
"depends_on": [
|
||||
"01-wire-use-case-helper"
|
||||
],
|
||||
"blocks": [
|
||||
"08-holistic-validation"
|
||||
]
|
||||
},
|
||||
"08-holistic-validation": {
|
||||
"status": "todo",
|
||||
"title": "Holistic validation — green gates + fallow clone-group check",
|
||||
"ac_total": 10,
|
||||
"ac_completed": 0,
|
||||
"depends_on": [],
|
||||
"blocks": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"template-reset-v1": {
|
||||
"status": "done",
|
||||
"title": "Template reset — strip setup-process noise + archive history",
|
||||
@@ -112,67 +17,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"ready": [
|
||||
{
|
||||
"epic": "binder-wrap-helper",
|
||||
"story": "01-wire-use-case-helper",
|
||||
"title": "wireUseCase helper + tests in core-shared/conformance"
|
||||
},
|
||||
{
|
||||
"epic": "binder-wrap-helper",
|
||||
"story": "08-holistic-validation",
|
||||
"title": "Holistic validation — green gates + fallow clone-group check"
|
||||
}
|
||||
],
|
||||
"blocked": [
|
||||
{
|
||||
"epic": "binder-wrap-helper",
|
||||
"story": "02-migrate-auth-binders",
|
||||
"title": "Migrate auth feature binders to wireUseCase",
|
||||
"waiting_on": [
|
||||
"binder-wrap-helper/01-wire-use-case-helper"
|
||||
]
|
||||
},
|
||||
{
|
||||
"epic": "binder-wrap-helper",
|
||||
"story": "03-migrate-blog-binders",
|
||||
"title": "Migrate blog feature binders to wireUseCase",
|
||||
"waiting_on": [
|
||||
"binder-wrap-helper/01-wire-use-case-helper"
|
||||
]
|
||||
},
|
||||
{
|
||||
"epic": "binder-wrap-helper",
|
||||
"story": "04-migrate-media-binders",
|
||||
"title": "Migrate media feature binders to wireUseCase",
|
||||
"waiting_on": [
|
||||
"binder-wrap-helper/01-wire-use-case-helper"
|
||||
]
|
||||
},
|
||||
{
|
||||
"epic": "binder-wrap-helper",
|
||||
"story": "05-migrate-marketing-pages-binders",
|
||||
"title": "Migrate marketing-pages feature binders to wireUseCase",
|
||||
"waiting_on": [
|
||||
"binder-wrap-helper/01-wire-use-case-helper"
|
||||
]
|
||||
},
|
||||
{
|
||||
"epic": "binder-wrap-helper",
|
||||
"story": "06-migrate-navigation-binders",
|
||||
"title": "Migrate navigation feature binders to wireUseCase",
|
||||
"waiting_on": [
|
||||
"binder-wrap-helper/01-wire-use-case-helper"
|
||||
]
|
||||
},
|
||||
{
|
||||
"epic": "binder-wrap-helper",
|
||||
"story": "07-update-feature-generator",
|
||||
"title": "Update feature generator template to emit wireUseCase calls",
|
||||
"waiting_on": [
|
||||
"binder-wrap-helper/01-wire-use-case-helper"
|
||||
]
|
||||
}
|
||||
],
|
||||
"ready": [],
|
||||
"blocked": [],
|
||||
"needs_prd_ship": []
|
||||
}
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
---
|
||||
id: 01-wire-use-case-helper
|
||||
epic: binder-wrap-helper
|
||||
title: wireUseCase helper + tests in core-shared/conformance
|
||||
type: technical-story
|
||||
status: in-progress
|
||||
feature: core-shared
|
||||
depends-on: []
|
||||
blocks:
|
||||
[
|
||||
02-migrate-auth-binders,
|
||||
03-migrate-blog-binders,
|
||||
04-migrate-media-binders,
|
||||
05-migrate-marketing-pages-binders,
|
||||
06-migrate-navigation-binders,
|
||||
07-update-feature-generator,
|
||||
]
|
||||
---
|
||||
|
||||
## Goal
|
||||
|
||||
Create `packages/core-shared/src/conformance/wire-use-case.ts` exporting a `wireUseCase(...)` helper that encapsulates the `withSpan + withCapture (+ optional withAudit)` composition and performs the container bind step, then unit-test every branch.
|
||||
|
||||
## Why
|
||||
|
||||
This is the prerequisite for all migration stories. Without the helper, binders have no shared point to delegate to, and each migration story would be writing its own abstraction. The helper must land first so migration stories can be validated independently.
|
||||
|
||||
## Done when
|
||||
|
||||
- `packages/core-shared/src/conformance/wire-use-case.ts` exists with the helper and all supporting types.
|
||||
- `packages/core-shared/src/conformance/wire-use-case.test.ts` is green and covers:
|
||||
- no-audit path: Instrumented + Captured brands present on the wired value.
|
||||
- with-audit path: Instrumented + Captured + Audited brands present.
|
||||
- span name derivation: `<feature>.<name>` matches existing binder convention.
|
||||
- capture tags: `{ feature, layer, name }` correctly applied.
|
||||
- container binding idempotency: calling `wireUseCase` twice on the same symbol unbinds then rebinds without error.
|
||||
- `wireUseCase` (and its companion types) exported from `packages/core-shared/src/conformance/index.ts`.
|
||||
- `pnpm test --filter @repo/core-shared -- --coverage` green; new file hits 100%.
|
||||
- `pnpm typecheck --filter @repo/core-shared` green.
|
||||
|
||||
## In scope
|
||||
|
||||
- `wire-use-case.ts`: helper function + TypeScript generics for factory shape, deps tuple, and brand-stacked return type.
|
||||
- `wire-use-case.test.ts`: unit tests using `RecordingTracer`, `RecordingLogger`, and mock audit emitter from `core-testing` (mirror the pattern in `core-shared/instrumentation/` tests).
|
||||
- Export through `conformance/index.ts`.
|
||||
- `layer: "use-case" | "controller"` discriminator on the options object per the PRD open-question recommendation (Q1).
|
||||
- Idempotent bind logic inside the helper per Q3 recommendation.
|
||||
|
||||
## Out of scope
|
||||
|
||||
- Controller-specific helper (`wireController`) — handled via the `layer` discriminator on the single helper.
|
||||
- Repository / service binding patterns — those stay as direct `.toConstantValue()` calls.
|
||||
- Changing `withSpan`, `withCapture`, `withAudit` internals — the helper only composes them.
|
||||
- Modifying the manifest schema.
|
||||
|
||||
## Tasks
|
||||
|
||||
- [ ] Read `packages/core-shared/src/instrumentation/with-span.ts`, `with-capture.ts`, and `packages/core-audit/src/with-audit.ts` to capture exact signatures and brand attachment behaviour
|
||||
- [ ] Read `packages/core-shared/src/conformance/brands.ts` and `brand-runtime.ts` for `isInstrumented` / `isCaptured` / `isAudited` runtime helpers
|
||||
- [ ] Read `packages/core-shared/src/conformance/production-use-case.ts` for existing brand-stacking type reference
|
||||
- [ ] Write `packages/core-shared/src/conformance/wire-use-case.ts` — helper + options type + return type (no-audit and with-audit paths, `layer` discriminator, idempotent bind)
|
||||
- [ ] Write `packages/core-shared/src/conformance/wire-use-case.test.ts` — all branches: no-audit brands, with-audit brands, span name derivation, capture tags, idempotent rebind
|
||||
- [ ] Export `wireUseCase` and option/return types from `packages/core-shared/src/conformance/index.ts`
|
||||
- [ ] Run `pnpm typecheck --filter @repo/core-shared` — fix any type errors
|
||||
- [ ] Run `pnpm test --filter @repo/core-shared -- --coverage` — verify green + 100% on `wire-use-case.ts`
|
||||
@@ -1,49 +0,0 @@
|
||||
---
|
||||
id: 02-migrate-auth-binders
|
||||
epic: binder-wrap-helper
|
||||
title: Migrate auth feature binders to wireUseCase
|
||||
type: technical-story
|
||||
status: todo
|
||||
feature: auth
|
||||
depends-on: [01-wire-use-case-helper]
|
||||
blocks: [08-holistic-validation]
|
||||
---
|
||||
|
||||
## Goal
|
||||
|
||||
Replace the inline `withSpan + withCapture (+ optional withAudit)` blocks in `packages/auth/src/di/bind-production.ts` and `packages/auth/src/di/bind-dev-seed.ts` with `wireUseCase` calls for all three auth use cases (signIn, signUp, signOut).
|
||||
|
||||
## Why
|
||||
|
||||
Auth's binder pair contributes one of the five top-ten `pnpm fallow` clone groups. The inline wrap blocks are ~30–79 lines of mechanical boilerplate that adds noise to every auth binder diff.
|
||||
|
||||
## Done when
|
||||
|
||||
- `bind-production.ts` and `bind-dev-seed.ts` call `wireUseCase` for signIn, signUp, and signOut — no inline `withSpan(... withCapture(...))` pattern remains in either file.
|
||||
- Audit-bearing use cases (per manifest check) pass `auditLog` + audit schema to `wireUseCase`; non-audit use cases omit it.
|
||||
- `pnpm test --filter @repo/auth` green (binder tests + integration tests).
|
||||
- `pnpm typecheck --filter @repo/auth` green.
|
||||
- `assertFeatureConformance` does not throw at boot for auth (brands + manifest match).
|
||||
|
||||
## In scope
|
||||
|
||||
- `packages/auth/src/di/bind-production.ts` — use-case binding blocks only.
|
||||
- `packages/auth/src/di/bind-dev-seed.ts` — use-case binding blocks only.
|
||||
- Repository and service bindings stay as-is (direct `.toConstantValue()` calls).
|
||||
- Controller bindings stay as-is (controllers are out of scope for this PRD).
|
||||
|
||||
## Out of scope
|
||||
|
||||
- Controller bindings — deferred follow-up per PRD.
|
||||
- Changes to auth use-case implementations, schemas, or tests outside the binder.
|
||||
- Changes to `assertFeatureConformance` or the manifest.
|
||||
|
||||
## Tasks
|
||||
|
||||
- [ ] Read `packages/auth/src/feature.manifest.ts` — identify which use cases declare `audits: [...]` (non-empty) vs `audits: []`
|
||||
- [ ] Read `packages/auth/src/di/bind-production.ts` — understand current inline wrap shape and which deps each use case receives
|
||||
- [ ] Read `packages/auth/src/di/bind-dev-seed.ts` — same for dev-seed mode
|
||||
- [ ] Update `packages/auth/src/di/bind-production.ts` — replace all three inline wrap blocks with `wireUseCase` calls; pass `auditLog` + schema for audit-bearing use cases
|
||||
- [ ] Update `packages/auth/src/di/bind-dev-seed.ts` — same
|
||||
- [ ] Run `pnpm test --filter @repo/auth` — verify all tests pass
|
||||
- [ ] Run `pnpm typecheck --filter @repo/auth` — verify no type regressions
|
||||
@@ -1,48 +0,0 @@
|
||||
---
|
||||
id: 03-migrate-blog-binders
|
||||
epic: binder-wrap-helper
|
||||
title: Migrate blog feature binders to wireUseCase
|
||||
type: technical-story
|
||||
status: todo
|
||||
feature: blog
|
||||
depends-on: [01-wire-use-case-helper]
|
||||
blocks: [08-holistic-validation]
|
||||
---
|
||||
|
||||
## Goal
|
||||
|
||||
Replace the inline `withSpan + withCapture (+ optional withAudit)` blocks in `packages/blog/src/di/bind-production.ts` and `packages/blog/src/di/bind-dev-seed.ts` with `wireUseCase` calls for all three blog use cases (getArticles, getArticleBySlug, createArticle).
|
||||
|
||||
## Why
|
||||
|
||||
Blog's binder pair contributes one of the five top-ten `pnpm fallow` clone groups. The inline wrap blocks are mechanical boilerplate identical in shape to auth, media, marketing-pages, and navigation.
|
||||
|
||||
## Done when
|
||||
|
||||
- `bind-production.ts` and `bind-dev-seed.ts` call `wireUseCase` for getArticles, getArticleBySlug, and createArticle — no inline `withSpan(... withCapture(...))` pattern remains in either file.
|
||||
- Audit-bearing use cases (per manifest check) pass `auditLog` + audit schema; non-audit use cases omit it.
|
||||
- `pnpm test --filter @repo/blog` green.
|
||||
- `pnpm typecheck --filter @repo/blog` green.
|
||||
- `assertFeatureConformance` does not throw at boot for blog.
|
||||
|
||||
## In scope
|
||||
|
||||
- `packages/blog/src/di/bind-production.ts` — use-case binding blocks only.
|
||||
- `packages/blog/src/di/bind-dev-seed.ts` — use-case binding blocks only.
|
||||
- Repository and service bindings stay as-is.
|
||||
- Controller bindings stay as-is.
|
||||
|
||||
## Out of scope
|
||||
|
||||
- Controller bindings — deferred follow-up per PRD.
|
||||
- Changes to blog use-case implementations, schemas, or tests outside the binder.
|
||||
|
||||
## Tasks
|
||||
|
||||
- [ ] Read `packages/blog/src/feature.manifest.ts` — identify audit-bearing vs non-audit use cases
|
||||
- [ ] Read `packages/blog/src/di/bind-production.ts` — understand inline wrap shape and deps
|
||||
- [ ] Read `packages/blog/src/di/bind-dev-seed.ts` — same for dev-seed mode
|
||||
- [ ] Update `packages/blog/src/di/bind-production.ts` — replace three inline wrap blocks with `wireUseCase` calls
|
||||
- [ ] Update `packages/blog/src/di/bind-dev-seed.ts` — same
|
||||
- [ ] Run `pnpm test --filter @repo/blog` — verify all tests pass
|
||||
- [ ] Run `pnpm typecheck --filter @repo/blog` — verify no type regressions
|
||||
@@ -1,48 +0,0 @@
|
||||
---
|
||||
id: 04-migrate-media-binders
|
||||
epic: binder-wrap-helper
|
||||
title: Migrate media feature binders to wireUseCase
|
||||
type: technical-story
|
||||
status: todo
|
||||
feature: media
|
||||
depends-on: [01-wire-use-case-helper]
|
||||
blocks: [08-holistic-validation]
|
||||
---
|
||||
|
||||
## Goal
|
||||
|
||||
Replace the inline `withSpan + withCapture (+ optional withAudit)` blocks in `packages/media/src/di/bind-production.ts` and `packages/media/src/di/bind-dev-seed.ts` with `wireUseCase` calls for all three media use cases (getMedia, listMedia, deleteMedia).
|
||||
|
||||
## Why
|
||||
|
||||
Media's binder pair contributes one of the five top-ten `pnpm fallow` clone groups. `deleteMedia` is likely audit-bearing; the helper consolidates the conditional wrapping.
|
||||
|
||||
## Done when
|
||||
|
||||
- `bind-production.ts` and `bind-dev-seed.ts` call `wireUseCase` for getMedia, listMedia, and deleteMedia — no inline `withSpan(... withCapture(...))` pattern remains.
|
||||
- Audit-bearing use cases (per manifest check) pass `auditLog` + audit schema; non-audit use cases omit it.
|
||||
- `pnpm test --filter @repo/media` green.
|
||||
- `pnpm typecheck --filter @repo/media` green.
|
||||
- `assertFeatureConformance` does not throw at boot for media.
|
||||
|
||||
## In scope
|
||||
|
||||
- `packages/media/src/di/bind-production.ts` — use-case binding blocks only.
|
||||
- `packages/media/src/di/bind-dev-seed.ts` — use-case binding blocks only.
|
||||
- Repository and service bindings stay as-is.
|
||||
- Controller bindings stay as-is.
|
||||
|
||||
## Out of scope
|
||||
|
||||
- Controller bindings — deferred follow-up per PRD.
|
||||
- Changes to media use-case implementations, schemas, or tests outside the binder.
|
||||
|
||||
## Tasks
|
||||
|
||||
- [ ] Read `packages/media/src/feature.manifest.ts` — identify audit-bearing vs non-audit use cases
|
||||
- [ ] Read `packages/media/src/di/bind-production.ts` — understand inline wrap shape and deps
|
||||
- [ ] Read `packages/media/src/di/bind-dev-seed.ts` — same for dev-seed mode
|
||||
- [ ] Update `packages/media/src/di/bind-production.ts` — replace three inline wrap blocks with `wireUseCase` calls
|
||||
- [ ] Update `packages/media/src/di/bind-dev-seed.ts` — same
|
||||
- [ ] Run `pnpm test --filter @repo/media` — verify all tests pass
|
||||
- [ ] Run `pnpm typecheck --filter @repo/media` — verify no type regressions
|
||||
@@ -1,48 +0,0 @@
|
||||
---
|
||||
id: 05-migrate-marketing-pages-binders
|
||||
epic: binder-wrap-helper
|
||||
title: Migrate marketing-pages feature binders to wireUseCase
|
||||
type: technical-story
|
||||
status: todo
|
||||
feature: marketing-pages
|
||||
depends-on: [01-wire-use-case-helper]
|
||||
blocks: [08-holistic-validation]
|
||||
---
|
||||
|
||||
## Goal
|
||||
|
||||
Replace the inline `withSpan + withCapture (+ optional withAudit)` blocks in `packages/marketing-pages/src/di/bind-production.ts` and `packages/marketing-pages/src/di/bind-dev-seed.ts` with `wireUseCase` calls for both marketing-pages use cases (getPageBySlug, getSiteSettings).
|
||||
|
||||
## Why
|
||||
|
||||
Marketing-pages' binder pair contributes one of the five top-ten `pnpm fallow` clone groups. These are read-only use cases unlikely to be audit-bearing, but the manifest check is the source of truth.
|
||||
|
||||
## Done when
|
||||
|
||||
- `bind-production.ts` and `bind-dev-seed.ts` call `wireUseCase` for getPageBySlug and getSiteSettings — no inline `withSpan(... withCapture(...))` pattern remains.
|
||||
- Audit-bearing use cases (per manifest check) pass `auditLog` + audit schema; non-audit use cases omit it.
|
||||
- `pnpm test --filter @repo/marketing-pages` green.
|
||||
- `pnpm typecheck --filter @repo/marketing-pages` green.
|
||||
- `assertFeatureConformance` does not throw at boot for marketing-pages.
|
||||
|
||||
## In scope
|
||||
|
||||
- `packages/marketing-pages/src/di/bind-production.ts` — use-case binding blocks only.
|
||||
- `packages/marketing-pages/src/di/bind-dev-seed.ts` — use-case binding blocks only.
|
||||
- Repository and service bindings stay as-is.
|
||||
- Controller bindings stay as-is.
|
||||
|
||||
## Out of scope
|
||||
|
||||
- Controller bindings — deferred follow-up per PRD.
|
||||
- Changes to marketing-pages use-case implementations, schemas, or tests outside the binder.
|
||||
|
||||
## Tasks
|
||||
|
||||
- [ ] Read `packages/marketing-pages/src/feature.manifest.ts` — identify audit-bearing vs non-audit use cases
|
||||
- [ ] Read `packages/marketing-pages/src/di/bind-production.ts` — understand inline wrap shape and deps
|
||||
- [ ] Read `packages/marketing-pages/src/di/bind-dev-seed.ts` — same for dev-seed mode
|
||||
- [ ] Update `packages/marketing-pages/src/di/bind-production.ts` — replace two inline wrap blocks with `wireUseCase` calls
|
||||
- [ ] Update `packages/marketing-pages/src/di/bind-dev-seed.ts` — same
|
||||
- [ ] Run `pnpm test --filter @repo/marketing-pages` — verify all tests pass
|
||||
- [ ] Run `pnpm typecheck --filter @repo/marketing-pages` — verify no type regressions
|
||||
@@ -1,48 +0,0 @@
|
||||
---
|
||||
id: 06-migrate-navigation-binders
|
||||
epic: binder-wrap-helper
|
||||
title: Migrate navigation feature binders to wireUseCase
|
||||
type: technical-story
|
||||
status: todo
|
||||
feature: navigation
|
||||
depends-on: [01-wire-use-case-helper]
|
||||
blocks: [08-holistic-validation]
|
||||
---
|
||||
|
||||
## Goal
|
||||
|
||||
Replace the inline `withSpan + withCapture (+ optional withAudit)` block in `packages/navigation/src/di/bind-production.ts` and `packages/navigation/src/di/bind-dev-seed.ts` with a `wireUseCase` call for navigation's single use case (getHeader).
|
||||
|
||||
## Why
|
||||
|
||||
Navigation's binder pair contributes one of the five top-ten `pnpm fallow` clone groups. Even with a single use case, the inline wrap shape is identical boilerplate that the helper eliminates.
|
||||
|
||||
## Done when
|
||||
|
||||
- `bind-production.ts` and `bind-dev-seed.ts` call `wireUseCase` for getHeader — no inline `withSpan(... withCapture(...))` pattern remains.
|
||||
- Audit-bearing status confirmed via manifest check; `auditLog` + schema passed if needed.
|
||||
- `pnpm test --filter @repo/navigation` green.
|
||||
- `pnpm typecheck --filter @repo/navigation` green.
|
||||
- `assertFeatureConformance` does not throw at boot for navigation.
|
||||
|
||||
## In scope
|
||||
|
||||
- `packages/navigation/src/di/bind-production.ts` — use-case binding block only.
|
||||
- `packages/navigation/src/di/bind-dev-seed.ts` — use-case binding block only.
|
||||
- Repository and service bindings stay as-is.
|
||||
- Controller bindings stay as-is.
|
||||
|
||||
## Out of scope
|
||||
|
||||
- Controller bindings — deferred follow-up per PRD.
|
||||
- Changes to navigation use-case implementations, schemas, or tests outside the binder.
|
||||
|
||||
## Tasks
|
||||
|
||||
- [ ] Read `packages/navigation/src/feature.manifest.ts` — confirm getHeader audit status
|
||||
- [ ] Read `packages/navigation/src/di/bind-production.ts` — understand inline wrap shape and deps
|
||||
- [ ] Read `packages/navigation/src/di/bind-dev-seed.ts` — same for dev-seed mode
|
||||
- [ ] Update `packages/navigation/src/di/bind-production.ts` — replace inline wrap block with `wireUseCase` call
|
||||
- [ ] Update `packages/navigation/src/di/bind-dev-seed.ts` — same
|
||||
- [ ] Run `pnpm test --filter @repo/navigation` — verify all tests pass
|
||||
- [ ] Run `pnpm typecheck --filter @repo/navigation` — verify no type regressions
|
||||
@@ -1,46 +0,0 @@
|
||||
---
|
||||
id: 07-update-feature-generator
|
||||
epic: binder-wrap-helper
|
||||
title: Update feature generator template to emit wireUseCase calls
|
||||
type: technical-story
|
||||
status: todo
|
||||
feature: tooling
|
||||
depends-on: [01-wire-use-case-helper]
|
||||
blocks: [08-holistic-validation]
|
||||
---
|
||||
|
||||
## Goal
|
||||
|
||||
Update `turbo/generators/templates/feature/src/di/bind-production.ts.hbs` and `bind-dev-seed.ts.hbs` to emit `wireUseCase` calls instead of inline `withSpan + withCapture` blocks, so that `pnpm turbo gen feature` scaffolds conformant binders from the first commit.
|
||||
|
||||
## Why
|
||||
|
||||
Without this change, every new feature scaffolded after the migration would drift back to the inline wrap shape, silently undoing the consolidation. The generator is the only enforcement point for new-feature defaults.
|
||||
|
||||
## Done when
|
||||
|
||||
- `turbo/generators/templates/feature/src/di/bind-production.ts.hbs` emits a `wireUseCase` call for the scaffolded use case, not an inline wrap block.
|
||||
- `turbo/generators/templates/feature/src/di/bind-dev-seed.ts.hbs` emits a `wireUseCase` call for the scaffolded use case.
|
||||
- The inline `withSpan(... withCapture(...))` pattern is absent from both templates.
|
||||
- `@repo/core-shared/conformance` is imported in the generated binder output (the `wireUseCase` import).
|
||||
- Running `pnpm turbo gen feature` (dry-run or against a scratch location) produces binders that match the migration shape from stories 02–06.
|
||||
|
||||
## In scope
|
||||
|
||||
- `turbo/generators/templates/feature/src/di/bind-production.ts.hbs` — replace use-case wrap block.
|
||||
- `turbo/generators/templates/feature/src/di/bind-dev-seed.ts.hbs` — replace use-case wrap block.
|
||||
- Import statement update in both templates to pull in `wireUseCase` from `@repo/core-shared/conformance`.
|
||||
|
||||
## Out of scope
|
||||
|
||||
- Other generator templates (entity, repository, controller, etc.) — unchanged.
|
||||
- The generator's interactive prompts or `index.ts` config — unchanged unless needed to pass new template variables.
|
||||
- Updating already-scaffolded features (covered by stories 02–06).
|
||||
|
||||
## Tasks
|
||||
|
||||
- [ ] Read `turbo/generators/templates/feature/src/di/bind-production.ts.hbs` — understand current inline wrap shape and Handlebars variables used
|
||||
- [ ] Read `turbo/generators/templates/feature/src/di/bind-dev-seed.ts.hbs` — same
|
||||
- [ ] Update `bind-production.ts.hbs` — replace inline wrap block with `wireUseCase` call; add `wireUseCase` import from `@repo/core-shared/conformance`
|
||||
- [ ] Update `bind-dev-seed.ts.hbs` — same
|
||||
- [ ] Verify template output by inspecting rendered Handlebars (or running `pnpm turbo gen feature` in dry-run / scratch mode) to confirm generated binder matches the migration shape
|
||||
@@ -1,60 +0,0 @@
|
||||
---
|
||||
id: 08-holistic-validation
|
||||
epic: binder-wrap-helper
|
||||
title: Holistic validation — green gates + fallow clone-group check
|
||||
type: technical-story
|
||||
status: todo
|
||||
feature: core-shared
|
||||
depends-on:
|
||||
[
|
||||
02-migrate-auth-binders,
|
||||
03-migrate-blog-binders,
|
||||
04-migrate-media-binders,
|
||||
05-migrate-marketing-pages-binders,
|
||||
06-migrate-navigation-binders,
|
||||
07-update-feature-generator,
|
||||
]
|
||||
blocks: []
|
||||
---
|
||||
|
||||
## Goal
|
||||
|
||||
Run all cross-cutting success criteria from the PRD in one pass to confirm the migration is complete, all gates are green, and the five top-ten fallow clone groups have disappeared.
|
||||
|
||||
## Why
|
||||
|
||||
Per-feature stories verify individual binders in isolation; this story verifies the workspace-wide gates that can only be confirmed after all migrations are merged. The PRD's success criteria are explicitly cross-cutting: `pnpm fallow dupes`, `pnpm conformance`, `pnpm coverage:diff`, and a full `pnpm dev` boot.
|
||||
|
||||
## Done when
|
||||
|
||||
- `pnpm typecheck` green across the entire workspace.
|
||||
- `pnpm test` green across the entire workspace (all per-feature L0 bands hold).
|
||||
- `pnpm lint` green (no ESLint errors introduced by the migration).
|
||||
- `pnpm conformance` green (no orphan event consumers).
|
||||
- `pnpm fallow:audit` green.
|
||||
- `pnpm fallow dupes` no longer shows the five binder-pair clone groups in the top-ten output.
|
||||
- `pnpm coverage:diff` reports `pass` against `origin/main`.
|
||||
- `pnpm dev` boots without `assertFeatureConformance` throwing for any feature.
|
||||
|
||||
## In scope
|
||||
|
||||
- Running the full gate suite and fixing any cross-cutting issues surfaced (e.g., a missed import, a stale type reference) that were not caught by per-feature tests.
|
||||
- Updating `coverage/summary.json` if `pnpm coverage:aggregate` is needed for L2 trend.
|
||||
|
||||
## Out of scope
|
||||
|
||||
- New feature work or use-case implementations — this story is validation only.
|
||||
- Resolving `pnpm fallow` issues unrelated to the binder migration (e.g., the `init-client.ts` / `init-client-react.ts` clone noted in the PRD's deferred section).
|
||||
|
||||
## Tasks
|
||||
|
||||
- [ ] Run `pnpm typecheck` — fix any workspace-wide type errors introduced by the migration
|
||||
- [ ] Run `pnpm test` — confirm all per-feature test suites pass
|
||||
- [ ] Run `pnpm lint` — confirm no ESLint regressions
|
||||
- [ ] Run `pnpm conformance` — confirm no orphan event consumers
|
||||
- [ ] Run `pnpm fallow:audit` — confirm AI-change audit is clean
|
||||
- [ ] Run `pnpm fallow dupes` — confirm the five binder-pair clone groups are absent from top-ten output; document remaining top-ten for baseline reference
|
||||
- [ ] Run `pnpm coverage:diff` — confirm `pass` against `origin/main`
|
||||
- [ ] Run `pnpm coverage:aggregate` — commit updated `coverage/summary.json` for L2 trend
|
||||
- [ ] Boot `pnpm dev` (or simulate with `assertFeatureConformance` unit tests) — confirm all features pass boot assertion
|
||||
- [ ] Flip PRD status to `shipped` via `pnpm work prd-ship 2026-05-13-binder-wrap-helper` once all checks pass
|
||||
@@ -1,28 +0,0 @@
|
||||
---
|
||||
id: binder-wrap-helper
|
||||
prd: 2026-05-13-binder-wrap-helper
|
||||
title: Collapse binder duplication via wireUseCase helper
|
||||
type: epic
|
||||
status: in-progress
|
||||
features: [core-shared, auth, blog, media, marketing-pages, navigation, tooling]
|
||||
created: 2026-05-13
|
||||
---
|
||||
|
||||
## Goal
|
||||
|
||||
Introduce a `wireUseCase(...)` helper in `@repo/core-shared/conformance/` that encapsulates the `withSpan + withCapture (+ optional withAudit)` composition, then migrate all five features' binder pairs to call it. Update the feature generator template so new features scaffold with the helper by default.
|
||||
|
||||
## Why
|
||||
|
||||
Five of `pnpm fallow`'s top-ten clone groups come from binder pairs. The inline wrapping is ~30–79 lines per binder pair, repeated identically across 10 files. Any change to the wrapping shape requires N × 2 simultaneous edits; forgetting one is silent drift.
|
||||
|
||||
## Stories
|
||||
|
||||
- [ ] [01 — wireUseCase helper + tests (core-shared)](01-wire-use-case-helper/_story.md)
|
||||
- [ ] [02 — Migrate auth binders](02-migrate-auth-binders/_story.md)
|
||||
- [ ] [03 — Migrate blog binders](03-migrate-blog-binders/_story.md)
|
||||
- [ ] [04 — Migrate media binders](04-migrate-media-binders/_story.md)
|
||||
- [ ] [05 — Migrate marketing-pages binders](05-migrate-marketing-pages-binders/_story.md)
|
||||
- [ ] [06 — Migrate navigation binders](06-migrate-navigation-binders/_story.md)
|
||||
- [ ] [07 — Update feature generator template](07-update-feature-generator/_story.md)
|
||||
- [ ] [08 — Holistic validation](08-holistic-validation/_story.md)
|
||||
Reference in New Issue
Block a user