From 756e36c720b080daffef4cd1c277f0bf605c11c5 Mon Sep 17 00:00:00 2001 From: Danijel Martinek Date: Thu, 14 May 2026 21:21:51 +0200 Subject: [PATCH] refactor(work): move epic folders into docs/work/epics/ 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/.prd.md _system/_state.json epics//_epic.md + /_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//. - decomposer.prompt.md emits epics under docs/work/epics//. - 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 -/ folders. Today it just hosts bare slugs. --- .../skills/grill-with-docs/glossary-format.md | 2 +- .claude/skills/handoff/SKILL.md | 2 +- .sandcastle/decomposer.prompt.md | 6 +++--- docs/glossary.md | 2 +- docs/work/_system/_state.json | 2 +- .../01-wire-use-case-helper/_story.md | 2 +- .../02-migrate-feature-binders/_story.md | 2 +- .../03-update-generator-templates/_story.md | 2 +- .../{ => epics}/binder-wrap-helper/_epic.md | 2 +- .../01-trace-schema-extensions/_story.md | 2 +- .../02-socket-integration/_story.md | 2 +- .../03-renovate-adoption/_story.md | 2 +- .../04-major-bump-reevaluation/_story.md | 2 +- .../05-trace-revalidation-workflow/_story.md | 2 +- .../06-codeql-and-audit-signatures/_story.md | 2 +- .../07-gitleaks-precommit/_story.md | 2 +- .../08-reviewer-prompt-update/_story.md | 2 +- .../09-ci-security-guide-and-docs/_story.md | 2 +- .../ci-security-and-supply-chain/_epic.md | 2 +- .../01-trace-schema-foundation/_story.md | 2 +- .../02-pre-commit-check-script/_story.md | 2 +- .../03-claude-hooks/_story.md | 2 +- .../04-evaluate-library-skill/_story.md | 2 +- .../05-human-guide/_story.md | 2 +- .../06-sandcastle-reviewer-prompt/_story.md | 2 +- .../07-generator-pre-shipped-traces/_story.md | 2 +- .../08-backfill-traces/_story.md | 2 +- .../09-claude-md-update/_story.md | 2 +- .../library-evaluation-policy/_epic.md | 2 +- scripts/work/decompose.mjs | 6 +++--- scripts/work/dispatch.mjs | 17 +++++++++++++---- scripts/work/prd-ship.mjs | 8 +++++--- scripts/work/state-builder.mjs | 17 +++++++---------- 33 files changed, 59 insertions(+), 51 deletions(-) rename docs/work/{ => epics}/binder-wrap-helper/01-wire-use-case-helper/_story.md (98%) rename docs/work/{ => epics}/binder-wrap-helper/02-migrate-feature-binders/_story.md (98%) rename docs/work/{ => epics}/binder-wrap-helper/03-update-generator-templates/_story.md (98%) rename docs/work/{ => epics}/binder-wrap-helper/_epic.md (97%) rename docs/work/{ => epics}/ci-security-and-supply-chain/01-trace-schema-extensions/_story.md (98%) rename docs/work/{ => epics}/ci-security-and-supply-chain/02-socket-integration/_story.md (98%) rename docs/work/{ => epics}/ci-security-and-supply-chain/03-renovate-adoption/_story.md (98%) rename docs/work/{ => epics}/ci-security-and-supply-chain/04-major-bump-reevaluation/_story.md (99%) rename docs/work/{ => epics}/ci-security-and-supply-chain/05-trace-revalidation-workflow/_story.md (99%) rename docs/work/{ => epics}/ci-security-and-supply-chain/06-codeql-and-audit-signatures/_story.md (98%) rename docs/work/{ => epics}/ci-security-and-supply-chain/07-gitleaks-precommit/_story.md (98%) rename docs/work/{ => epics}/ci-security-and-supply-chain/08-reviewer-prompt-update/_story.md (98%) rename docs/work/{ => epics}/ci-security-and-supply-chain/09-ci-security-guide-and-docs/_story.md (99%) rename docs/work/{ => epics}/ci-security-and-supply-chain/_epic.md (98%) rename docs/work/{ => epics}/library-evaluation-policy/01-trace-schema-foundation/_story.md (98%) rename docs/work/{ => epics}/library-evaluation-policy/02-pre-commit-check-script/_story.md (98%) rename docs/work/{ => epics}/library-evaluation-policy/03-claude-hooks/_story.md (98%) rename docs/work/{ => epics}/library-evaluation-policy/04-evaluate-library-skill/_story.md (99%) rename docs/work/{ => epics}/library-evaluation-policy/05-human-guide/_story.md (98%) rename docs/work/{ => epics}/library-evaluation-policy/06-sandcastle-reviewer-prompt/_story.md (98%) rename docs/work/{ => epics}/library-evaluation-policy/07-generator-pre-shipped-traces/_story.md (98%) rename docs/work/{ => epics}/library-evaluation-policy/08-backfill-traces/_story.md (98%) rename docs/work/{ => epics}/library-evaluation-policy/09-claude-md-update/_story.md (98%) rename docs/work/{ => epics}/library-evaluation-policy/_epic.md (98%) diff --git a/.claude/skills/grill-with-docs/glossary-format.md b/.claude/skills/grill-with-docs/glossary-format.md index aa682ec..5218c40 100644 --- a/.claude/skills/grill-with-docs/glossary-format.md +++ b/.claude/skills/grill-with-docs/glossary-format.md @@ -29,7 +29,7 @@ The 5-gate enforcement system (TS brands → ESLint → boot assertion → `pnpm The top-level requirements doc at `docs/work/prds/-.prd.md` that seeds an epic. **Epic**: -A large body of work containing stories. Folder at `docs/work//_epic.md`. +A large body of work containing stories. Folder at `docs/work/epics//_epic.md`. **Story**: One use case or technical capability. Folder under the epic, file `_story.md`. diff --git a/.claude/skills/handoff/SKILL.md b/.claude/skills/handoff/SKILL.md index 45ca92c..dcb5711 100644 --- a/.claude/skills/handoff/SKILL.md +++ b/.claude/skills/handoff/SKILL.md @@ -17,7 +17,7 @@ Suggest the skills the next session should use, if any. In this repo, the common Reference these artifacts by path or URL rather than inlining their content: -- PRDs (`docs/work/prds/*.prd.md`), epics (`docs/work//_epic.md`), stories (`_story.md`), tasks (`*.task.md`) +- PRDs (`docs/work/prds/*.prd.md`), epics (`docs/work/epics//_epic.md`), stories (`_story.md`), tasks (`*.task.md`) - ADRs (`docs/decisions/adr-NNN-*.md`) - AGENTS.md and CLAUDE.md (the next agent loads these automatically) - `_state.json` (orchestrator-derived; the next agent regenerates it from markdown via `pnpm work rebuild-state`) diff --git a/.sandcastle/decomposer.prompt.md b/.sandcastle/decomposer.prompt.md index 7ea56d5..43425bb 100644 --- a/.sandcastle/decomposer.prompt.md +++ b/.sandcastle/decomposer.prompt.md @@ -1,6 +1,6 @@ # Decomposer Agent -You are the decomposer agent. Given an approved PRD, you produce the epic file + one story file per requirement under `docs/work//`. Folder names use the **bare slug** — no date prefix; the `created:` timestamp in frontmatter carries the date. Each story has its own checkbox-driven Tasks list — where **every checkbox is a vertical slice**. +You are the decomposer agent. Given an approved PRD, you produce the epic file + one story file per requirement under `docs/work/epics//`. Folder names use the **bare slug** — no date prefix; the `created:` timestamp in frontmatter carries the date. Each story has its own checkbox-driven Tasks list — where **every checkbox is a vertical slice**. ## The slice rule (non-negotiable) @@ -54,8 +54,8 @@ The approved PRD: ## Your job 1. Read the PRD. Extract: epic id (kebab-slug from title — **no date prefix**; the `created:` timestamp carries the date), story list (one per Requirement), dependency edges (from "depends on" hints in the PRD), out-of-scope items. The epic id should match the PRD's `id:` field exactly. -2. Write `docs/work//_epic.md` with frontmatter: `id`, `prd` (path to the PRD file), `title`, `type: epic`, `status: in-progress`, `features`, `created: ` (use the current timestamp). The pre-commit hook adds `updated:` automatically — do NOT set it yourself. -3. For each Requirement, write `docs/work//-/_story.md`: +2. Write `docs/work/epics//_epic.md` with frontmatter: `id`, `prd` (path to the PRD file), `title`, `type: epic`, `status: in-progress`, `features`, `created: ` (use the current timestamp). The pre-commit hook adds `updated:` automatically — do NOT set it yourself. +3. For each Requirement, write `docs/work/epics//-/_story.md`: - Frontmatter: `id`, `epic`, `title`, `type: technical-story | user-story`, `status: in-progress` (for the first) or `todo` (subsequent), `feature`, `depends-on` (array, may reference other stories in this epic by id), `blocks`, `created: `. The pre-commit hook stamps `updated:` — do NOT set it yourself. - Sections: Goal, Why, Done when, In scope, Out of scope, Tasks (checkbox list). - **Each story's Tasks list:** every checkbox MUST satisfy the slice rule above — one green commit per checkbox. If a generator is applicable, list the generator invocation as the FIRST checkbox; subsequent checkboxes customise the generator's output and each one lands its own green commit (e.g. "Add audit emission to use case X", "Wire event publish from X into bus"). diff --git a/docs/glossary.md b/docs/glossary.md index 3642216..14a89ad 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -273,7 +273,7 @@ The top-level requirements doc at `docs/work/prds/-.prd.md`. Status _Avoid:_ spec (in this template the **ADR** is the durable design record; PRDs are the implementation seed). **Epic**: -A large body of work, one folder under `docs/work//` with `_epic.md`. Decomposed from a PRD. +A large body of work, one folder under `docs/work/epics//` with `_epic.md`. Decomposed from a PRD. **Story**: One use case or one technical capability, one folder under `//` with `_story.md`. Type metadata: `user-story` or `technical-story`. diff --git a/docs/work/_system/_state.json b/docs/work/_system/_state.json index 9786370..0db8739 100644 --- a/docs/work/_system/_state.json +++ b/docs/work/_system/_state.json @@ -1,5 +1,5 @@ { - "updated_at": "2026-05-14T19:16:53.146Z", + "updated_at": "2026-05-14T19:21:52.736Z", "epics": { "binder-wrap-helper": { "status": "done", diff --git a/docs/work/binder-wrap-helper/01-wire-use-case-helper/_story.md b/docs/work/epics/binder-wrap-helper/01-wire-use-case-helper/_story.md similarity index 98% rename from docs/work/binder-wrap-helper/01-wire-use-case-helper/_story.md rename to docs/work/epics/binder-wrap-helper/01-wire-use-case-helper/_story.md index 4f8a8b8..ca6c4ad 100644 --- a/docs/work/binder-wrap-helper/01-wire-use-case-helper/_story.md +++ b/docs/work/epics/binder-wrap-helper/01-wire-use-case-helper/_story.md @@ -8,7 +8,7 @@ feature: core-shared depends-on: [] blocks: [02-migrate-feature-binders, 03-update-generator-templates] created: 2026-05-13T19:17:10+02:00 -updated: 2026-05-14T19:16:52.691Z +updated: 2026-05-14T19:21:52.308Z --- ## Goal diff --git a/docs/work/binder-wrap-helper/02-migrate-feature-binders/_story.md b/docs/work/epics/binder-wrap-helper/02-migrate-feature-binders/_story.md similarity index 98% rename from docs/work/binder-wrap-helper/02-migrate-feature-binders/_story.md rename to docs/work/epics/binder-wrap-helper/02-migrate-feature-binders/_story.md index 85af4d2..90f5c0e 100644 --- a/docs/work/binder-wrap-helper/02-migrate-feature-binders/_story.md +++ b/docs/work/epics/binder-wrap-helper/02-migrate-feature-binders/_story.md @@ -8,7 +8,7 @@ feature: auth, blog, media, marketing-pages, navigation depends-on: [01-wire-use-case-helper] blocks: [] created: 2026-05-13T19:17:10+02:00 -updated: 2026-05-14T19:16:52.691Z +updated: 2026-05-14T19:21:52.308Z --- ## Goal diff --git a/docs/work/binder-wrap-helper/03-update-generator-templates/_story.md b/docs/work/epics/binder-wrap-helper/03-update-generator-templates/_story.md similarity index 98% rename from docs/work/binder-wrap-helper/03-update-generator-templates/_story.md rename to docs/work/epics/binder-wrap-helper/03-update-generator-templates/_story.md index 49cfab6..0a7ca09 100644 --- a/docs/work/binder-wrap-helper/03-update-generator-templates/_story.md +++ b/docs/work/epics/binder-wrap-helper/03-update-generator-templates/_story.md @@ -8,7 +8,7 @@ feature: core-shared depends-on: [01-wire-use-case-helper] blocks: [] created: 2026-05-13T19:17:10+02:00 -updated: 2026-05-14T19:16:52.691Z +updated: 2026-05-14T19:21:52.308Z --- ## Goal diff --git a/docs/work/binder-wrap-helper/_epic.md b/docs/work/epics/binder-wrap-helper/_epic.md similarity index 97% rename from docs/work/binder-wrap-helper/_epic.md rename to docs/work/epics/binder-wrap-helper/_epic.md index f15d7f7..5481abb 100644 --- a/docs/work/binder-wrap-helper/_epic.md +++ b/docs/work/epics/binder-wrap-helper/_epic.md @@ -6,7 +6,7 @@ type: epic status: done features: [core-shared, auth, blog, media, marketing-pages, navigation] created: 2026-05-13T00:00:00Z -updated: 2026-05-14T19:16:52.691Z +updated: 2026-05-14T19:21:52.308Z --- ## Goal diff --git a/docs/work/ci-security-and-supply-chain/01-trace-schema-extensions/_story.md b/docs/work/epics/ci-security-and-supply-chain/01-trace-schema-extensions/_story.md similarity index 98% rename from docs/work/ci-security-and-supply-chain/01-trace-schema-extensions/_story.md rename to docs/work/epics/ci-security-and-supply-chain/01-trace-schema-extensions/_story.md index 968170f..cc54abd 100644 --- a/docs/work/ci-security-and-supply-chain/01-trace-schema-extensions/_story.md +++ b/docs/work/epics/ci-security-and-supply-chain/01-trace-schema-extensions/_story.md @@ -13,7 +13,7 @@ blocks: 05-trace-revalidation-workflow, ] created: 2026-05-14T18:59:12+02:00 -updated: 2026-05-14T19:16:52.691Z +updated: 2026-05-14T19:21:52.308Z --- ## Goal diff --git a/docs/work/ci-security-and-supply-chain/02-socket-integration/_story.md b/docs/work/epics/ci-security-and-supply-chain/02-socket-integration/_story.md similarity index 98% rename from docs/work/ci-security-and-supply-chain/02-socket-integration/_story.md rename to docs/work/epics/ci-security-and-supply-chain/02-socket-integration/_story.md index 286a68c..d86a5d8 100644 --- a/docs/work/ci-security-and-supply-chain/02-socket-integration/_story.md +++ b/docs/work/epics/ci-security-and-supply-chain/02-socket-integration/_story.md @@ -8,7 +8,7 @@ feature: tooling depends-on: [01-trace-schema-extensions] blocks: [08-reviewer-prompt-update] created: 2026-05-14T18:59:12+02:00 -updated: 2026-05-14T19:16:52.691Z +updated: 2026-05-14T19:21:52.308Z --- ## Goal diff --git a/docs/work/ci-security-and-supply-chain/03-renovate-adoption/_story.md b/docs/work/epics/ci-security-and-supply-chain/03-renovate-adoption/_story.md similarity index 98% rename from docs/work/ci-security-and-supply-chain/03-renovate-adoption/_story.md rename to docs/work/epics/ci-security-and-supply-chain/03-renovate-adoption/_story.md index 1d50cb4..af1c3c1 100644 --- a/docs/work/ci-security-and-supply-chain/03-renovate-adoption/_story.md +++ b/docs/work/epics/ci-security-and-supply-chain/03-renovate-adoption/_story.md @@ -8,7 +8,7 @@ feature: tooling depends-on: [] blocks: [09-ci-security-guide-and-docs] created: 2026-05-14T18:59:12+02:00 -updated: 2026-05-14T19:16:52.691Z +updated: 2026-05-14T19:21:52.308Z --- ## Goal diff --git a/docs/work/ci-security-and-supply-chain/04-major-bump-reevaluation/_story.md b/docs/work/epics/ci-security-and-supply-chain/04-major-bump-reevaluation/_story.md similarity index 99% rename from docs/work/ci-security-and-supply-chain/04-major-bump-reevaluation/_story.md rename to docs/work/epics/ci-security-and-supply-chain/04-major-bump-reevaluation/_story.md index 1ab02ef..04c99be 100644 --- a/docs/work/ci-security-and-supply-chain/04-major-bump-reevaluation/_story.md +++ b/docs/work/epics/ci-security-and-supply-chain/04-major-bump-reevaluation/_story.md @@ -8,7 +8,7 @@ feature: scripts depends-on: [01-trace-schema-extensions] blocks: [05-trace-revalidation-workflow] created: 2026-05-14T18:59:12+02:00 -updated: 2026-05-14T19:16:52.691Z +updated: 2026-05-14T19:21:52.308Z --- ## Goal diff --git a/docs/work/ci-security-and-supply-chain/05-trace-revalidation-workflow/_story.md b/docs/work/epics/ci-security-and-supply-chain/05-trace-revalidation-workflow/_story.md similarity index 99% rename from docs/work/ci-security-and-supply-chain/05-trace-revalidation-workflow/_story.md rename to docs/work/epics/ci-security-and-supply-chain/05-trace-revalidation-workflow/_story.md index 6aba501..e4e536d 100644 --- a/docs/work/ci-security-and-supply-chain/05-trace-revalidation-workflow/_story.md +++ b/docs/work/epics/ci-security-and-supply-chain/05-trace-revalidation-workflow/_story.md @@ -8,7 +8,7 @@ feature: scripts depends-on: [01-trace-schema-extensions, 04-major-bump-reevaluation] blocks: [09-ci-security-guide-and-docs] created: 2026-05-14T18:59:12+02:00 -updated: 2026-05-14T19:16:52.691Z +updated: 2026-05-14T19:21:52.308Z --- ## Goal diff --git a/docs/work/ci-security-and-supply-chain/06-codeql-and-audit-signatures/_story.md b/docs/work/epics/ci-security-and-supply-chain/06-codeql-and-audit-signatures/_story.md similarity index 98% rename from docs/work/ci-security-and-supply-chain/06-codeql-and-audit-signatures/_story.md rename to docs/work/epics/ci-security-and-supply-chain/06-codeql-and-audit-signatures/_story.md index 2ae84d6..b1aadd8 100644 --- a/docs/work/ci-security-and-supply-chain/06-codeql-and-audit-signatures/_story.md +++ b/docs/work/epics/ci-security-and-supply-chain/06-codeql-and-audit-signatures/_story.md @@ -8,7 +8,7 @@ feature: tooling depends-on: [] blocks: [08-reviewer-prompt-update] created: 2026-05-14T18:59:12+02:00 -updated: 2026-05-14T19:16:52.691Z +updated: 2026-05-14T19:21:52.308Z --- ## Goal diff --git a/docs/work/ci-security-and-supply-chain/07-gitleaks-precommit/_story.md b/docs/work/epics/ci-security-and-supply-chain/07-gitleaks-precommit/_story.md similarity index 98% rename from docs/work/ci-security-and-supply-chain/07-gitleaks-precommit/_story.md rename to docs/work/epics/ci-security-and-supply-chain/07-gitleaks-precommit/_story.md index ca50f1e..65fbc32 100644 --- a/docs/work/ci-security-and-supply-chain/07-gitleaks-precommit/_story.md +++ b/docs/work/epics/ci-security-and-supply-chain/07-gitleaks-precommit/_story.md @@ -8,7 +8,7 @@ feature: tooling depends-on: [] blocks: [09-ci-security-guide-and-docs] created: 2026-05-14T18:59:12+02:00 -updated: 2026-05-14T19:16:52.691Z +updated: 2026-05-14T19:21:52.308Z --- ## Goal diff --git a/docs/work/ci-security-and-supply-chain/08-reviewer-prompt-update/_story.md b/docs/work/epics/ci-security-and-supply-chain/08-reviewer-prompt-update/_story.md similarity index 98% rename from docs/work/ci-security-and-supply-chain/08-reviewer-prompt-update/_story.md rename to docs/work/epics/ci-security-and-supply-chain/08-reviewer-prompt-update/_story.md index fae8bfd..95e5230 100644 --- a/docs/work/ci-security-and-supply-chain/08-reviewer-prompt-update/_story.md +++ b/docs/work/epics/ci-security-and-supply-chain/08-reviewer-prompt-update/_story.md @@ -8,7 +8,7 @@ feature: tooling depends-on: [02-socket-integration, 06-codeql-and-audit-signatures] blocks: [09-ci-security-guide-and-docs] created: 2026-05-14T18:59:12+02:00 -updated: 2026-05-14T19:16:52.691Z +updated: 2026-05-14T19:21:52.308Z --- ## Goal diff --git a/docs/work/ci-security-and-supply-chain/09-ci-security-guide-and-docs/_story.md b/docs/work/epics/ci-security-and-supply-chain/09-ci-security-guide-and-docs/_story.md similarity index 99% rename from docs/work/ci-security-and-supply-chain/09-ci-security-guide-and-docs/_story.md rename to docs/work/epics/ci-security-and-supply-chain/09-ci-security-guide-and-docs/_story.md index 76beae4..9b9ca03 100644 --- a/docs/work/ci-security-and-supply-chain/09-ci-security-guide-and-docs/_story.md +++ b/docs/work/epics/ci-security-and-supply-chain/09-ci-security-guide-and-docs/_story.md @@ -18,7 +18,7 @@ depends-on: ] blocks: [] created: 2026-05-14T18:59:12+02:00 -updated: 2026-05-14T19:16:52.691Z +updated: 2026-05-14T19:21:52.308Z --- ## Goal diff --git a/docs/work/ci-security-and-supply-chain/_epic.md b/docs/work/epics/ci-security-and-supply-chain/_epic.md similarity index 98% rename from docs/work/ci-security-and-supply-chain/_epic.md rename to docs/work/epics/ci-security-and-supply-chain/_epic.md index dee3c08..fa9cb93 100644 --- a/docs/work/ci-security-and-supply-chain/_epic.md +++ b/docs/work/epics/ci-security-and-supply-chain/_epic.md @@ -6,7 +6,7 @@ type: epic status: done features: [scripts, tooling, docs] created: 2026-05-14T00:00:00Z -updated: 2026-05-14T19:16:52.691Z +updated: 2026-05-14T19:21:52.308Z --- ## Goal diff --git a/docs/work/library-evaluation-policy/01-trace-schema-foundation/_story.md b/docs/work/epics/library-evaluation-policy/01-trace-schema-foundation/_story.md similarity index 98% rename from docs/work/library-evaluation-policy/01-trace-schema-foundation/_story.md rename to docs/work/epics/library-evaluation-policy/01-trace-schema-foundation/_story.md index 32e111b..00dae50 100644 --- a/docs/work/library-evaluation-policy/01-trace-schema-foundation/_story.md +++ b/docs/work/epics/library-evaluation-policy/01-trace-schema-foundation/_story.md @@ -14,7 +14,7 @@ blocks: 08-backfill-traces, ] created: 2026-05-14T06:52:02+02:00 -updated: 2026-05-14T19:16:52.691Z +updated: 2026-05-14T19:21:52.308Z --- ## Goal diff --git a/docs/work/library-evaluation-policy/02-pre-commit-check-script/_story.md b/docs/work/epics/library-evaluation-policy/02-pre-commit-check-script/_story.md similarity index 98% rename from docs/work/library-evaluation-policy/02-pre-commit-check-script/_story.md rename to docs/work/epics/library-evaluation-policy/02-pre-commit-check-script/_story.md index 3ff8579..2daebf9 100644 --- a/docs/work/library-evaluation-policy/02-pre-commit-check-script/_story.md +++ b/docs/work/epics/library-evaluation-policy/02-pre-commit-check-script/_story.md @@ -8,7 +8,7 @@ feature: scripts depends-on: [01-trace-schema-foundation] blocks: [06-sandcastle-reviewer-prompt] created: 2026-05-14T06:52:02+02:00 -updated: 2026-05-14T19:16:52.691Z +updated: 2026-05-14T19:21:52.308Z --- ## Goal diff --git a/docs/work/library-evaluation-policy/03-claude-hooks/_story.md b/docs/work/epics/library-evaluation-policy/03-claude-hooks/_story.md similarity index 98% rename from docs/work/library-evaluation-policy/03-claude-hooks/_story.md rename to docs/work/epics/library-evaluation-policy/03-claude-hooks/_story.md index b240862..dffdbc8 100644 --- a/docs/work/library-evaluation-policy/03-claude-hooks/_story.md +++ b/docs/work/epics/library-evaluation-policy/03-claude-hooks/_story.md @@ -8,7 +8,7 @@ feature: tooling depends-on: [] blocks: [] created: 2026-05-14T06:52:02+02:00 -updated: 2026-05-14T19:16:52.691Z +updated: 2026-05-14T19:21:52.308Z --- ## Goal diff --git a/docs/work/library-evaluation-policy/04-evaluate-library-skill/_story.md b/docs/work/epics/library-evaluation-policy/04-evaluate-library-skill/_story.md similarity index 99% rename from docs/work/library-evaluation-policy/04-evaluate-library-skill/_story.md rename to docs/work/epics/library-evaluation-policy/04-evaluate-library-skill/_story.md index ceb20eb..ee540a4 100644 --- a/docs/work/library-evaluation-policy/04-evaluate-library-skill/_story.md +++ b/docs/work/epics/library-evaluation-policy/04-evaluate-library-skill/_story.md @@ -8,7 +8,7 @@ feature: tooling depends-on: [01-trace-schema-foundation] blocks: [05-human-guide] created: 2026-05-14T06:52:02+02:00 -updated: 2026-05-14T19:16:52.691Z +updated: 2026-05-14T19:21:52.308Z --- ## Goal diff --git a/docs/work/library-evaluation-policy/05-human-guide/_story.md b/docs/work/epics/library-evaluation-policy/05-human-guide/_story.md similarity index 98% rename from docs/work/library-evaluation-policy/05-human-guide/_story.md rename to docs/work/epics/library-evaluation-policy/05-human-guide/_story.md index e992840..b0f1438 100644 --- a/docs/work/library-evaluation-policy/05-human-guide/_story.md +++ b/docs/work/epics/library-evaluation-policy/05-human-guide/_story.md @@ -8,7 +8,7 @@ feature: docs depends-on: [04-evaluate-library-skill] blocks: [09-claude-md-update] created: 2026-05-14T06:52:02+02:00 -updated: 2026-05-14T19:16:52.691Z +updated: 2026-05-14T19:21:52.308Z --- ## Goal diff --git a/docs/work/library-evaluation-policy/06-sandcastle-reviewer-prompt/_story.md b/docs/work/epics/library-evaluation-policy/06-sandcastle-reviewer-prompt/_story.md similarity index 98% rename from docs/work/library-evaluation-policy/06-sandcastle-reviewer-prompt/_story.md rename to docs/work/epics/library-evaluation-policy/06-sandcastle-reviewer-prompt/_story.md index 905b5f2..5e4a071 100644 --- a/docs/work/library-evaluation-policy/06-sandcastle-reviewer-prompt/_story.md +++ b/docs/work/epics/library-evaluation-policy/06-sandcastle-reviewer-prompt/_story.md @@ -8,7 +8,7 @@ feature: tooling depends-on: [02-pre-commit-check-script] blocks: [] created: 2026-05-14T06:52:02+02:00 -updated: 2026-05-14T19:16:52.691Z +updated: 2026-05-14T19:21:52.308Z --- ## Goal diff --git a/docs/work/library-evaluation-policy/07-generator-pre-shipped-traces/_story.md b/docs/work/epics/library-evaluation-policy/07-generator-pre-shipped-traces/_story.md similarity index 98% rename from docs/work/library-evaluation-policy/07-generator-pre-shipped-traces/_story.md rename to docs/work/epics/library-evaluation-policy/07-generator-pre-shipped-traces/_story.md index 9f05519..2e4f76e 100644 --- a/docs/work/library-evaluation-policy/07-generator-pre-shipped-traces/_story.md +++ b/docs/work/epics/library-evaluation-policy/07-generator-pre-shipped-traces/_story.md @@ -8,7 +8,7 @@ feature: tooling depends-on: [01-trace-schema-foundation] blocks: [] created: 2026-05-14T06:52:02+02:00 -updated: 2026-05-14T19:16:52.691Z +updated: 2026-05-14T19:21:52.308Z --- ## Goal diff --git a/docs/work/library-evaluation-policy/08-backfill-traces/_story.md b/docs/work/epics/library-evaluation-policy/08-backfill-traces/_story.md similarity index 98% rename from docs/work/library-evaluation-policy/08-backfill-traces/_story.md rename to docs/work/epics/library-evaluation-policy/08-backfill-traces/_story.md index d316ec2..9955e07 100644 --- a/docs/work/library-evaluation-policy/08-backfill-traces/_story.md +++ b/docs/work/epics/library-evaluation-policy/08-backfill-traces/_story.md @@ -8,7 +8,7 @@ feature: docs depends-on: [01-trace-schema-foundation] blocks: [] created: 2026-05-14T06:52:02+02:00 -updated: 2026-05-14T19:16:52.691Z +updated: 2026-05-14T19:21:52.308Z --- ## Goal diff --git a/docs/work/library-evaluation-policy/09-claude-md-update/_story.md b/docs/work/epics/library-evaluation-policy/09-claude-md-update/_story.md similarity index 98% rename from docs/work/library-evaluation-policy/09-claude-md-update/_story.md rename to docs/work/epics/library-evaluation-policy/09-claude-md-update/_story.md index c5deeb1..97f65dd 100644 --- a/docs/work/library-evaluation-policy/09-claude-md-update/_story.md +++ b/docs/work/epics/library-evaluation-policy/09-claude-md-update/_story.md @@ -8,7 +8,7 @@ feature: docs depends-on: [05-human-guide] blocks: [] created: 2026-05-14T06:52:02+02:00 -updated: 2026-05-14T19:16:52.691Z +updated: 2026-05-14T19:21:52.308Z --- ## Goal diff --git a/docs/work/library-evaluation-policy/_epic.md b/docs/work/epics/library-evaluation-policy/_epic.md similarity index 98% rename from docs/work/library-evaluation-policy/_epic.md rename to docs/work/epics/library-evaluation-policy/_epic.md index d360978..8f1474d 100644 --- a/docs/work/library-evaluation-policy/_epic.md +++ b/docs/work/epics/library-evaluation-policy/_epic.md @@ -6,7 +6,7 @@ type: epic status: done features: [scripts, tooling, docs] created: 2026-05-14T00:00:00Z -updated: 2026-05-14T19:16:52.691Z +updated: 2026-05-14T19:21:52.308Z --- ## Goal diff --git a/scripts/work/decompose.mjs b/scripts/work/decompose.mjs index ba66a84..29a931a 100644 --- a/scripts/work/decompose.mjs +++ b/scripts/work/decompose.mjs @@ -4,7 +4,7 @@ * * Decomposer dispatcher — takes an approved PRD and invokes the decomposer * agent to write the epic folder + per-requirement story files under - * docs/work//. + * docs/work/epics//. * * Default mode (no --execute): print the dispatch plan + validate the PRD * (refuses to proceed on draft / in-review / shipped). Safe anywhere. @@ -82,7 +82,7 @@ export function printDecomposePlan(prdId, prdPath, frontmatter) { console.log(); console.log(` Decomposer prompt: .sandcastle/decomposer.prompt.md`); console.log( - ` Output: docs/work//_epic.md + per-requirement story files`, + ` Output: docs/work/epics//_epic.md + per-requirement story files`, ); console.log(); console.log("To run for real:"); @@ -205,7 +205,7 @@ export async function executeDecompose(prdId, prdPath, prdText) { console.log(); console.log("=== Suggested next steps ==="); console.log( - ` 1. Inspect the new epic folder under docs/work// on branch ${result.branch}`, + ` 1. Inspect the new epic folder under docs/work/epics// on branch ${result.branch}`, ); console.log( ` 2. Review the generated stories + tasks; edit anything that should change`, diff --git a/scripts/work/dispatch.mjs b/scripts/work/dispatch.mjs index 8fd24db..8e031e4 100644 --- a/scripts/work/dispatch.mjs +++ b/scripts/work/dispatch.mjs @@ -30,7 +30,13 @@ export function findNextTask(workRoot = WORK_ROOT) { const state = buildState(workRoot); if (state.ready.length === 0) return null; const next = state.ready[0]; - const storyPath = path.join(workRoot, next.epic, next.story, "_story.md"); + const storyPath = path.join( + workRoot, + "epics", + next.epic, + next.story, + "_story.md", + ); if (!fs.existsSync(storyPath)) return null; const storyContent = fs.readFileSync(storyPath, "utf8"); const { bulletLine, bulletIndex } = findFirstUncheckedBullet(storyContent); @@ -198,7 +204,7 @@ export function readFrontmatterStatus(content) { * files, applied at the parent-epic granularity. */ export function tickStoryBulletInEpic(workRoot, epicId, storyId) { - const epicFile = path.join(workRoot, epicId, "_epic.md"); + const epicFile = path.join(workRoot, "epics", epicId, "_epic.md"); if (!fs.existsSync(epicFile)) return false; const content = fs.readFileSync(epicFile, "utf8"); const lines = content.split("\n"); @@ -230,7 +236,7 @@ export function tickStoryBulletInEpic(workRoot, epicId, storyId) { * frontmatter to `status: done`. Returns true if it flipped, false otherwise. */ export function flipEpicDoneIfAllStoriesDone(workRoot, epicId) { - const epicDir = path.join(workRoot, epicId); + const epicDir = path.join(workRoot, "epics", epicId); const epicFile = path.join(epicDir, "_epic.md"); if (!fs.existsSync(epicFile)) return false; const epicContent = fs.readFileSync(epicFile, "utf8"); @@ -500,7 +506,10 @@ function applyApprovedState(next) { const filesToStage = [path.relative(REPO_ROOT, next.storyPath)]; if (epicFlipped || epicBulletTicked) { filesToStage.push( - path.relative(REPO_ROOT, path.join(WORK_ROOT, next.epic, "_epic.md")), + path.relative( + REPO_ROOT, + path.join(WORK_ROOT, "epics", next.epic, "_epic.md"), + ), ); } const commitMsg = epicFlipped diff --git a/scripts/work/prd-ship.mjs b/scripts/work/prd-ship.mjs index 5d3f7ac..bfb3c5f 100644 --- a/scripts/work/prd-ship.mjs +++ b/scripts/work/prd-ship.mjs @@ -144,11 +144,13 @@ export function flipPrdStatus(text, { shippedDate, commits } = {}) { */ export function deriveShippingCommits(repoRoot, prdId, workRoot) { // Find the epic whose `prd:` matches this prdId - const entries = fs.readdirSync(workRoot, { withFileTypes: true }); + const epicsRoot = path.join(workRoot, "epics"); + if (!fs.existsSync(epicsRoot)) return []; + const entries = fs.readdirSync(epicsRoot, { withFileTypes: true }); let epicDir = null; for (const entry of entries) { if (!entry.isDirectory()) continue; - const epicFile = path.join(workRoot, entry.name, "_epic.md"); + const epicFile = path.join(epicsRoot, entry.name, "_epic.md"); if (!fs.existsSync(epicFile)) continue; const { frontmatter } = parseFrontmatter(fs.readFileSync(epicFile, "utf8")); if (frontmatter.prd === prdId) { @@ -160,7 +162,7 @@ export function deriveShippingCommits(repoRoot, prdId, workRoot) { try { const log = execSync( - `git log --format=%h --reverse -- docs/work/${epicDir}/`, + `git log --format=%h --reverse -- docs/work/epics/${epicDir}/`, { cwd: repoRoot, encoding: "utf8" }, ); return log.trim().split("\n").filter(Boolean); diff --git a/scripts/work/state-builder.mjs b/scripts/work/state-builder.mjs index 7aa735a..3829184 100644 --- a/scripts/work/state-builder.mjs +++ b/scripts/work/state-builder.mjs @@ -1,13 +1,10 @@ import fs from "node:fs"; import path from "node:path"; -const SKIP_FOLDERS = new Set(["_templates", "_system", "prds"]); -const SKIP_FILES = new Set(["README.md", "_state.json"]); - /** - * Walk the `docs/work/` tree starting at `workRoot` and return a structured - * state object. Each epic folder must contain `_epic.md`; each story - * subfolder must contain `_story.md`. + * Walk the `docs/work/epics/` tree under `workRoot` and return a structured + * state object. Each epic folder under `epics/` must contain `_epic.md`; + * each story subfolder must contain `_story.md`. * * Returns: * { @@ -34,11 +31,11 @@ export function buildState(workRoot) { epics: {}, }; - if (!fs.existsSync(workRoot)) return state; + const epicsRoot = path.join(workRoot, "epics"); + if (!fs.existsSync(epicsRoot)) return state; - for (const entry of fs.readdirSync(workRoot)) { - if (SKIP_FOLDERS.has(entry) || SKIP_FILES.has(entry)) continue; - const epicDir = path.join(workRoot, entry); + for (const entry of fs.readdirSync(epicsRoot)) { + const epicDir = path.join(epicsRoot, entry); if (!fs.statSync(epicDir).isDirectory()) continue; const epicFile = path.join(epicDir, "_epic.md"); if (!fs.existsSync(epicFile)) continue;