014578c9a81a37313edc6f714c2a1380514ce15b
Closes the gap surfaced by the user: `pnpm work` usage referenced
`decompose` (via docs + the to-prd skill) but the subcommand was
never built. Mirrors `pnpm work dispatch`'s shape.
scripts/work/decompose.mjs (new):
- validatePrdForDecompose(prdPath) — refuses draft (must go
through human review first), in-review (review incomplete),
shipped (epic already exists); accepts only approved
- printDecomposePlan(prdId, prdPath, frontmatter) — print-mode
output showing the PRD's eligibility + sandcastle invocation
plan + auth modes
- executeDecompose(prdId, prdPath, prdText) — invokes sandcastle
with .sandcastle/decomposer.prompt.md, passing PRD_FILE_CONTENT
promptArg. The decomposer agent writes the epic + per-story
files to disk on a sandcastle branch the human can review
- runCli(args, { workRoot }) — entry point used by cli.mjs
- Direct invocation also supported (mirrors dispatch.mjs's
invokedDirectly guard, NEW pattern after this commit)
scripts/work/decompose.test.mjs (new, 9 tests, all green):
- validatePrdForDecompose: accepts approved; rejects draft,
in-review, shipped, unknown status, missing file
- runCli: writes error + returns 1 on missing PRD; writes error
+ returns 1 on draft PRD; prints plan + returns 0 on approved
scripts/work/cli.mjs:
- Adds `decompose` subcommand to usage + dispatch
- Usage formatting realigned for the 3-line subcommand block
scripts/work/dispatch.mjs:
- **Fix** the bug surfaced by the user: dispatch.mjs's CLI ran
as a top-level side effect whenever any of its exports was
imported. decompose.mjs imports resolveClaudeAuth from it, so
importing decompose.mjs printed "No ready task to dispatch."
Added an `import.meta.url === \`file://${process.argv[1]}\``
guard so the CLI only runs when invoked directly. This unblocks
cross-import without side effects.
Smoke-tested end-to-end:
- `pnpm work decompose` (no id) prints usage + exits 2
- `pnpm work decompose 2026-05-13-binder-wrap-helper` prints the
decompose plan with status: approved (eligible)
- 9/9 unit tests green
- dispatch.mjs's existing direct-invocation path unchanged
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Clean Architecture Monorepo Template
Turborepo + pnpm monorepo organised by vertical features, with an agent-first workflow and five conformance gates.
This template is built for agent-driven development. Sandcastle is the orchestration substrate; pnpm work dispatch is the entry point. See ADR-019 for the decision rationale and docs/guides/runbook.md for end-to-end usage.
Start here
Read docs/guides/runbook.md — day-1 onboarding (prerequisites, env vars, daily commands, troubleshooting, Using Sandcastle for agent dispatch).
Quick reference
pnpm install # Install + auto-wire husky pre-commit hooks
pnpm dev # All dev servers (web-next:3000, cms:3001, web-tanstack:3002, storybook:6006)
pnpm test # All tests
pnpm typecheck # TypeScript across all packages
pnpm lint # ESLint (incl. 8 conformance/* rules)
pnpm conformance # Cross-feature event closure
pnpm fallow # Whole-codebase: dead exports, dupes, complexity
pnpm turbo boundaries # Workspace dependency graph
pnpm work status # docs/work/ epic + story state
docker compose up -d # Start PostgreSQL
Documentation map
docs/guides/runbook.md— start hereCLAUDE.md— full conventions referenceAGENTS.md— package map + boundary rulesdocs/guides/conformance-quickref.md— manifest + 5-gate daily referencedocs/architecture/agent-first-workflow-and-conformance.md— full designdocs/architecture/feature-conformance-explainer.html— interactive explainer
Scaffolding
pnpm turbo gen feature <name> # Scaffold a feature (manifest + contracts + tests)
pnpm turbo gen event # Event contract or handler (requires gen core-package events)
pnpm turbo gen job # Background job
pnpm turbo gen realtime # Realtime channel (requires gen core-package realtime)
pnpm turbo gen core-package <name> # Optional core: events / realtime / trpc / ui / audit
pnpm turbo gen core-ui-component <name> # Atomic-design component
Generator-first is non-negotiable — hand-rolled feature/event/job/realtime/component code is rejected by reviewer agents and may fail the CI scaffold-drift check.
Optional packages
Five core packages scaffold on demand:
pnpm turbo gen core-package realtime # Socket.IO realtime layer (ADR-016)
pnpm turbo gen core-package events # Cross-feature events + Payload jobs (ADR-015)
pnpm turbo gen core-package trpc # tRPC server setup
pnpm turbo gen core-package ui # Design system
pnpm turbo gen core-package audit # DPA-compliant audit logging (ADR-018)
See docs/architecture/template-tiers.md for the full tier list.
Description
Languages
TypeScript
65.6%
JavaScript
21.1%
Handlebars
12.2%
Shell
0.9%
Dockerfile
0.1%