The previous layout placed epic folders directly under docs/work/
alongside prds/ and _system/. Tightening: epics now live in their
own docs/work/epics/ subfolder, peer to prds/ and _system/. Same
shape as the existing prds/ bucket.
Final docs/work/ layout:
README.md
prds/<slug>.prd.md
_system/_state.json
epics/<slug>/_epic.md + <story-folder>/_story.md
Renames (git mv preserves history):
- docs/work/binder-wrap-helper/
-> docs/work/epics/binder-wrap-helper/
- docs/work/library-evaluation-policy/
-> docs/work/epics/library-evaluation-policy/
- docs/work/ci-security-and-supply-chain/
-> docs/work/epics/ci-security-and-supply-chain/
Tooling updates:
- state-builder.mjs walks workRoot/epics/ directly; SKIP_FOLDERS
obsoleted (no more sibling folders to filter out).
- dispatch.mjs's findNextTask, tickStoryBulletInEpic, and
flipEpicDoneIfAllStoriesDone all join with "epics" segment.
- prd-ship.mjs's deriveShippingCommits walks workRoot/epics/ and
git-logs docs/work/epics/<epic>/.
- decomposer.prompt.md emits epics under docs/work/epics/<epic-id>/.
- handoff + grill-with-docs glossary references updated.
- Glossary entry for Epic updated.
Reserved future shape: when a task-tracker integration (ClickUp,
Linear) ships, the epics/ subfolder hosts <task-id>-<slug>/
folders. Today it just hosts bare slugs.
.sandcastle/
This directory holds prompt templates that the future orchestrator
(pnpm work dispatch in the sandcastle-dispatch-v1 epic) feeds to
sandcastle when dispatching
agents.
Prompt templates
| File | Role | Variables |
|---|---|---|
prd-eliciter.prompt.md |
Interview a human to produce a PRD draft | {{INITIAL_BRIEF}} |
adr-eliciter.prompt.md |
Interview a human to produce an ADR draft | {{INITIAL_PROPOSAL}} |
decomposer.prompt.md |
Turn a PRD into epic + story files | {{PRD_FILE_CONTENT}} |
implementer.prompt.md |
Execute a single task | {{TASK_FILE_CONTENT}} |
reviewer.prompt.md |
Review the implementer's diff | {{TASK_FILE_CONTENT}}, {{DIFF}} |
Convention: every prompt enforces "generators first"
Each prompt template starts with the same non-negotiable rule: the agent
must prefer pnpm turbo gen <kind> over hand-rolled scaffolding. This
applies to feature packages, events, jobs, realtime channels, optional
core packages, and atomic-design components. Hand-rolled code is only
acceptable when the generator's output doesn't cover the case — and even
then, the agent runs the generator first and modifies its output rather
than starting from scratch.
Environment
Configure runtime tokens via .env (gitignored). Copy .env.example
and fill values for the providers you use.
Build the sandbox image (one-time)
Sandcastle dispatches into a Docker image tagged sandcastle:<root-package-name>.
Build it once per clone before pnpm work dispatch --execute or
pnpm work decompose <id> --execute will work:
pnpm exec sandcastle docker build-image
# Tags: sandcastle:template-vertical
Rebuild after editing this Dockerfile:
pnpm exec sandcastle docker remove-image
pnpm exec sandcastle docker build-image
See docs/guides/runbook.md → Using Sandcastle → Prerequisites for the full setup.
Manual usage
Until the orchestrator ships, these templates are usable manually: copy
the relevant .prompt.md content into a Claude / Codex / other agent
session, fill the {{VARIABLE}} placeholders by hand, and run.