Output from `pnpm work decompose 2026-05-13-binder-wrap-helper
--execute` — sandcastle ran the decomposer agent with subscription
auth (after the macOS keychain workaround + Dockerfile fix from
prior commits). The agent wrote files but hit `Max iterations: 1`
before committing, so this commit carries its output unchanged.
Epic: docs/work/binder-wrap-helper/
- _epic.md links to PRD 2026-05-13-binder-wrap-helper
- features: [core-shared, auth, blog, media, marketing-pages,
navigation, tooling]
Stories (8 total, with dependency edges):
01-wire-use-case-helper prereq (blocks 02..07)
Goal: helper at core-shared/conformance/wire-use-case.ts +
tests covering brand stacking, span/capture/audit composition,
idempotent bind. depends-on: [], blocks 02..07.
02-migrate-auth-binders depends-on [01]
03-migrate-blog-binders depends-on [01]
04-migrate-media-binders depends-on [01]
05-migrate-marketing-pages- depends-on [01]
binders
06-migrate-navigation-binders depends-on [01]
07-update-feature-generator depends-on [01]
08-holistic-validation depends-on [02..07], blocks: []
Final gate suite + fallow dupes check to verify the 5 binder-
pair clone groups have disappeared.
After 01 lands, stories 02..07 are parallelisable; 08 collects them.
Pre-commit hook regenerates _state.json + re-stages it so `pnpm
work next` immediately surfaces the new ready story.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
3.7 KiB
3.7 KiB
id, epic, title, type, status, feature, depends-on, blocks
| id | epic | title | type | status | feature | depends-on | blocks | ||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 01-wire-use-case-helper | binder-wrap-helper | wireUseCase helper + tests in core-shared/conformance | technical-story | in-progress | core-shared |
|
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.tsexists with the helper and all supporting types.packages/core-shared/src/conformance/wire-use-case.test.tsis 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
wireUseCasetwice on the same symbol unbinds then rebinds without error.
wireUseCase(and its companion types) exported frompackages/core-shared/src/conformance/index.ts.pnpm test --filter @repo/core-shared -- --coveragegreen; new file hits 100%.pnpm typecheck --filter @repo/core-sharedgreen.
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 usingRecordingTracer,RecordingLogger, and mock audit emitter fromcore-testing(mirror the pattern incore-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 thelayerdiscriminator on the single helper. - Repository / service binding patterns — those stay as direct
.toConstantValue()calls. - Changing
withSpan,withCapture,withAuditinternals — the helper only composes them. - Modifying the manifest schema.
Tasks
- Read
packages/core-shared/src/instrumentation/with-span.ts,with-capture.ts, andpackages/core-audit/src/with-audit.tsto capture exact signatures and brand attachment behaviour - Read
packages/core-shared/src/conformance/brands.tsandbrand-runtime.tsforisInstrumented/isCaptured/isAuditedruntime helpers - Read
packages/core-shared/src/conformance/production-use-case.tsfor 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,layerdiscriminator, 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
wireUseCaseand option/return types frompackages/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% onwire-use-case.ts