@jaybeeuu/agent-cortex 2.1.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (181) hide show
  1. package/CHANGELOG.md +411 -0
  2. package/README.md +33 -13
  3. package/agents/README.md +22 -10
  4. package/agents/plan/agent.md +2 -2
  5. package/agents/ralph/agent.md +126 -88
  6. package/agents/ralph/claude/frontmatter.json +3 -3
  7. package/agents/ralph/claude/wake.md +46 -0
  8. package/agents/ralph/pi/{polling.md → wake.md} +35 -20
  9. package/agents/ralph-plan/agent.md +23 -11
  10. package/bin/agent-cortex.mjs +66 -4
  11. package/bin/installers/claude.mjs +182 -68
  12. package/bin/installers/pi.mjs +200 -24
  13. package/extensions/agent-guardrails/README.md +1 -1
  14. package/extensions/agent-guardrails/guardrails.ts +1 -1
  15. package/extensions/agent-guardrails/index.ts +1 -1
  16. package/extensions/agent-modes/discover.test.ts +2 -2
  17. package/extensions/output-style/README.md +1 -1
  18. package/extensions/output-style/index.ts +2 -2
  19. package/extensions/output-style/output-style.ts +2 -2
  20. package/hooks/claude/scripts/notify.mjs +8 -1
  21. package/lib/cli.mjs +91 -2
  22. package/package.json +27 -3
  23. package/scripts/check-changeset.mjs +4 -0
  24. package/scripts/check-no-sync.mjs +5 -1
  25. package/scripts/lib/compose-agent.mjs +69 -9
  26. package/scripts/lib/fs.mjs +10 -2
  27. package/scripts/lib/migrate.mjs +736 -0
  28. package/scripts/lib/release-gates.mjs +21 -1
  29. package/scripts/lib/skill-frontmatter.mjs +23 -6
  30. package/scripts/lib/skill-links.mjs +52 -0
  31. package/scripts/lib/verify-worker-tree.mjs +25 -0
  32. package/scripts/resolve-publish-command.mjs +4 -0
  33. package/skills/engineering/design-an-interface/SKILL.md +3 -3
  34. package/skills/engineering/grill-with-docs/SKILL.md +3 -5
  35. package/skills/engineering/improve-codebase-architecture/SKILL.md +5 -4
  36. package/skills/engineering/tdd/SKILL.md +5 -7
  37. package/skills/engineering/technical-direction/SKILL.md +5 -5
  38. package/skills/planning/classify-bead/REFERENCE.md +3 -3
  39. package/skills/planning/classify-bead/SKILL.md +14 -9
  40. package/skills/planning/classify-bead/scripts/classify-bead.mjs +5 -4
  41. package/skills/planning/create-task/REFERENCE.md +52 -3
  42. package/skills/planning/create-task/SKILL.md +70 -26
  43. package/skills/planning/create-task/scripts/{create-chores.ts → create-chores.mjs} +48 -23
  44. package/skills/planning/flesh-out-idea/REFERENCE.md +116 -0
  45. package/skills/planning/flesh-out-idea/SKILL.md +146 -0
  46. package/skills/planning/prd-to-tasks/REFERENCE.md +54 -5
  47. package/skills/planning/prd-to-tasks/SKILL.md +22 -16
  48. package/skills/planning/record-idea/FORMAT.md +66 -17
  49. package/skills/planning/record-idea/SKILL.md +48 -24
  50. package/skills/planning/request-refactor-plan/SKILL.md +4 -4
  51. package/skills/planning/spec-to-tickets/SKILL.md +5 -5
  52. package/skills/planning/write-a-prd/SKILL.md +8 -9
  53. package/skills/planning/write-a-ticket/SKILL.md +4 -6
  54. package/skills/productivity/bd-tool/SKILL.md +15 -10
  55. package/skills/productivity/grill-me/SKILL.md +5 -0
  56. package/skills/productivity/init-beads/SKILL.md +3 -3
  57. package/skills/productivity/migration/REFERENCE.md +227 -0
  58. package/skills/productivity/migration/SKILL.md +188 -0
  59. package/skills/productivity/validate-agent-dir/scripts/{validate-agent-dir.ts → validate-agent-dir.mjs} +49 -28
  60. package/skills/productivity/write-a-skill/SKILL.md +5 -5
  61. package/skills/review/maintain-agent-docs/SKILL.md +5 -7
  62. package/skills/review/refactor-skill/SKILL.md +4 -3
  63. package/skills/review/review-security/SKILL.md +3 -5
  64. package/skills/style/style-code/SKILL.md +5 -10
  65. package/skills/style/style-comms/SKILL.md +5 -7
  66. package/skills/style/style-documentation/SKILL.md +5 -6
  67. package/skills/style/style-tests/SKILL.md +5 -7
  68. package/skills/workflow/git-workflow/SKILL.md +52 -26
  69. package/skills/workflow/hitl-collab/SKILL.md +4 -6
  70. package/skills/workflow/plan/SKILL.md +41 -30
  71. package/skills/workflow/ralph/REFERENCE.md +182 -51
  72. package/skills/workflow/ralph/SKILL.md +89 -50
  73. package/skills/workflow/run-pipeline-stage/SKILL.md +72 -71
  74. package/skills/workflow/run-pipeline-stage/playbooks/code.md +11 -0
  75. package/skills/workflow/run-pipeline-stage/playbooks/document.md +12 -0
  76. package/skills/workflow/run-pipeline-stage/playbooks/fix.md +12 -0
  77. package/skills/workflow/run-pipeline-stage/playbooks/review.md +11 -0
  78. package/skills/workflow/run-pipeline-stage/playbooks/verify.md +13 -0
  79. package/skills/workflow/run-pipeline-stage/prompts/stage-runner.md +73 -1
  80. package/token-map.README.md +9 -4
  81. package/token-map.json +13 -6
  82. package/.agents/skills/style-versioning/SKILL.md +0 -172
  83. package/.changeset/README.md +0 -8
  84. package/.changeset/config.json +0 -11
  85. package/.github/workflows/ci.yml +0 -302
  86. package/.junie/guidelines.md +0 -87
  87. package/.junie/mcp/mcp.json +0 -10
  88. package/AGENTS.md +0 -153
  89. package/agents/ralph/claude/polling.md +0 -31
  90. package/agents-native/ralph.md +0 -203
  91. package/docs/claude-hooks.md +0 -144
  92. package/docs/commit-signing.md +0 -231
  93. package/docs/ideas/auto-model-selection.md +0 -75
  94. package/docs/ideas/ban-content-assertion-tests.md +0 -75
  95. package/docs/ideas/bead-progress-notes-for-session-resumption.md +0 -75
  96. package/docs/ideas/classify-beads-via-deterministic-script-with-agent-fallback.md +0 -70
  97. package/docs/ideas/ctx-alias-version-and-update-commands.md +0 -65
  98. package/docs/ideas/ctx-feedback-command-for-capturing-ideas-from-any-machine.md +0 -67
  99. package/docs/ideas/dedicated-review-tests-skill.md +0 -71
  100. package/docs/ideas/deployment-beads-for-post-merge-pipelines.md +0 -36
  101. package/docs/ideas/design-and-delivery-as-separate-bead-trees/design-and-delivery-as-separate-bead-trees.md +0 -99
  102. package/docs/ideas/enable-signed-commit-enforcement-changesets-bot-commits-must-be-signed.md +0 -42
  103. package/docs/ideas/extension-manifests.md +0 -121
  104. package/docs/ideas/improve-pi-system-prompt.md +0 -43
  105. package/docs/ideas/map-every-cortex-tool-to-a-real-pi-equivalent.md +0 -95
  106. package/docs/ideas/model-selector.md +0 -40
  107. package/docs/ideas/pi-task-memory.md +0 -34
  108. package/docs/ideas/qa-extension.md +0 -43
  109. package/docs/ideas/record-idea-implementation-questions.md +0 -68
  110. package/docs/ideas/record-ideas-as-beads.md +0 -115
  111. package/docs/ideas/self-flushing-session.md +0 -72
  112. package/docs/ideas/state-in-beads-not-md.md +0 -69
  113. package/docs/ideas/subagent-visibility.md +0 -72
  114. package/docs/ideas/task-session-context.local.md +0 -95
  115. package/docs/ideas/task-session-context.md +0 -89
  116. package/docs/ideas/test-data-creation-helpers.md +0 -92
  117. package/docs/ideas/test-planning-stage-bead-in-feature-planning.md +0 -68
  118. package/docs/ideas/unified-ci-pipeline.md +0 -28
  119. package/docs/ideas/unify-the-ticket-and-task-decomposition-workflows.md +0 -71
  120. package/docs/ideas/worktree-housekeeping-for-closed-beads.md +0 -39
  121. package/docs/inspirations.md +0 -33
  122. package/docs/research/disable-model-invocation.md +0 -82
  123. package/docs/research/gas-city-research.md +0 -256
  124. package/docs/research/skill-design-research.md +0 -286
  125. package/docs/research/skill-improvements-analysis.md +0 -117
  126. package/docs/research/skill-patterns-research.md +0 -24
  127. package/docs/skills/skill-anatomy.md +0 -200
  128. package/docs/technical-direction/harness-config.md +0 -177
  129. package/docs/technical-direction/migration-execution-labels.md +0 -177
  130. package/docs/user-preferences.md +0 -17
  131. package/extensions/agent-guardrails/tsconfig.json +0 -12
  132. package/extensions/agent-modes/tsconfig.json +0 -12
  133. package/extensions/output-style/tsconfig.json +0 -12
  134. package/extensions/session-start/tsconfig.json +0 -12
  135. package/extensions/skill-stats/pnpm-lock.yaml +0 -329
  136. package/extensions/skill-stats/tsconfig.json +0 -12
  137. package/extensions/subagent/agents/planner.md +0 -37
  138. package/extensions/subagent/agents/reviewer.md +0 -35
  139. package/extensions/subagent/agents/scout.md +0 -50
  140. package/extensions/subagent/agents/worker.md +0 -24
  141. package/extensions/subagent/prompts/implement-and-review.md +0 -10
  142. package/extensions/subagent/prompts/implement.md +0 -10
  143. package/extensions/subagent/prompts/scout-and-plan.md +0 -9
  144. package/extensions/subagent/tsconfig.json +0 -12
  145. package/pi/keybindings.json +0 -3
  146. package/pi/settings.json +0 -34
  147. package/pnpm-workspace.yaml +0 -14
  148. package/skills/planning/create-task/scripts/package.json +0 -14
  149. package/skills/planning/create-task/scripts/pnpm-lock.yaml +0 -342
  150. package/skills/planning/create-task/scripts/tsconfig.json +0 -12
  151. package/skills/planning/record-idea/scripts/new-idea.sh +0 -89
  152. package/skills/productivity/validate-agent-dir/scripts/package.json +0 -15
  153. package/skills/productivity/validate-agent-dir/scripts/pnpm-lock.yaml +0 -329
  154. package/skills/productivity/validate-agent-dir/scripts/pnpm-workspace.yaml +0 -2
  155. package/skills/productivity/validate-agent-dir/scripts/tsconfig.json +0 -19
  156. package/skills/productivity/validate-agent-dir/scripts/validate-agent-dir.test.ts +0 -317
  157. package/skills/workflow/run-pipeline-stage/REFERENCE.md +0 -22
  158. package/skills/workflow/run-pipeline-stage/scripts/generate-progress.test.ts +0 -682
  159. package/skills/workflow/run-pipeline-stage/scripts/generate-progress.ts +0 -588
  160. package/skills/workflow/run-pipeline-stage/scripts/package.json +0 -15
  161. package/skills/workflow/run-pipeline-stage/scripts/pnpm-lock.yaml +0 -342
  162. package/skills/workflow/run-pipeline-stage/scripts/pnpm-workspace.yaml +0 -2
  163. package/skills/workflow/run-pipeline-stage/scripts/tsconfig.json +0 -12
  164. package/test/classify-bead.test.mjs +0 -277
  165. package/test/claude-installer.test.mjs +0 -308
  166. package/test/cli.test.mjs +0 -314
  167. package/test/create-chores.test.mjs +0 -85
  168. package/test/fake-bd.test.mjs +0 -72
  169. package/test/fs.test.mjs +0 -76
  170. package/test/helpers/fake-bd.mjs +0 -87
  171. package/test/helpers/fake-claude.mjs +0 -152
  172. package/test/helpers/fake-pi.mjs +0 -132
  173. package/test/installer.test.mjs +0 -806
  174. package/test/notify-hook.test.mjs +0 -63
  175. package/test/pending-gates.test.mjs +0 -147
  176. package/test/pi-installer.test.mjs +0 -785
  177. package/test/pi-register.test.mjs +0 -342
  178. package/test/pi-sweep.test.mjs +0 -619
  179. package/test/release-gates.test.mjs +0 -190
  180. package/test/skill-frontmatter.test.mjs +0 -137
  181. package/test/verify-worker-tree.test.mjs +0 -120
@@ -1,16 +1,18 @@
1
1
  ---
2
2
  name: create-task
3
- description: Create a task bead, classify it as AFK or HITL, and if AFK expand it into pipeline stage chores plus a HITL PR gate. Use when starting tracked work with implementation and review gates — "create a task for this", "track this end-to-end", or "get this into the ralph pipeline".
3
+ description: Create a task or feature bead, classify each child as AFK or HITL, and expand AFK beads into pipeline stage chores plus a HITL PR gate. Use when starting tracked work with implementation and review gates — "create a task for this", "track this end-to-end", or "get this into the ralph pipeline".
4
4
  ---
5
5
 
6
6
  # Create Task
7
7
 
8
- Turn a piece of work into a tracked bead, classify it for autonomous (AFK) or human-in-the-loop (HITL) execution, and — when AFK — expand it into the standard pipeline: one chore bead per stage plus a HITL PR gate task so a human always reviews the finished branch. Parameters: `title` (required), `description` (required), `priority` (0–3, default 2), `parent` (epic bead ID, optional — sets a `parent-child` dependency). The description must carry the task's required section — `## Acceptance Criteria` — which `--validate` enforces; fill it from agreed answers, not assumptions (see `bd-tool` → Required sections).
8
+ Turn a piece of work into a tracked bead, classify it for autonomous (AFK) or human-in-the-loop (HITL) execution, and — when AFK — expand it into the standard pipeline: one chore bead per stage plus a HITL PR gate task so a human always reviews the finished branch. Parameters: `title` (required), `description` (required), `priority` (0–3, default 2), `parent` (feature or epic bead ID, optional — sets ownership at create time). The description must carry the task's required section — `## Acceptance Criteria` — which `--validate` enforces; fill it from agreed answers, not assumptions (see `bd-tool` → Required sections).
9
9
 
10
10
  ## When to use
11
11
 
12
12
  - Starting new tracked work that must move through implementation, verification, and review gates — user phrases like "create a task for this", "track this work end-to-end", or "get this into the ralph pipeline".
13
+ - Expanding an **existing** AFK task bead that has no `stage:*` chore children — run step 7 only (see _Expanding an existing bead_).
13
14
  - A caller (`prd-to-tasks`, `ralph-plan`) needs one task bead with the full child-chore structure.
15
+ - A workstream of several deliverables needs a planning bead in front of them — the feature path in steps 5–6, then step 7 for each AFK impl child.
14
16
 
15
17
  ## When NOT to use
16
18
 
@@ -21,50 +23,84 @@ Turn a piece of work into a tracked bead, classify it for autonomous (AFK) or hu
21
23
 
22
24
  ## Workflow
23
25
 
24
- 1. **Create the parent bead.** The description must contain the task's required section —
26
+ 1. **Pick the shape.** One deliverable an agent can finish in a session → a **task** bead (steps 2–4). A workstream of several deliverables that needs design settled before code → a **feature** bead carrying a planning bead and one impl task per deliverable (steps 5–6, then step 7 for each AFK impl child).
27
+
28
+ **Ownership is `--parent`; ordering is `bd dep add`.** `--parent` records who owns a bead at create time; a dependency records what must finish first. Never express one as the other.
29
+
30
+ 2. **Create the task bead.** The description must contain the task's required section —
25
31
  `## Acceptance Criteria` — or `--validate` rejects creation. Fill it from agreed answers, not
26
32
  assumptions (see `bd-tool` → Required sections).
27
33
 
28
34
  ```bash
29
- bd create "<title>" --description "<description>" --priority <priority> --validate
35
+ bd create "<title>" --type task --description "<description>" --priority <priority> \
36
+ [--parent <feature-id> --no-inherit-labels] --validate
30
37
  bd lint <new-id>
31
38
  ```
32
39
 
33
- If a `parent` epic was provided, record the dependency:
34
-
35
- ```bash
36
- bd dep add <new-id> <parent> --type parent-child
37
- ```
40
+ Pass `--parent` when a container bead was supplied, and `--no-inherit-labels` with it: `bd` copies a parent's labels at create time, so a child of an `execution:hitl` feature would acquire `execution:hitl` beside the classifier's `execution:afk` — an unroutable bead. No `parent-child` dependency is needed; `--parent` already recorded ownership.
38
41
 
39
- 2. **Classify deterministically.** Run the `classify-bead` classifier — it resolves an existing label, the legacy `## Type` field, and explicit heuristic signals without a model call, and applies the label itself when it resolves:
42
+ 3. **Classify deterministically.** Run the `classify-bead` classifier — it resolves an existing label, the legacy `## Type` field, and explicit heuristic signals without a model call, and applies the label itself when it resolves:
40
43
 
41
44
  ```bash
42
45
  # Run from the TARGET project's directory — bd resolves its beads DB from cwd.
43
46
  node <skill-scripts>/../../classify-bead/scripts/classify-bead.mjs <new-id>
44
47
  ```
45
48
 
46
- - `"classification": "afk" | "hitl"` → the label is applied; branch on that class in step 3.
49
+ - `"classification": "afk" | "hitl"` → the label is applied; branch on that class in step 4.
47
50
  - `"escalate": true` → delegate to the `classify-bead` skill as a subagent via {{TOOL:task}}; it applies the rubric and tags the bead.
48
51
 
49
52
  `<skill-scripts>` is the absolute path to this skill's own `scripts/` directory, resolved from wherever this skill was loaded. Sibling skills sit alongside this skill's directory in every harness, so `../../classify-bead/scripts/` resolves to the classifier.
50
53
 
51
- 3. **Branch on classification.**
54
+ 4. **Branch on classification.**
52
55
  - **HITL** — stop here. Report the bead ID and classification to the caller. Do not create pipeline chores: a human drives the work, so the chore tree does not apply.
53
- - **AFK** — continue to step 4.
56
+ - **AFK** — continue to step 7.
54
57
 
55
- 4. **Expand into pipeline stage chores.** Run the `create-chores` script, which reads this skill's `pipeline.json` and deterministically creates all stage chores plus the PR gate bead in one shot:
58
+ 5. **Feature path: create the container.** A feature is a container a person owns, so it is `execution:hitl`; its children state the class of their own work, so nothing aggregates upward.
59
+
60
+ ```bash
61
+ bd create "<Feature title>" --type feature --priority <priority> \
62
+ -l execution:hitl --description "<feature body>" --validate
63
+ ```
64
+
65
+ 6. **Feature path: planning bead, then impl children.** The planning bead is the design gate; each impl child delivers one slice and waits for it.
66
+
67
+ ```bash
68
+ # Design gate: human-owned, owned by the feature, blocking every impl child.
69
+ bd create "Plan: <Feature title>" --type task --priority <priority> \
70
+ -l execution:hitl --parent <feature-id> --no-inherit-labels \
71
+ --description "<cold-start plan>" --validate
72
+
73
+ # One impl child per deliverable: owned by the feature, labelled for its own work.
74
+ bd create "<Deliverable title>" --type task --priority <priority> \
75
+ -l execution:afk --parent <feature-id> --no-inherit-labels \
76
+ --description "<deliverable body>" --validate
77
+
78
+ # Readiness gate: the child leaves `bd ready` until planning closes.
79
+ bd dep add <impl-task-id> <planning-bead-id>
80
+ ```
81
+
82
+ The planning bead is cold-start ready — what and why, decisions already made, open questions and risks, references — and needs `## Acceptance Criteria`, which `--validate` requires for type `task` (template in `REFERENCE.md` → Hierarchy). A deliverable that genuinely needs a human — visual sign-off, credentials, hardware — is created `-l execution:hitl` and stops there.
83
+
84
+ 7. **Expand into pipeline stage chores.** Run the `create-chores` script, which reads this skill's `pipeline.json` and deterministically creates all stage chores plus the PR gate bead in one shot:
56
85
 
57
86
  ```bash
58
87
  # Run from the TARGET project's directory — bd resolves its beads DB from cwd;
59
88
  # the skill's own location or `pnpm --prefix <scripts>` would target the wrong tree.
60
- <skill-scripts>/node_modules/.bin/tsx \
61
- <skill-scripts>/create-chores.ts \
89
+ node <skill-scripts>/create-chores.mjs \
62
90
  --parent <parent-id> [--priority <priority>]
63
91
  ```
64
92
 
65
93
  `<skill-scripts>` is the absolute path to this skill's own `scripts/` directory, resolved from wherever this skill was loaded — it varies by harness and install location, so never hardcode one harness's path.
66
94
 
67
- 5. **Report.** Return the parent bead ID, the classification (`AFK`), and the created child bead IDs from the script output (including `featurePrReview`).
95
+ On the feature path, run it **once per AFK impl child**, with `--parent <impl-task-id>` — never the feature ID: stage chores inherit their parent's labels, the script checks only that it was handed a parent ID (`REFERENCE.md` → PR gate bead), so an `execution:hitl` feature parent yields a chore tree no executor routes. A deliverable created `execution:hitl` in step 6 is not expanded.
96
+
97
+ 8. **Report.** Return the bead ID (or, on the feature path, the feature ID plus every planning and impl child ID), the classification of each expanded bead (`AFK`), and the created stage chore IDs from the script output (including `featurePrReview`) — one mapping per expanded impl child on the feature path.
98
+
99
+ ### Expanding an existing bead
100
+
101
+ Steps 2–6 create beads; step 7 expands one. A bead that already exists but has no `stage:*` chore children — an AFK task filed before the pipeline existed, or one ralph found chore-less — is a supported entry point: run step 7's `create-chores.mjs --parent <existing-id> --priority <its-own-priority>` directly, then report the mapping. No create steps, no new description, no re-classification.
102
+
103
+ **Never re-run `create-task` for an existing bead.** It creates a bead first and expands second, so the run leaves a **second parent** beside the original, which stays chore-less — the duplicate ralph's expansion guard exists to prevent. `create-chores.mjs` expands a bead that already exists; only step 2 creates a bead.
68
104
 
69
105
  ## Red Flags
70
106
 
@@ -73,7 +109,10 @@ Turn a piece of work into a tracked bead, classify it for autonomous (AFK) or hu
73
109
  - **Spawning the `classify-bead` subagent when the classifier already resolved the bead.** The deterministic script is the short-circuit; a subagent is only for `escalate: true`.
74
110
  - **Skipping the classifier and classifying by hand.** The rubric is a subagent's job; a hand-rolled guess drifts from it.
75
111
  - **Expanding an HITL bead.** If classification is HITL, stop — creating a chore tree for human-driven work is wrong.
112
+ - **Expanding an existing bead by re-running `create-task`.** That step creates a bead, so the original stays chore-less and gains a second parent beside it. Run `create-chores.mjs --parent <existing-id>` instead.
76
113
  - **Hardcoding `<skill-scripts>`.** The install path differs per harness (plugin cache, installed-plugins, dev checkout); resolve it at runtime.
114
+ - **Creating a feature with no planning bead.** A feature that goes straight to impl children is a feature nobody designed. The planning bead keeps the children blocked until the design is confirmed.
115
+ - **Expressing ownership as a dependency.** `bd dep add <child> <parent>` mixes hierarchy into the readiness gate; pass `--parent` at create time instead.
77
116
 
78
117
  ## Common Rationalizations
79
118
 
@@ -87,28 +126,33 @@ Turn a piece of work into a tracked bead, classify it for autonomous (AFK) or hu
87
126
 
88
127
  - **The script owns the expansion contract.** Pipeline stages, titles, labels, dependency chains, and the PR gate are deterministic — a one-shot script keeps every chore identical to the contract and reproducible across runs.
89
128
  - **The PR gate is a hard human checkpoint.** Every AFK task ends with a `featurePrReview` task that blocks the final document stage, so automated work never merges without a human reviewing the branch.
129
+ - **Each bead states its own execution class.** Containers are human-owned; the work inside them is AFK unless a deliverable genuinely needs a person. Nothing aggregates upward, so a label always answers "who does this?" for that bead.
90
130
 
91
- ## Cross-skill references
131
+ ## See Also
92
132
 
93
- - `classify-bead` — deterministic classifier first, rubric subagent only on escalation (step 2).
133
+ - [classify-bead](../classify-bead/SKILL.md) — step 3 defers to its deterministic classifier; the rubric subagent runs only on escalation.
134
+ - [prd-to-tasks](../prd-to-tasks/SKILL.md) — calls this skill per vertical slice; load it when the input is a whole PRD.
94
135
 
95
136
  ## Examples
96
137
 
97
- Input: title `Add export API to invoices`, description `…`, priority `2`, parent `epic-456`. Output: the parent bead ID plus the script's JSON mapping stage IDs → chore bead IDs, with `featurePrReview` as the HITL PR gate:
138
+ Input: title `Add export API to invoices`, description `…`, priority `2`, parent `feature-456`. Output: the bead ID plus the script's JSON mapping stage IDs → chore bead IDs, with `featurePrReview` as the HITL PR gate:
98
139
 
99
140
  ```json
100
141
  {"code": "abc123", "verify": "def456", "review": "ghi789", "document": "jkl012", "featurePrReview": "bd-mno345"}
101
142
  ```
102
143
 
144
+ Feature path input: "several endpoints, a UI, and a migration". Output: `feature-456` (`execution:hitl`), `plan-457` ("Plan: …", `execution:hitl`, owned by the feature, blocking every child), and one `execution:afk` impl child per deliverable, each expanded into its own stage chores plus PR gate.
145
+
103
146
  The full bead-property contract (titles, labels, dependencies per chore and for the PR gate) is in `REFERENCE.md`.
104
147
 
105
148
  ## Verification checklist
106
149
 
107
- - [ ] Parent bead exists with the correct title, description, and priority.
108
- - [ ] Parent bead created with `--validate`, and `bd lint <id>` reports no missing sections.
109
- - [ ] `parent-child` dependency added when a parent epic was supplied.
110
- - [ ] `implementation-type` label present on the parent bead (`bd label list <id>`) — resolved by the classifier or, on escalation, the rubric subagent.
150
+ - [ ] Bead created with `--validate`, and `bd lint <id>` reports no missing sections.
151
+ - [ ] `--parent` used for ownership when a container was supplied, with `--no-inherit-labels` beside it.
152
+ - [ ] `execution:afk` or `execution:hitl` label present on the bead (`bd label list <id>`) — resolved by the classifier or, on escalation, the rubric subagent.
111
153
  - [ ] HITL path: no pipeline chores created, caller told the classification. AFK path: script ran from the target project's cwd and its JSON contains every stage ID plus `featurePrReview`.
154
+ - [ ] Feature path: the feature is `execution:hitl`, exactly one planning bead is owned by it and carries the cold-start contract, and every impl child is `execution:afk` and depends on the planning bead.
112
155
  - [ ] Chore titles/labels/dependencies match the contract (`[<parent-id>] <stage title>`, `stage:<id>`, `parent-child` to parent, `blocks` per `dependsOn`), verified against `REFERENCE.md`.
113
- - [ ] PR gate task exists and blocks the final document stage chore, carrying **exactly one** `implementation-type` label — `implementation-type:hitl` (never an inherited `implementation-type:afk` alongside it) — plus `lifecycle:feature-pr`.
114
- - [ ] Report returned the parent bead ID, classification, and all child bead IDs.
156
+ - [ ] PR gate task exists and blocks the final document stage chore, carrying **exactly one** `execution` label — `execution:hitl` (never an inherited `execution:afk` alongside it) — plus `lifecycle:feature-pr`.
157
+ - [ ] Report returned the bead ID, classification, and all child bead IDs.
158
+ - [ ] Expansion-only run (existing bead): the create steps skipped, `create-chores.mjs` expanded that bead, and the tree still holds exactly one parent.
@@ -1,3 +1,13 @@
1
+ // @ts-check
2
+ // Pre-create the pipeline stage chores for a task bead, plus the feature PR
3
+ // review gate, from `pipeline.json`.
4
+ //
5
+ // The parent is an `execution:afk` bead. Stage chores inherit that label from it, so
6
+ // create-chores does not classify: a parent that is hitl or unlabelled silently yields
7
+ // a chore tree no executor routes. Check the parent's labels before invoking this.
8
+ //
9
+ // Zero dependencies: run with `node create-chores.mjs --parent <bead-id>`.
10
+
1
11
  import { execSync } from 'node:child_process';
2
12
  import { readFileSync } from 'node:fs';
3
13
  import { resolve, dirname } from 'node:path';
@@ -5,23 +15,30 @@ import { fileURLToPath } from 'node:url';
5
15
 
6
16
  // ─── Types ────────────────────────────────────────────────────────────────────
7
17
 
8
- interface Stage {
9
- id: string;
10
- title: string;
11
- description: string;
12
- template: string;
13
- dependsOn: string[];
14
- }
15
-
16
- interface Pipeline {
17
- maxFixRounds: number;
18
- stages: Stage[];
19
- }
18
+ /**
19
+ * @typedef {object} Stage
20
+ * @property {string} id
21
+ * @property {string} title
22
+ * @property {string} description
23
+ * @property {string} template
24
+ * @property {string[]} dependsOn
25
+ */
26
+
27
+ /**
28
+ * @typedef {object} Pipeline
29
+ * @property {number} maxFixRounds
30
+ * @property {Stage[]} stages
31
+ */
20
32
 
21
33
  // ─── Args ─────────────────────────────────────────────────────────────────────
22
34
 
23
- function parseArgs(args: string[]): { parentId: string; priority: string } {
24
- let parentId: string | undefined;
35
+ /**
36
+ * @param {string[]} args
37
+ * @returns {{ parentId: string, priority: string }}
38
+ */
39
+ function parseArgs(args) {
40
+ /** @type {string | undefined} */
41
+ let parentId;
25
42
  let priority = '2';
26
43
 
27
44
  for (let i = 0; i < args.length; i++) {
@@ -30,7 +47,7 @@ function parseArgs(args: string[]): { parentId: string; priority: string } {
30
47
  }
31
48
 
32
49
  if (!parentId) {
33
- console.error('Usage: create-chores.ts --parent <bead-id> [--priority <0-4>]');
50
+ console.error('Usage: create-chores.mjs --parent <bead-id> [--priority <0-4>]');
34
51
  process.exit(1);
35
52
  }
36
53
 
@@ -43,7 +60,11 @@ function parseArgs(args: string[]): { parentId: string; priority: string } {
43
60
  // Defaults to `bd`, resolved via PATH.
44
61
  const BD_PATH = process.env.BD_PATH || 'bd';
45
62
 
46
- function run(args: string[]): string {
63
+ /**
64
+ * @param {string[]} args
65
+ * @returns {string}
66
+ */
67
+ function run(args) {
47
68
  const cmd = args[0] === 'bd' ? [BD_PATH, ...args.slice(1)] : args;
48
69
  return execSync(cmd.join(' '), { encoding: 'utf-8' }).trim();
49
70
  }
@@ -56,9 +77,11 @@ const __dirname = dirname(__filename);
56
77
  const { parentId, priority } = parseArgs(process.argv.slice(2));
57
78
 
58
79
  const pipelinePath = resolve(__dirname, '..', 'pipeline.json');
59
- const pipeline: Pipeline = JSON.parse(readFileSync(pipelinePath, 'utf-8'));
80
+ /** @type {Pipeline} */
81
+ const pipeline = JSON.parse(readFileSync(pipelinePath, 'utf-8'));
60
82
 
61
- const stageToBeadId = new Map<string, string>();
83
+ /** @type {Map<string, string>} */
84
+ const stageToBeadId = new Map();
62
85
 
63
86
  for (const stage of pipeline.stages) {
64
87
  const title = `[${parentId}] ${stage.title}`;
@@ -107,17 +130,19 @@ const prGateBeadId = run([
107
130
  // section. Stage chores require no sections and deliberately omit the flag.
108
131
  '--validate',
109
132
  '--priority', priority,
110
- '--labels', 'implementation-type:hitl,lifecycle:feature-pr',
133
+ '--labels', 'execution:hitl,lifecycle:feature-pr',
111
134
  '--parent', parentId,
112
- // The gate declares its own labels; opt out of bd's create-time parent-label
113
- // inheritance so its explicit :hitl is never joined by an inherited :afk.
114
- // Stage chores deliberately keep inheriting :afk -- do not add this there.
135
+ // The gate declares its own execution class (it is human-owned review work), so opt
136
+ // out of bd's create-time parent-label inheritance and its explicit :hitl is never
137
+ // joined by an inherited :afk. Stage chores deliberately keep inheriting the parent's
138
+ // :afk -- do not add this flag there.
115
139
  '--no-inherit-labels',
116
140
  '--silent',
117
141
  ]);
118
142
  run(['bd', 'dep', 'add', prGateBeadId, documentStageBeadId, '--type', 'blocks']);
119
143
 
120
- const result: Record<string, string> = {
144
+ /** @type {Record<string, string>} */
145
+ const result = {
121
146
  ...Object.fromEntries(stageToBeadId),
122
147
  featurePrReview: prGateBeadId,
123
148
  };
@@ -0,0 +1,116 @@
1
+ # flesh-out-idea reference
2
+
3
+ Detail behind `SKILL.md`: the queries, the round-to-round field updates, and a full promotion
4
+ transcript. Field names and section markers are the contract — see `record-idea`'s `FORMAT.md`
5
+ for the capture-side mapping this builds on.
6
+
7
+ ## Queries
8
+
9
+ | Question | Command |
10
+ |---|---|
11
+ | Which ideas can be worked now? | `bd ready -l kind:idea` |
12
+ | Every idea, blocked and deferred included | `bd list -l kind:idea` |
13
+ | One idea, fields and markers | `bd show <id> --json` |
14
+ | Why is this idea blocked? | `bd show <id>` — its dependency list, with each blocker's status |
15
+
16
+ `bd ready` applies blocker-aware semantics: an idea that depends on open work is omitted, while
17
+ `bd list` still returns it. That difference is the readiness signal — there is no separate
18
+ `ready:` label to maintain.
19
+
20
+ To park an idea behind other work, express it as a dependency rather than an exclusion label:
21
+
22
+ ```bash
23
+ bd dep add <idea-id> <blocker-id> # "<idea> depends on <blocker>"
24
+ ```
25
+
26
+ ## Fields and verbs
27
+
28
+ | Field | Verb | Use it for |
29
+ |---|---|---|
30
+ | `--description` | `bd update <id> -d …` | Problem, who benefits, proposed outcome — rewrite when an answer supersedes the text |
31
+ | `--design` | `bd update <id> --design …` | How we might do it: mechanism, alternatives, deciding tradeoffs |
32
+ | `--notes` | `bd update <id> --append-notes …` | Validity check, constraints, next validation step, provenance — append so rounds accumulate |
33
+ | `--acceptance` | `bd update <id> --acceptance …` | Promotion criteria, restated once the interview settles what "ready" means |
34
+ | `--priority` | `bd update <id> -p <P0-P4>` | Moves as the idea gets clearer or more urgent |
35
+
36
+ Multiple `##` sections share one field; keep every marker, because that is how the next round
37
+ finds the section to update.
38
+
39
+ ## Round-by-round updates
40
+
41
+ Round 1 deepens the mechanism and records what is still open:
42
+
43
+ ```bash
44
+ bd update proj-idea1 \
45
+ --design "## How we might do it
46
+
47
+ Two candidates: a pre-commit hook, or a CI gate. The hook catches the mistake earlier; the CI
48
+ gate cannot be bypassed locally. The deciding tradeoff is whether local friction is acceptable." \
49
+ --append-notes "## Validity check
50
+
51
+ - Evidence we already have: two accidental token commits in the last six months.
52
+ - Riskiest assumption: that a hook survives the team's current tooling.
53
+ - What would invalidate this idea: a secret scanner already covering this path.
54
+
55
+ ## Next validation step
56
+
57
+ Check whether the existing pre-commit config already runs a scanner." \
58
+ -p 3
59
+ ```
60
+
61
+ Round 2 corrects the design in place and appends only what changed:
62
+
63
+ ```bash
64
+ bd update proj-idea1 \
65
+ --design "## How we might do it
66
+
67
+ CI gate (chosen): pre-commit config already runs an unrelated linter and the hook is bypassed
68
+ with --no-verify, which the two incidents both used." \
69
+ --append-notes "## Next validation step
70
+
71
+ Prototype the gate on one repository and confirm it fails on a seeded fake token."
72
+ ```
73
+
74
+ ## Promotion transcript
75
+
76
+ Promotion is two moves: flip the idea bead into the epic node, then create execution children
77
+ that point at it. The epic stays `execution:hitl` — a human owns the outcome even when every
78
+ child is agent-routable.
79
+
80
+ ```bash
81
+ # 1. The idea bead becomes the epic node.
82
+ bd update proj-idea1 --add-label kind:epic --remove-label kind:idea -t epic
83
+
84
+ # 2. Execution children hang off it by ownership.
85
+ bd create "Add the token scanner to CI" --parent proj-idea1 \
86
+ -l execution:afk --no-inherit-labels -t task \
87
+ -d "Wire the scanner into the pipeline.
88
+
89
+ ## Acceptance Criteria
90
+ - [ ] A seeded fake token fails the build." --validate
91
+
92
+ # 3. Ordering is a dependency, not a label.
93
+ bd create "Document the scanner baseline" --parent proj-idea1 \
94
+ -l execution:afk --no-inherit-labels -t task \
95
+ -d "Record the current findings so new alerts are attributable.
96
+
97
+ ## Acceptance Criteria
98
+ - [ ] Baseline written and linked from the epic." --validate
99
+ bd dep add proj-idea1.2 proj-idea1.1 # the doc waits for the scanner to land
100
+ ```
101
+
102
+ - `--no-inherit-labels` is required on every child: without it a child inherits `kind:epic` and
103
+ stops reading as ordinary executable work.
104
+ - `bd update <id> --remove-label` and `--add-label` are the label verbs; `bd label add/remove`
105
+ works too, and `bd tag <id> <label>` is the single-add shorthand.
106
+ - A promoted epic satisfies lint through `--acceptance` (or a `## Success Criteria` section); if
107
+ the idea never got one, add it at promotion time.
108
+ - `bd close` refuses to close a bead with open children, so the epic closes after its last child
109
+ — that ordering is the built-in completion rule, not a convention to remember.
110
+
111
+ ## When a planning bead belongs in the hierarchy
112
+
113
+ If the children cannot be written down yet because the design is still unsettled, create one
114
+ planning bead as a child of the epic (`execution:hitl`) and make every implementation child depend
115
+ on it. The implementation children then surface as ready exactly when planning closes — no extra
116
+ readiness label. Use `create-task` when the children also need pipeline stage chores.
@@ -0,0 +1,146 @@
1
+ ---
2
+ name: flesh-out-idea
3
+ description: Deepen an idea bead through an interview, then update its fields or promote it to an epic with task children. Use when the user asks "flesh out an idea", "which ideas are ready", or "promote this idea".
4
+ ---
5
+
6
+ # Flesh Out Idea
7
+
8
+ Take an idea recorded as a `kind:idea` bead and deepen it until it is either ready to promote or
9
+ explicitly still waiting on something. The bead is the record throughout: deepening rewrites its
10
+ fields, promotion changes its labels and type in place.
11
+
12
+ ## When to use
13
+
14
+ - The user wants to work on the idea backlog ("flesh out an idea", "which ideas are ready?").
15
+ - An idea bead has stalled — its sections are thin, or its validity check has open questions.
16
+ - An idea looks ready to become an epic and needs the promotion step.
17
+
18
+ ## When NOT to use
19
+
20
+ - The idea is not yet recorded — run `record-idea` first; deepening an unrecorded idea loses it.
21
+ - The idea is already an epic or a task bead — update it directly, or run `create-task` for
22
+ pipeline expansion.
23
+ - The work is already understood and needs a requirements document — run `write-a-prd`.
24
+
25
+ ## Workflow
26
+
27
+ 1. **List candidates.** Query the blocker-aware ready view scoped to ideas:
28
+
29
+ ```bash
30
+ bd ready -l kind:idea
31
+ ```
32
+
33
+ `bd ready` respects dependencies, so an idea that `depends-on` in-flight work does not appear
34
+ until that work closes. Use `bd list -l kind:idea` when you need every idea including blocked
35
+ and deferred ones. If the user named a bead, skip straight to step 2.
36
+
37
+ 2. **Read the current record.** `bd show <id> --json` — note which `##` markers already carry
38
+ content and which are empty. Deepening fills gaps and challenges weak sections; it does not
39
+ restart the capture interview from scratch.
40
+
41
+ 3. **Interview at depth, one question at a time.** Push past the capture-level answer:
42
+ - **Why** — what problem, and what evidence says it is real? What breaks if it is never done?
43
+ - **Who** — who benefits, and how would they notice the improvement?
44
+ - **How** — what shape would the implementation take, what alternatives were considered, and
45
+ which tradeoffs decide between them?
46
+ - **When** — what has to be true or landed first? Which dependencies gate it?
47
+ - **Priority** — where does it now sit relative to current work (P0–P4)?
48
+
49
+ Sharpen the validity check while you go: the riskiest assumption, the signal that would
50
+ invalidate the idea, and the cheapest next step that would firm it up.
51
+
52
+ 4. **Write the answers back into the bead.** Preserve the `##` markers — they are how the next
53
+ round finds each section. Append notes rather than replacing them so interview rounds
54
+ accumulate, and correct description or design in place when an answer supersedes what is there:
55
+
56
+ ```bash
57
+ bd update <id> --design "<## How we might do it …>" \
58
+ --append-notes "<## Validity check …>" \
59
+ -p <P0-P4>
60
+ ```
61
+
62
+ Use `-d/--description` to rewrite the problem, beneficiaries, or outcome, and `--acceptance` to
63
+ restate the promotion criteria once the interview settles what "ready" means.
64
+
65
+ 5. **Decide readiness against the acceptance criteria.** Read `--acceptance` and check it against
66
+ what the interview established:
67
+ - **Met** → go to step 6, or stop if the user only wanted deepening.
68
+ - **Not met** → stop here. Record the blocking question and the next validation step in
69
+ `## Next validation step`, and leave the bead open. An idea promoted before its bar is met
70
+ produces children nobody can execute.
71
+
72
+ 6. **Promote (optional, user-confirmed).** Turn the idea bead into the epic node and hang
73
+ execution children off it:
74
+
75
+ ```bash
76
+ # the idea becomes the epic; it stays execution:hitl — a human owns the epic
77
+ bd update <id> --add-label kind:epic --remove-label kind:idea -t epic
78
+
79
+ # each executable child is agent-routable and inherits nothing from the epic
80
+ bd create "<child title>" --parent <id> -l execution:afk --no-inherit-labels -t task \
81
+ -d "<child description>" --validate
82
+ ```
83
+
84
+ `--parent` expresses ownership; `bd dep add <child> <blocker>` expresses ordering. Where a
85
+ feature needs planning before implementation, create a planning bead and make the
86
+ implementation children depend on it — the dependency, not a label, is the readiness gate. Run
87
+ `create-task` instead when the children need pipeline stage chores.
88
+
89
+ 7. **Report back.** Return the bead ID, what changed (sections rewritten, priority moved,
90
+ children created), and either the promotion result or the specific reason it is not ready.
91
+
92
+ ## Red Flags
93
+
94
+ - Promoting on enthusiasm while the acceptance criteria are still unmet — the children inherit a
95
+ decision nobody made.
96
+ - Replacing notes instead of appending — the interview trail is the provenance the next round reads.
97
+ - Dropping the `##` markers while writing a field — the next flesh-out pass cannot find the section.
98
+ - Restarting the capture interview instead of challenging the existing record.
99
+ - Rewriting the idea as a markdown file — the bead is the record at every stage.
100
+
101
+ ## Common Rationalizations
102
+
103
+ | Rationalization | Rebuttal |
104
+ |---|---|
105
+ | "The idea is obviously good, skip to promotion" | Promotion is the moment the idea spends other work's time; the acceptance criteria are the cheapest gate it will ever have. |
106
+ | "I'll remember the interview detail" | Only what lands in a field survives the session. Append it. |
107
+ | "The description is close enough, I'll just add a note" | Superseded description text misleads the next reader; correct it in place and keep the note for provenance. |
108
+ | "Adding children now saves a round trip" | Children created before the bar is met are the round trip — they get rewritten or closed. |
109
+
110
+ ## Philosophy / rationale
111
+
112
+ - **An idea earns its children.** Promotion is cheap and reversal is not, so the interview
113
+ pressure-tests the idea until its own acceptance criteria say it can be executed. Everything
114
+ before that is one bead getting better.
115
+ - **Two axes, one hierarchy.** Ownership is `--parent`; ordering is a dependency. Keeping them
116
+ separate means the readiness view answers "what can be worked now?" without a second label
117
+ scheme.
118
+
119
+ ## See Also
120
+
121
+ - [record-idea](../record-idea/SKILL.md) — load to capture a new idea instead of deepening an existing one.
122
+ - [create-task](../create-task/SKILL.md) — load when a promoted epic needs pipeline-stage chores.
123
+ - [write-a-prd](../write-a-prd/SKILL.md) — load when the deepened idea is ready for requirements capture.
124
+ - [bd-tool](../../productivity/bd-tool/SKILL.md) — load for label vocabulary and queries beyond the commands used here.
125
+
126
+ ## Examples
127
+
128
+ Input: "which ideas are ready?" → `bd ready -l kind:idea` lists three; the user picks one whose
129
+ acceptance criteria name a prototype result.
130
+
131
+ Output: the interview settles the mechanism and the two tradeoffs that decide it; `--design` and
132
+ `--notes` are updated with the markers preserved, priority moves from P4 to P2, and the bead is
133
+ promoted (`kind:epic`, `-t epic`) with two `execution:afk` children created via `--parent`. See
134
+ `REFERENCE.md` for the full worked promotion.
135
+
136
+ ## Verification checklist
137
+
138
+ - [ ] The candidate list came from `bd ready -l kind:idea` (or the user named the bead).
139
+ - [ ] The existing record was read before the interview started (`bd show <id> --json`).
140
+ - [ ] Every `##` marker present before the update is still present after it.
141
+ - [ ] Notes were appended, not replaced; superseded description or design text was corrected.
142
+ - [ ] Priority reflects the interview (`bd show <id>` confirms it).
143
+ - [ ] On promotion: label is `kind:epic`, type is `epic`, and `kind:idea` is gone.
144
+ - [ ] On promotion: every child carries `execution:afk` and no inherited epic label.
145
+ - [ ] On no promotion: `## Next validation step` records what would unblock it.
146
+ - [ ] Report returned the bead ID, the changes, and the promotion outcome or blocker.
@@ -56,11 +56,60 @@ This vertical slice: end-to-end behaviour, not layer-by-layer implementation.
56
56
  - Blocked by #<task-id> (if any) — or "None — can start immediately"
57
57
  ```
58
58
 
59
- ## Aggregate classification tags
59
+ ## Feature → planning → impl sequence
60
60
 
61
- After all tasks in an epic exist, tag the epic with the aggregate classification:
61
+ When a slice is several deliverables, it gets a planning bead in front of them. Ownership is
62
+ `--parent` at create time; ordering is `bd dep add`:
62
63
 
63
64
  ```bash
64
- bd tag <epic-id> implementation-type:hitl # if any task is HITL
65
- bd tag <epic-id> implementation-type:afk # if all tasks are AFK
66
- ```
65
+ # The slice, as a container.
66
+ bd create "<Slice Title>" --type feature -l execution:hitl --description "<slice body>" --validate
67
+
68
+ # The planning bead: human-owned, owned by the feature, blocking every impl child.
69
+ bd create "Plan: <Slice Title>" --type task -l execution:hitl --parent <feature-id> \
70
+ --no-inherit-labels --description "<planning body>" --validate
71
+
72
+ # One impl child per deliverable. Owned by the feature (not by the planning bead),
73
+ # labelled for the work it does.
74
+ bd create "<Deliverable title>" --type task -l execution:afk --parent <feature-id> \
75
+ --no-inherit-labels --description "<task body above>" --validate
76
+
77
+ # Readiness gate: impl stays out of `bd ready` until the planning bead closes.
78
+ bd dep add <impl-task-id> <planning-bead-id>
79
+ ```
80
+
81
+ `--no-inherit-labels` is required on both children: `bd` copies a parent's labels at create
82
+ time, so a child of a `execution:hitl` feature would silently acquire `execution:hitl`.
83
+
84
+ ### Planning bead body template
85
+
86
+ Cold-start ready — another person picks it up with no chat history:
87
+
88
+ ```markdown
89
+ ## What and why
90
+
91
+ The deliverable this feature produces and the problem it solves.
92
+
93
+ ## Decisions already made
94
+
95
+ - Decision — rationale
96
+
97
+ ## Open questions / risks
98
+
99
+ - Question — who answers it
100
+
101
+ ## References
102
+
103
+ - Bead IDs, files, docs consulted
104
+
105
+ ## Acceptance Criteria
106
+
107
+ - [ ] The user confirms planning is sufficient for this feature.
108
+ ```
109
+
110
+ ## No aggregate classification
111
+
112
+ Do not tag a container with its children's execution class. A human owns an epic or feature, so
113
+ it is `execution:hitl`; each impl task states `execution:afk` or `execution:hitl` for its own
114
+ work. Aggregating upward labels a human-owned container as agent work and gives a single bead two
115
+ answers to "who does this?".