Files
agentic-dev/docs/work/binder-wrap-helper/01-wire-use-case-helper/_story.md
Danijel Martinek 6f18075593 docs(work): decompose binder-wrap-helper PRD into epic + 8 stories
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>
2026-05-13 18:10:31 +02:00

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