@jaybeeuu/agent-cortex 2.1.0 → 2.2.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 (178) hide show
  1. package/CHANGELOG.md +387 -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/hooks/claude/scripts/notify.mjs +8 -1
  18. package/lib/cli.mjs +91 -2
  19. package/package.json +27 -3
  20. package/scripts/check-changeset.mjs +4 -0
  21. package/scripts/check-no-sync.mjs +5 -1
  22. package/scripts/lib/compose-agent.mjs +69 -9
  23. package/scripts/lib/fs.mjs +10 -2
  24. package/scripts/lib/migrate.mjs +736 -0
  25. package/scripts/lib/release-gates.mjs +21 -1
  26. package/scripts/lib/skill-frontmatter.mjs +23 -6
  27. package/scripts/lib/skill-links.mjs +52 -0
  28. package/scripts/lib/verify-worker-tree.mjs +25 -0
  29. package/scripts/resolve-publish-command.mjs +4 -0
  30. package/skills/engineering/design-an-interface/SKILL.md +3 -3
  31. package/skills/engineering/grill-with-docs/SKILL.md +3 -5
  32. package/skills/engineering/improve-codebase-architecture/SKILL.md +5 -4
  33. package/skills/engineering/tdd/SKILL.md +5 -7
  34. package/skills/engineering/technical-direction/SKILL.md +5 -5
  35. package/skills/planning/classify-bead/REFERENCE.md +3 -3
  36. package/skills/planning/classify-bead/SKILL.md +14 -9
  37. package/skills/planning/classify-bead/scripts/classify-bead.mjs +5 -4
  38. package/skills/planning/create-task/REFERENCE.md +52 -3
  39. package/skills/planning/create-task/SKILL.md +70 -26
  40. package/skills/planning/create-task/scripts/{create-chores.ts → create-chores.mjs} +48 -23
  41. package/skills/planning/flesh-out-idea/REFERENCE.md +116 -0
  42. package/skills/planning/flesh-out-idea/SKILL.md +146 -0
  43. package/skills/planning/prd-to-tasks/REFERENCE.md +54 -5
  44. package/skills/planning/prd-to-tasks/SKILL.md +22 -16
  45. package/skills/planning/record-idea/FORMAT.md +66 -17
  46. package/skills/planning/record-idea/SKILL.md +48 -24
  47. package/skills/planning/request-refactor-plan/SKILL.md +4 -4
  48. package/skills/planning/spec-to-tickets/SKILL.md +5 -5
  49. package/skills/planning/write-a-prd/SKILL.md +8 -9
  50. package/skills/planning/write-a-ticket/SKILL.md +4 -6
  51. package/skills/productivity/bd-tool/SKILL.md +15 -10
  52. package/skills/productivity/grill-me/SKILL.md +5 -0
  53. package/skills/productivity/init-beads/SKILL.md +3 -3
  54. package/skills/productivity/migration/REFERENCE.md +227 -0
  55. package/skills/productivity/migration/SKILL.md +188 -0
  56. package/skills/productivity/validate-agent-dir/scripts/{validate-agent-dir.ts → validate-agent-dir.mjs} +49 -28
  57. package/skills/productivity/write-a-skill/SKILL.md +5 -5
  58. package/skills/review/maintain-agent-docs/SKILL.md +5 -7
  59. package/skills/review/refactor-skill/SKILL.md +4 -3
  60. package/skills/review/review-security/SKILL.md +3 -5
  61. package/skills/style/style-code/SKILL.md +5 -10
  62. package/skills/style/style-comms/SKILL.md +5 -7
  63. package/skills/style/style-documentation/SKILL.md +5 -6
  64. package/skills/style/style-tests/SKILL.md +5 -7
  65. package/skills/workflow/git-workflow/SKILL.md +28 -4
  66. package/skills/workflow/hitl-collab/SKILL.md +4 -6
  67. package/skills/workflow/plan/SKILL.md +41 -30
  68. package/skills/workflow/ralph/REFERENCE.md +182 -51
  69. package/skills/workflow/ralph/SKILL.md +89 -50
  70. package/skills/workflow/run-pipeline-stage/SKILL.md +72 -71
  71. package/skills/workflow/run-pipeline-stage/playbooks/code.md +11 -0
  72. package/skills/workflow/run-pipeline-stage/playbooks/document.md +12 -0
  73. package/skills/workflow/run-pipeline-stage/playbooks/fix.md +12 -0
  74. package/skills/workflow/run-pipeline-stage/playbooks/review.md +11 -0
  75. package/skills/workflow/run-pipeline-stage/playbooks/verify.md +13 -0
  76. package/skills/workflow/run-pipeline-stage/prompts/stage-runner.md +73 -1
  77. package/token-map.README.md +9 -4
  78. package/token-map.json +13 -6
  79. package/.agents/skills/style-versioning/SKILL.md +0 -172
  80. package/.changeset/README.md +0 -8
  81. package/.changeset/config.json +0 -11
  82. package/.github/workflows/ci.yml +0 -302
  83. package/.junie/guidelines.md +0 -87
  84. package/.junie/mcp/mcp.json +0 -10
  85. package/AGENTS.md +0 -153
  86. package/agents/ralph/claude/polling.md +0 -31
  87. package/agents-native/ralph.md +0 -203
  88. package/docs/claude-hooks.md +0 -144
  89. package/docs/commit-signing.md +0 -231
  90. package/docs/ideas/auto-model-selection.md +0 -75
  91. package/docs/ideas/ban-content-assertion-tests.md +0 -75
  92. package/docs/ideas/bead-progress-notes-for-session-resumption.md +0 -75
  93. package/docs/ideas/classify-beads-via-deterministic-script-with-agent-fallback.md +0 -70
  94. package/docs/ideas/ctx-alias-version-and-update-commands.md +0 -65
  95. package/docs/ideas/ctx-feedback-command-for-capturing-ideas-from-any-machine.md +0 -67
  96. package/docs/ideas/dedicated-review-tests-skill.md +0 -71
  97. package/docs/ideas/deployment-beads-for-post-merge-pipelines.md +0 -36
  98. package/docs/ideas/design-and-delivery-as-separate-bead-trees/design-and-delivery-as-separate-bead-trees.md +0 -99
  99. package/docs/ideas/enable-signed-commit-enforcement-changesets-bot-commits-must-be-signed.md +0 -42
  100. package/docs/ideas/extension-manifests.md +0 -121
  101. package/docs/ideas/improve-pi-system-prompt.md +0 -43
  102. package/docs/ideas/map-every-cortex-tool-to-a-real-pi-equivalent.md +0 -95
  103. package/docs/ideas/model-selector.md +0 -40
  104. package/docs/ideas/pi-task-memory.md +0 -34
  105. package/docs/ideas/qa-extension.md +0 -43
  106. package/docs/ideas/record-idea-implementation-questions.md +0 -68
  107. package/docs/ideas/record-ideas-as-beads.md +0 -115
  108. package/docs/ideas/self-flushing-session.md +0 -72
  109. package/docs/ideas/state-in-beads-not-md.md +0 -69
  110. package/docs/ideas/subagent-visibility.md +0 -72
  111. package/docs/ideas/task-session-context.local.md +0 -95
  112. package/docs/ideas/task-session-context.md +0 -89
  113. package/docs/ideas/test-data-creation-helpers.md +0 -92
  114. package/docs/ideas/test-planning-stage-bead-in-feature-planning.md +0 -68
  115. package/docs/ideas/unified-ci-pipeline.md +0 -28
  116. package/docs/ideas/unify-the-ticket-and-task-decomposition-workflows.md +0 -71
  117. package/docs/ideas/worktree-housekeeping-for-closed-beads.md +0 -39
  118. package/docs/inspirations.md +0 -33
  119. package/docs/research/disable-model-invocation.md +0 -82
  120. package/docs/research/gas-city-research.md +0 -256
  121. package/docs/research/skill-design-research.md +0 -286
  122. package/docs/research/skill-improvements-analysis.md +0 -117
  123. package/docs/research/skill-patterns-research.md +0 -24
  124. package/docs/skills/skill-anatomy.md +0 -200
  125. package/docs/technical-direction/harness-config.md +0 -177
  126. package/docs/technical-direction/migration-execution-labels.md +0 -177
  127. package/docs/user-preferences.md +0 -17
  128. package/extensions/agent-guardrails/tsconfig.json +0 -12
  129. package/extensions/agent-modes/tsconfig.json +0 -12
  130. package/extensions/output-style/tsconfig.json +0 -12
  131. package/extensions/session-start/tsconfig.json +0 -12
  132. package/extensions/skill-stats/pnpm-lock.yaml +0 -329
  133. package/extensions/skill-stats/tsconfig.json +0 -12
  134. package/extensions/subagent/agents/planner.md +0 -37
  135. package/extensions/subagent/agents/reviewer.md +0 -35
  136. package/extensions/subagent/agents/scout.md +0 -50
  137. package/extensions/subagent/agents/worker.md +0 -24
  138. package/extensions/subagent/prompts/implement-and-review.md +0 -10
  139. package/extensions/subagent/prompts/implement.md +0 -10
  140. package/extensions/subagent/prompts/scout-and-plan.md +0 -9
  141. package/extensions/subagent/tsconfig.json +0 -12
  142. package/pi/keybindings.json +0 -3
  143. package/pi/settings.json +0 -34
  144. package/pnpm-workspace.yaml +0 -14
  145. package/skills/planning/create-task/scripts/package.json +0 -14
  146. package/skills/planning/create-task/scripts/pnpm-lock.yaml +0 -342
  147. package/skills/planning/create-task/scripts/tsconfig.json +0 -12
  148. package/skills/planning/record-idea/scripts/new-idea.sh +0 -89
  149. package/skills/productivity/validate-agent-dir/scripts/package.json +0 -15
  150. package/skills/productivity/validate-agent-dir/scripts/pnpm-lock.yaml +0 -329
  151. package/skills/productivity/validate-agent-dir/scripts/pnpm-workspace.yaml +0 -2
  152. package/skills/productivity/validate-agent-dir/scripts/tsconfig.json +0 -19
  153. package/skills/productivity/validate-agent-dir/scripts/validate-agent-dir.test.ts +0 -317
  154. package/skills/workflow/run-pipeline-stage/REFERENCE.md +0 -22
  155. package/skills/workflow/run-pipeline-stage/scripts/generate-progress.test.ts +0 -682
  156. package/skills/workflow/run-pipeline-stage/scripts/generate-progress.ts +0 -588
  157. package/skills/workflow/run-pipeline-stage/scripts/package.json +0 -15
  158. package/skills/workflow/run-pipeline-stage/scripts/pnpm-lock.yaml +0 -342
  159. package/skills/workflow/run-pipeline-stage/scripts/pnpm-workspace.yaml +0 -2
  160. package/skills/workflow/run-pipeline-stage/scripts/tsconfig.json +0 -12
  161. package/test/classify-bead.test.mjs +0 -277
  162. package/test/claude-installer.test.mjs +0 -308
  163. package/test/cli.test.mjs +0 -314
  164. package/test/create-chores.test.mjs +0 -85
  165. package/test/fake-bd.test.mjs +0 -72
  166. package/test/fs.test.mjs +0 -76
  167. package/test/helpers/fake-bd.mjs +0 -87
  168. package/test/helpers/fake-claude.mjs +0 -152
  169. package/test/helpers/fake-pi.mjs +0 -132
  170. package/test/installer.test.mjs +0 -806
  171. package/test/notify-hook.test.mjs +0 -63
  172. package/test/pending-gates.test.mjs +0 -147
  173. package/test/pi-installer.test.mjs +0 -785
  174. package/test/pi-register.test.mjs +0 -342
  175. package/test/pi-sweep.test.mjs +0 -619
  176. package/test/release-gates.test.mjs +0 -190
  177. package/test/skill-frontmatter.test.mjs +0 -137
  178. package/test/verify-worker-tree.test.mjs +0 -120
@@ -4,8 +4,141 @@ Detailed procedures for the ralph orchestration workflow. See [SKILL.md](./SKILL
4
4
 
5
5
  ---
6
6
 
7
+ ## The in-flight invariant
8
+
9
+ Every ralph control-flow predicate — *is any agent work in flight?*, *is there work?*, *is there
10
+ room to dispatch?*, *may we pause?*, *may we shut down?* — is answered from `state.json`'s
11
+ `inflight` list (entries carry `kind: "stage"`, `kind: "decompose"` or `kind: "expand"`) plus
12
+ `bd ready -l execution:afk`. **Never** from a chore-type `bd` query, and never from "was a chore
13
+ dispatched?".
14
+
15
+ | Question | Derive it from | Never from |
16
+ |----------|----------------|------------|
17
+ | Is any agent work in flight? | `inflight` in `.agent-cortex/ralph/state.json` — stage, decomposition **and** expansion entries | `bd list -t chore`, `bd ready -t chore`, or any "were chores dispatched?" test |
18
+ | Is anything dispatchable? | `bd ready -l execution:afk`: a `stage:*` chore, a childless `execution:afk` `feature` bead to decompose, **or** a ready, claimable chore-less `execution:afk` task bead awaiting expansion | A chore listing alone — a ready, claimable childless feature or chore-less task is work waiting, not idle |
19
+ | Is there room under the 5-feature cap? | Parent count in `inflight` | A count of chore beads |
20
+ | May ralph pause or shut down? | `inflight` empty **and** nothing dispatchable (per the row above) | "No stage worker is running" |
21
+
22
+ **`execution:afk` is the one dispatch predicate.** It answers *whose work is this* for features,
23
+ tasks and chores alike, and the bead graph answers *when*. Ralph therefore never narrows the query
24
+ — "chores with `stage:*`" would report a ready childless feature or an unexpanded task as idle
25
+ while both are work waiting for a worker.
26
+
27
+ **Dispatchable means ready *and* claimable.** `bd ready -l execution:afk` decides ready; pending human action
28
+ decides claimable: while `pending-gates.mjs` reports an unblocked `lifecycle:feature-pr` gate, ralph
29
+ schedules no new parent features (_Feature PR gate_, step 6), so a queued unexpanded `execution:afk` bead in
30
+ that state is paused work, not dispatchable work. Scoping the predicate both ways is what makes HITL Pause
31
+ reachable in the canonical post-PR state — gate open, unexpanded `execution:afk` beads queued, `inflight`
32
+ empty, no ready `stage:*` chore — instead of re-arming a PI
33
+ wait over an empty agent set forever on an idle poll.
34
+
35
+ **Why:** an expansion or decomposition worker claims no chore. A chore-only predicate therefore
36
+ reports "nothing in flight" while an agent is running, which makes ralph pause or shut down
37
+ mid-expansion and leaves the parent's freshly created `stage:*` chain undispatched. The only
38
+ legitimate chore-type control-flow predicate in ralph is the retry counter in _Cap Backstop_
39
+ (`stage:fix` children): it counts remediation history rather than in-flight work, so it may gate a
40
+ dispatch decision but it must never answer *is anything in flight?*. Every other chore-type `bd`
41
+ query used as a control-flow predicate is a bug. Structural checks that ask nothing more than
42
+ *what does this bead already have?* — the _Expansion Guard_'s `grep -c '"stage:'`, the _Cap
43
+ Backstop_'s `stage:fix` count, the _Feature Decomposition_'s child count — are not predicates and
44
+ are fine.
45
+
46
+ ---
47
+
48
+ ## Expansion Guard
49
+
50
+ Stage chores are pre-created, never created on demand. `create-chores.mjs` (in `skills/planning/create-task/`) reads `pipeline.json` and creates the whole chain in one shot — `code` → `verify` → `review` → `document`, plus the `featurePrReview` HITL gate — with `blocks` deps that encode the order, and with the parent's priority and inherited labels. Ralph's dispatch is therefore always "claim what `bd ready -l execution:afk` returns".
51
+
52
+ A ready `execution:afk` task bead with **no** `stage:*` chore children has nothing to dispatch. Expand it, then dispatch the resulting `stage:code` chore:
53
+
54
+ 1. **Confirm it is chore-less** — a bead that already has stage chores is never expanded again:
55
+ ```bash
56
+ bd children <parent-id> --json | grep -c '"stage:'
57
+ ```
58
+ Expect `0` printed. `grep -c` exits `1` when it counts zero matches, so add `|| true` when the
59
+ check runs under `set -e` or inside an `&&` chain — the printed count is the answer, not the exit
60
+ status.
61
+ 2. **Dispatch an expansion worker** in the feature worktree (`.agent-cortex/worktrees/<parent-id>`) whose whole job is to run the pre-creator against the existing bead and report the JSON it printed:
62
+ ```bash
63
+ node <create-task-scripts>/create-chores.mjs \
64
+ --parent <parent-id> --priority <parent-priority>
65
+ ```
66
+ `<create-task-scripts>` is the absolute path to `skills/planning/create-task/scripts/`, resolved from wherever the skill was loaded — never hardcode one harness's install path. `<parent-priority>` is the parent's own priority from `bd show <parent-id>`, so chores match the task they belong to.
67
+ 3. **Record it in `inflight`** so its completion is attributable to the parent and it stays in the wait set — it has no chore, so `choreId` is `null`:
68
+ ```json
69
+ { "kind": "expand", "choreId": null, "parentId": "<parent-id>", "title": "<parent title>", "agentId": "<agent-id>", "logLine": 1 }
70
+ ```
71
+ 4. **Report the mapping** the worker returns — `code`, `verify`, `review`, `document`, `featurePrReview` — and close nothing. The worker owns no bead on this run; the expansion is bookkeeping, not a stage.
72
+ 5. **Dispatch normally.** The next `bd ready -l execution:afk` pass picks up the `stage:code` chore, and the pre-created chain carries the rest.
73
+ 6. **Handle the completion as an expansion completion**, not a stage completion — see below.
74
+
75
+ **Never expand an existing bead with `create-task`** — or with any other command that creates a bead. `create-task` creates a bead first and expands second, so running it for an existing bead leaves a **second parent** beside the original, which stays chore-less and never gets dispatched. The guard exists so an `execution:afk` task bead always ends with exactly one parent: `create-chores.mjs` expands a bead that already exists; only `create-task` creates parents.
76
+
77
+ **Labels on the chain.** Stage chores inherit `execution:afk` from their parent task bead, so they surface in ralph's `bd ready -l execution:afk` query without extra tagging — an expanded task never needs its chores relabelled. The `featurePrReview` HITL gate is the one exception: it declares its own `execution:hitl` + `lifecycle:feature-pr` labels and the script passes `--no-inherit-labels` for it, so it never picks up the parent's `execution:afk`.
78
+
79
+ ### Expansion Completion Contract
80
+
81
+ An expansion worker is dispatched like a stage worker but is **not** one. Nothing downstream of a stage dispatch applies to it:
82
+
83
+ | Stage worker | Expansion worker |
84
+ |------|------|
85
+ | Correlates to a claimed chore: `kind: "stage"` with a `choreId` | Holds no chore: `kind: "expand"`, `choreId: null` |
86
+ | Emits a `---REPORT---` block | Emits none — it prints the `create-chores.mjs` JSON mapping |
87
+ | Owns its leaf bead, which must read `closed` | Owns nothing — no bead to close, nothing to confirm |
88
+ | Completion advances the parent along the chain | Completion means "chores now exist" — dispatch the ready `stage:code` chore |
89
+
90
+ On completion, remove the entry from `inflight` and confirm the chore tree exists rather than taking the worker's word for it:
91
+
92
+ ```bash
93
+ bd children <parent-id> --json | grep -c '"stage:'
94
+ ```
95
+
96
+ Expect a non-zero count — one match per `stage:*` label in the chain. A printed `0` means the
97
+ expansion failed. Surface the worker's output in chat and record the parent for the shutdown summary — **never re-dispatch the expansion**, because `create-chores.mjs` is not idempotent and a second run duplicates the chain beside the first. Then continue at the normal dispatch pass: either way nothing is created and nothing is closed by ralph.
98
+
99
+ ---
100
+
101
+ ## Feature Decomposition
102
+
103
+ Epic Q2 makes ralph responsible for decomposing a feature bead into the hierarchy; Q5 makes a
104
+ feature `execution:hitl` by default. Both hold because the **label**, not the bead type, decides
105
+ routing: a feature is invisible to ralph while it carries `execution:hitl`, and a human exposes it
106
+ to ralph by relabelling it `execution:afk` when its delivery is genuinely agent-routable. Ralph
107
+ then decomposes it once and immediately goes idle behind the planning bead — Q5b's dependency gate
108
+ does the pausing, so no extra "ready to decompose" label is needed.
109
+
110
+ A ready `execution:afk` bead of type `feature` with **no** children is not dispatchable work.
111
+ Decompose it:
112
+
113
+ 1. **Confirm it is childless** — any existing child means the feature is already decomposed and this
114
+ procedure does not apply:
115
+ ```bash
116
+ bd children <feature-id> --json
117
+ ```
118
+ Expect an empty list `[]`. A non-empty list, however few children, means stop here.
119
+ 2. **Dispatch a decomposition worker** in the feature worktree (`.agent-cortex/worktrees/<feature-id>`) whose whole job is to run the `create-task` hierarchy flow (`prd-to-tasks` → `create-task`) for that one **existing** feature — its planning bead and impl children only, never a second feature bead — and report the IDs it created. The worker builds the Q5 shape:
120
+ - a **planning bead** — `--parent <feature-id>`, `execution:hitl` — held for a human to confirm planning is sufficient;
121
+ - **implementation task children** — `--parent <feature-id>`, `execution:afk`, `--no-inherit-labels` — each wired to wait on the planning bead with `bd dep add <impl-child> <planning-bead>`.
122
+
123
+ This is the shape `create-task` builds on its feature path (`SKILL.md` steps 5–6): an `execution:hitl` planning bead owned by the feature, whose impl children depend on it, so the dependency — not a label — is the readiness gate.
124
+ 3. **Record it in `inflight`** so its completion is attributable to the feature and it stays in the wait set — it holds no chore, so `choreId` is `null`:
125
+ ```json
126
+ { "kind": "decompose", "choreId": null, "parentId": "<feature-id>", "title": "<feature title>", "agentId": "<agent-id>", "logLine": 1 }
127
+ ```
128
+ 4. **Confirm the children exist** rather than trusting the report — the worker's IDs are a claim, the bead graph is the evidence:
129
+ ```bash
130
+ bd children <feature-id> --json
131
+ ```
132
+ Surface the created IDs in chat. An empty list means the decomposition failed: record the feature for the shutdown summary and continue — do not re-dispatch.
133
+ 5. **Never re-dispatch a decomposition.** The bead creation it runs is not idempotent, so a second run duplicates the planning bead and every implementation child beside the first. This is the same hazard as re-running `create-chores.mjs`.
134
+ 6. **Go idle.** After decomposition nothing is dispatchable for that feature: `bd ready -l execution:afk` still lists the feature itself (it now has children, so it is skipped — never decomposed again) but none of its children until a human closes the planning bead. Returning to the event loop with *nothing* to dispatch is the correct outcome, not a failure to re-expand — that is Q5b working as designed.
135
+
136
+ ---
137
+
7
138
  ## Dispatching a Chore Bead
8
139
 
140
+ Chores already exist, so dispatch never creates one:
141
+
9
142
  1. **Claim** the bead: `bd update <id> --claim`.
10
143
  2. **Read its `stage:*` label** from `bd show <id>`.
11
144
  3. **Load the universal stage runner prompt** from `skills/workflow/run-pipeline-stage/prompts/stage-runner.md`.
@@ -13,7 +146,7 @@ Detailed procedures for the ralph orchestration workflow. See [SKILL.md](./SKILL
13
146
  5. **Ensure branch + worktree exist for this parent task** (see _Feature branches and worktrees_ below), then note the worktree path — you'll pass it as `cwd` to {{TOOL:task}}.
14
147
  6. **Fill in the prompt** — replace placeholders with:
15
148
  - Stage from bead label (`stage:<stage>`) for `<stage>`
16
- - Chore bead ID and its `bd show` output for the bead specification. Do **not** inject `bd prime` output — the stage runner runs `bd prime` itself if it needs project context
149
+ - The leaf execution bead ID and its `bd show` output for the bead specification. Do **not** inject `bd prime` output — the stage runner runs `bd prime` itself if it needs project context
17
150
  - Parent task description from `bd show <parent-id>`
18
151
  - For `fix` stage: `FILES_CHANGED` from the preceding stage's report (the required changes come from the fix bead's own description — read via `bd show <fix-id>`)
19
152
  - For `verify`, `review`, `document` stages: `SUMMARY` and `FILES_CHANGED` from the preceding stage's report
@@ -55,6 +188,10 @@ For each parent task bead (`<parent-id>`):
55
188
  # <base> is epic/<epic-id> for multi-feature epics, origin/main for single-feature
56
189
  git worktree add .agent-cortex/worktrees/<parent-id> -b feature/<parent-id> <base>
57
190
  ```
191
+ **`<base>` is `epic/<epic-id>` or `origin/main` — never another `feature/*` branch.** If this
192
+ task depends on another unmerged task, its `blocks` edge already keeps it out of `bd ready`;
193
+ do not create the worktree early to get ahead, and never reuse a sibling task's worktree — that
194
+ silently stacks the branches and turns the dependency into a squash-merge conflict later.
58
195
  If `.agent-cortex/worktrees/<parent-id>` already exists, reuse it.
59
196
  5. All chores for this parent run in `.agent-cortex/worktrees/<parent-id>`. The `feature/<parent-id>` branch is the agent branch for HITL PRs.
60
197
 
@@ -64,7 +201,7 @@ For each parent task bead (`<parent-id>`):
64
201
 
65
202
  When the `document` chore for a parent task completes:
66
203
 
67
- 1. Close the `document` chore.
204
+ 1. Confirm the document worker closed its own chore (`bd show <id>` reads `closed`); do not close it yourself.
68
205
  2. Create or update a feature PR immediately from the agent branch to the feature branch (`feature/<parent-id>` into `epic/<epic-id>`; into `main` for single-feature epics):
69
206
  ```bash
70
207
  # <base> is epic/<epic-id> for multi-feature epics, main for single-feature
@@ -72,7 +209,7 @@ When the `document` chore for a parent task completes:
72
209
  ```
73
210
  If an open PR already exists, update it instead of creating a duplicate.
74
211
  3. Report the PR URL in chat as soon as it is created.
75
- 4. Find the child HITL task bead for this parent with label `lifecycle:feature-pr` (created by `create-task`).
212
+ 4. Find the child HITL task bead for this parent with label `lifecycle:feature-pr` and `execution:hitl` (created by `create-task`).
76
213
  5. Update that HITL bead with the PR URL/status (comment or note) so the reviewer has the link.
77
214
  6. Do not schedule new parent features while this gate is **unblocked** — an unblocked gate is a feature genuinely awaiting a human merge (see _Gate predicate_ below).
78
215
  7. Once the PR is merged, a human closes the HITL PR gate bead, which unblocks the scheduling brake. After that, close the parent feature bead:
@@ -101,40 +238,27 @@ Gate queries match the HITL axis on either `execution:hitl` (current) or `implem
101
238
  **Invariant — what may block a gate.** `parked` means "blocked by its own pipeline". A gate blocked by its parent **feature** bead is not parked in any harness: that bead stays open until after the merge, so the gate never reaches `bd ready`, never appears in `pendingHumanAction`, and a human merge is silently never requested. Keep the two shapes apart:
102
239
 
103
240
  - A `create-chores` gate unblocks exactly once, when its `document` chore closes. Until then it is parked and must not stop dispatch.
104
- - A gate must never carry a `blocks` dependency onto its own feature bead (the native-Claude shape: `bd create ... --labels ...lifecycle:feature-pr` then dep it to `<id>`). Remove it with `bd dep rm <gate> <id>` if present, so the gate is unblocked while its PR awaits merge.
241
+ - A gate must never carry a `blocks` dependency onto its own feature bead (e.g. `bd create ... --labels ...lifecycle:feature-pr` then dep it to `<id>`). Remove it with `bd dep rm <gate> <id>` if present, so the gate is unblocked while its PR awaits merge.
105
242
 
106
- So the predicate is sensitive to *what* blocks a gate, not only whether something does. `agents-native/ralph.md` (the Claude harness) keeps the open-gate form for this reason: its gates stay blocked by design, and its `document` chores never close; F10 (agnt-ctx-s5xd.10) unifies the two predicates.
243
+ So the predicate is sensitive to *what* blocks a gate, not only whether something does. It is ralph's only gate predicate on every harness: the Claude-native agent file that kept an open-gate form is retired, so nothing else restates a second predicate.
107
244
 
108
245
  ---
109
246
 
110
- ## Fix Loop
247
+ ## Cap Backstop (read-only)
111
248
 
112
- When a verify or review stage fails:
113
-
114
- 1. **Determine the parent task**: look up the chore bead's parent via `bd show <chore-id>` (follow the `parent-child` dependency).
115
- 2. **Count existing fix rounds**: list all chore beads that are children of the parent task with label `stage:fix`. The count of these (including closed ones) is the number of fix rounds already attempted.
116
- 3. **Read `maxFixRounds`** from `skills/planning/create-task/pipeline.json` (held in memory since initialization).
117
- 4. **If fix rounds ≥ maxFixRounds**: close the parent task bead as failed (`bd close <parent-id> --reason "Max fix rounds reached"`). Do not create another fix chore.
118
- 5. **Otherwise, create a fix chore** with the feedback in its description so the fixer agent can read it directly from `bd show`:
119
- ```bash
120
- fix_id=$(bd create "[<parent-id>] Fix (round <N>)" --type chore \
121
- --priority <same as parent> \
122
- --description "Requirements: see <parent-id> acceptance criteria (`bd show <parent-id>`).
249
+ Ralph never builds remediation. The worker that fails a stage creates its own `stage:fix` chore, a fresh instance of the failed stage blocked on that fix, and re-blocks the later stages behind the fresh bead (see the `run-pipeline-stage` skill, _Remediation Children_). Ralph only guards the cap, and only reads:
123
250
 
124
- <CHANGES_REQUESTED list or VERIFY_FAILURES list from the triggering REPORT>" -q)
125
- bd tag $fix_id stage:fix
126
- bd dep add $fix_id <parent-id> --type parent-child # fix-chore is child of parent
127
- ```
128
- 6. **Find the verify chore** for this parent task (the chore with label `stage:verify` and a `parent-child` dep to the parent).
129
- 7. **Block the verify chore** on the new fix chore:
251
+ 1. **Read `maxFixRounds`** from `skills/planning/create-task/pipeline.json` (held in memory since initialization).
252
+ 2. **Count existing fix rounds** for the parent — closed chores count:
130
253
  ```bash
131
- bd dep add <verify-id> $fix_id --type blocks # verify waits for fix
254
+ fix_rounds=$(bd children <parent-id> --json | grep -c '"stage:fix"')
132
255
  ```
133
- 8. **Reopen the verify chore**:
256
+ 3. **Before dispatching any `stage:*` chore of that parent**, if `fix_rounds >= maxFixRounds`: create nothing and block the parent, so a human sees it in the shutdown summary:
134
257
  ```bash
135
- bd reopen <verify-id>
258
+ bd update <parent-id> --status blocked \
259
+ --append-notes "[<ISO-timestamp>] max fix rounds reached (<fix_rounds>/<maxFixRounds>)"
136
260
  ```
137
- This ensures the fix chore runs first, then verify re-runs automatically when the fix closes.
261
+ 4. Ralph does **not** close the parent as failed and does **not** reopen or re-wire any chore — the worker already closed the failed leaf bead and the fresh stage bead is already blocked on its fix.
138
262
 
139
263
  ---
140
264
 
@@ -142,43 +266,43 @@ When a verify or review stage fails:
142
266
 
143
267
  Run whenever completion handling is triggered (an agent completion):
144
268
 
145
- 1. **Query in-flight beads**: `bd list --status=in_progress --type=chore`. Extract each bead's ID and title.
146
- 2. For each in-flight bead, read new lines from its **parent's** log file — logs are keyed by **parent** bead ID, so all stages of a feature share one file. Track the next unread line number per parent in memory, starting at 1:
269
+ 1. **Read in-flight entries**: `inflight` in `.agent-cortex/ralph/state.json` — every dispatched worker: stage (`kind: "stage"`), decomposition (`kind: "decompose"`) or expansion (`kind: "expand"`). Each entry carries `parentId` and `logLine`.
270
+ 2. For each in-flight entry, read new lines from its **parent's** log file — logs are keyed by **parent** bead ID, so all stages of a feature share one file:
147
271
  ```bash
148
- tail -n +<lastLine> .agent-cortex/ralph/ralph-<parent-id>.log 2>/dev/null
272
+ tail -n +<logLine> .agent-cortex/ralph/ralph-<parentId>.log 2>/dev/null
149
273
  ```
150
- 3. For each bead that has new lines:
274
+ 3. For each entry that has new lines:
151
275
  - **Post a chat summary** of new key events (stage transitions and notable events — not every line verbatim):
152
276
  ```
153
- 📋 [bead-id] <title>
277
+ 📋 [parent-id] <title>
154
278
  coding → verifying (or whatever transition)
155
279
  Tests: 12 passed, 0 failed
156
280
  ```
157
- - Update the in-memory line offset for that bead.
158
- 4. If no bead had new lines, post nothing — do not spam the chat with empty polls.
281
+ - Update `logLine` in `state.json` for that entry.
282
+ 4. If no entry had new lines, post nothing — do not spam the chat with empty polls.
159
283
 
160
284
  ---
161
285
 
162
286
  ## HITL Pause
163
287
 
164
- Proceed here when no chore beads are in-flight, no `stage:*` chore beads are ready, and `pending-gates.mjs` reports a non-empty `pendingHumanAction` — an **unblocked** `lifecycle:feature-pr` gate or an epic tagged `awaiting-epic-pr-merge` (see _Gate predicate_). Gates still parked behind their own pipeline do not count. Ralph stops rather than burning requests on idle polls.
288
+ Proceed here when no agent work is in flight (no stage, decomposition or expansion workers in `inflight`), nothing is dispatchable (`bd ready -l execution:afk` returns no `stage:*` chore, no childless feature to decompose, and no ready, claimable chore-less `execution:afk` task bead awaiting expansion), and `pending-gates.mjs` reports a non-empty `pendingHumanAction` — an **unblocked** `lifecycle:feature-pr` gate or an epic tagged `awaiting-epic-pr-merge` (see _Gate predicate_). Gates still parked behind their own pipeline do not count. Ralph stops rather than burning requests on idle polls.
165
289
 
166
- 1. Regenerate `.agent-cortex/ralph/progress.md` one final time — do not delete it.
167
- 2. For each **multi-feature** epic whose feature beads are all closed but not yet tagged `awaiting-epic-pr-merge`, open/update an epic PR to main (skip single-feature epics — their feature branch PRs already target `main`):
290
+ 1. For each **multi-feature** epic whose feature beads are all closed but not yet tagged `awaiting-epic-pr-merge`, open/update an epic PR to main (skip single-feature epics — their feature branch PRs already target `main`):
168
291
  ```bash
169
292
  gh pr create --base main --head epic/<epic-id> --title "[<epic-id>] Merge epic into main" --body "<epic summary>"
170
293
  ```
171
294
  Tag each epic bead with `awaiting-epic-pr-merge` until merged.
172
- 3. Run:
295
+ 2. Run:
173
296
  ```bash
174
297
  bd dolt push
175
298
  ```
176
- 4. Collect the table rows from `pendingHumanAction`:
299
+ **Gate on the exit status.** Non-zero: retry once, then stop and report the command, exit code and stderr as a sync blocker — no Pending Human Action table, and ralph does not claim a clean pause.
300
+ 3. Collect the table rows from the script's `pendingHumanAction` list:
177
301
  ```bash
178
302
  node skills/workflow/ralph/scripts/pending-gates.mjs
179
303
  ```
180
304
  For each entry, run `bd show <id>` to retrieve the PR URL from bead notes. `kind: "feature-pr"` rows read "review and merge the feature PR"; `kind: "epic-pr"` rows read "review and merge the epic PR into main".
181
- 5. Output the **Pending Human Action** summary:
305
+ 4. Output the **Pending Human Action** summary:
182
306
  ```
183
307
  ⏸️ Ralph is paused — human action required before work can continue.
184
308
 
@@ -190,25 +314,25 @@ Proceed here when no chore beads are in-flight, no `stage:*` chore beads are rea
190
314
 
191
315
  When you've completed the above, prompt me to continue.
192
316
  ```
193
- 6. **Stop completely.** Do not continue the event loop. Wait for the user to re-prompt before doing any further work.
317
+ 5. **Stop completely.** Stop the wake mechanism as the wake section describes. Do not continue the event loop. Wait for the user to re-prompt before doing any further work.
194
318
 
195
319
  ---
196
320
 
197
321
  ## Shutdown
198
322
 
199
- When `bd list --status=in_progress --type=chore` returns no results AND `bd ready` returns no chore beads with `stage:*` labels:
323
+ When nothing is in flight AND nothing is dispatchable — `inflight` holds no entries, `bd ready -l execution:afk` returns nothing (no `stage:*` chore, no childless feature to decompose, no ready, claimable chore-less task bead awaiting expansion) (_The in-flight invariant_ above):
200
324
 
201
- 1. Regenerate `.agent-cortex/ralph/progress.md` one final time — do not delete it.
202
- 2. For each **multi-feature** epic whose feature beads are all closed, open/update an epic PR to main (skip single-feature epics — no epic branch exists):
325
+ 1. For each **multi-feature** epic whose feature beads are all closed, open/update an epic PR to main (skip single-feature epics — no epic branch exists):
203
326
  ```bash
204
327
  gh pr create --base main --head epic/<epic-id> --title "[<epic-id>] Merge epic into main" --body "<epic summary>"
205
328
  ```
206
329
  Tag each epic bead with `awaiting-epic-pr-merge` until merged.
207
- 3. Run:
330
+ 2. Run:
208
331
  ```bash
209
332
  bd dolt push
210
333
  ```
211
- 4. If any HITL beads were noted during the session, output:
334
+ **Gate on the exit status.** Non-zero: retry once, then stop and report the command, exit code and stderr as a sync blocker — no completion summary, no "All beads complete.", and the remaining shutdown steps are not run.
335
+ 3. If any HITL beads were noted during the session, output:
212
336
  ```
213
337
  All agent work is complete. The following steps require human action before work can continue:
214
338
 
@@ -229,20 +353,27 @@ When `bd list --status=in_progress --type=chore` returns no results AND `bd read
229
353
 
230
354
  ## State Files
231
355
 
356
+ Status is read from beads — there is no rendered status document to build or refresh:
357
+
358
+ ```bash
359
+ bd list --parent <parent-id> # every chore for a feature, with its state
360
+ bd ready -l execution:afk # the next dispatchable work
361
+ bd show <id> # full detail, including the worker's notes
362
+ ```
363
+
232
364
  | File | Purpose |
233
365
  |------|---------|
234
- | `.agent-cortex/ralph/progress.md` | Human-readable snapshot. Regenerate: `workspace="/abs/path"; pnpm --prefix skills/workflow/run-pipeline-stage/scripts exec tsx generate-progress.ts --workspace "$workspace" > "$workspace/.agent-cortex/ralph/progress.md"`. `workspace` must be an **absolute** path — never `.` or `$(pwd)`. **Never hand-edit.** |
235
- | `.agent-cortex/ralph/state.json` | Runtime bookkeeping only: the in-flight agent-ID→bead mapping. Shape: `{ "inflight": [ { "choreId": "...", "parentId": "...", "title": "...", "agentId": "...", "logLine": 1 } ] }`. Initialise at startup with `{ "inflight": [] }`. Update after every dispatch and every agent completion. **Never hand-edit.** |
366
+ | `.agent-cortex/ralph/state.json` | Runtime bookkeeping only: the in-flight agent-ID→bead mapping. Shape: `{ "inflight": [ { "kind": "stage", "choreId": "...", "parentId": "...", "title": "...", "agentId": "...", "logLine": 1 } ] }`. A decomposition worker is recorded with `"kind": "decompose"` and an expansion worker with `"kind": "expand"`, both with `"choreId": null` — they hold no chore but still occupy the wait set and the in-flight check. Initialise at startup with `{ "inflight": [] }`. Update after every dispatch and every agent completion. **Never hand-edit.** |
236
367
  | `.agent-cortex/ralph/ralph-*.log` | Per-parent log files written by subagents — every stage chore of a feature appends to `.agent-cortex/ralph/ralph-<parent-id>.log` (e.g. `ralph-abc-123.log`). |
237
368
 
238
369
  All task state is derived from beads; `state.json` holds only runtime bookkeeping:
239
370
 
240
371
  | Question | How to answer |
241
372
  |----------|---------------|
242
- | What is in-flight? | `bd list --status=in_progress --type=chore` |
243
- | What is ready? | `bd ready` — filter for chores with `stage:*` labels |
373
+ | What is in-flight? | The `inflight` entries in `.agent-cortex/ralph/state.json` — `kind: "stage"` for a dispatched stage chore, `kind: "decompose"` for a feature-decomposition worker, `kind: "expand"` for an expansion worker. Decomposition and expansion workers hold no chore, so beads alone under-report in-flight work. |
374
+ | What is ready? | `bd ready -l execution:afk` — the single dispatch predicate. Each result is routed by its shape: a childless `feature` bead is decomposed (_Feature Decomposition_), a bead with no `stage:*` children is expanded (_Expansion Guard_), a `stage:*` chore is dispatched. |
244
375
  | What stage is a bead in? | Read the `stage:*` label from `bd show <id>` |
245
376
  | Which agent-ID maps to which bead? | `inflight` entries in `.agent-cortex/ralph/state.json` |
246
- | How many fix rounds? | Count chore beads with label `stage:fix` that are children of the parent task. Read `maxFixRounds` from `skills/planning/create-task/pipeline.json`. |
377
+ | How many fix rounds? | Count chore beads with label `stage:fix` that are children of the parent task (`bd children <parent-id> --json | grep -c '"stage:fix"'`). Read `maxFixRounds` from `skills/planning/create-task/pipeline.json`. Read-only: used for the cap backstop, never to build remediation. |
247
378
  | Which features are review-gated? | `pendingHumanAction` entries with `kind: "feature-pr"` from `pending-gates.mjs` — unblocked `lifecycle:feature-pr` gates on either HITL axis. A gate in `parked` is pre-created but not yet actionable |
248
379
  | Which epics are review-gated? | `bd list -l awaiting-epic-pr-merge` |
@@ -1,18 +1,22 @@
1
1
  ---
2
2
  name: ralph
3
- description: "Run all pending beads end-to-end with up to 5 concurrent pipeline-stage chores in dedicated worktrees, opening review-gated PRs immediately and pausing for human merges. Use when you want to \"run the backlog\", \"run all beads\", or \"run ralph\" with human approval gates."
3
+ description: "Run every ready execution:afk bead end-to-end — decomposing features, expanding tasks into pipeline-stage chores, and driving up to 5 concurrent workers in dedicated worktrees while opening review-gated PRs immediately and pausing for human merges. Use when you want to \"run the backlog\", \"run all beads\", or \"run ralph\" with human approval gates."
4
4
  ---
5
5
 
6
6
  # Ralph
7
7
 
8
- Ralph is a parallel orchestration loop. It advances AFK task beads through pipeline-stage chores (`code` → `verify` → `review` → `document`), dispatching each stage as a background subagent in the feature's worktree, then opens review-gated feature and epic PRs and pauses for human merges. Ralph never writes code itself — it dispatches, tracks, and reports.
8
+ Ralph is a parallel orchestration loop. It advances `execution:afk` beads through pipeline-stage chores (`code` → `verify` → `review` → `document`), dispatching each unit as a background subagent in its parent's worktree, then opens review-gated feature and epic PRs and pauses for human merges. Ralph never writes code itself — it dispatches, tracks, and reports.
9
9
 
10
- State model: task state lives in beads (ready/in_progress via `bd`); the only local file is `.agent-cortex/ralph/state.json`, holding the agent-ID→bead mapping. Pipeline configuration comes from `skills/planning/create-task/pipeline.json`, and stage execution belongs to the `run-pipeline-stage` skill.
10
+ One query decides what ralph works on: **`bd ready -l execution:afk`**. Features, tasks and chores all arrive through it, and each bead's *shape* — not a second `bd` filter — decides which procedure carries it: a childless feature is decomposed, a bead with no stage chores is expanded, a stage chore is dispatched. An `execution:afk` bead is therefore never invisible to ralph for lacking a `stage:*` label, and ralph never invents a narrower "only stage chores" predicate that would hide one.
11
+
12
+ Each leaf execution bead belongs to the worker that ran it: the worker appends its milestone notes, closes the bead on both outcomes, and builds its own `stage:fix` + fresh-stage remediation chain when it fails. Ralph reads beads and routes — it never closes a leaf bead and never creates a fix bead. Its only retry control is a read-only cap backstop.
13
+
14
+ State model: task state lives in beads (ready/in_progress via `bd`); the only local file is `.agent-cortex/ralph/state.json`, holding the agent-ID→bead mapping. Pipeline configuration comes from `skills/planning/create-task/pipeline.json`, and stage execution belongs to the `run-pipeline-stage` skill. Stage chores are pre-created from that pipeline when a task is expanded — with `blocks` deps encoding the order — so ralph's dispatch is always "claim what `bd ready -l execution:afk` returns"; it never creates a stage chore.
11
15
 
12
16
  ## When to use
13
17
 
14
18
  - "Run the backlog", "run all beads", "run ralph", "run everything pending".
15
- - A planning session has produced classified, unblocked AFK task beads and you want autonomous execution with human review gates.
19
+ - A planning session has produced classified, unblocked `execution:afk` beads and you want autonomous execution with human review gates.
16
20
  - You want the full pipeline (implement → verify → review → document) orchestrated concurrently, with fix loops on failure.
17
21
 
18
22
  ## When NOT to use
@@ -29,61 +33,85 @@ State model: task state lives in beads (ready/in_progress via `bd`); the only lo
29
33
  2. Ensure `.agent-cortex/` and `.agent-cortex/worktrees/` are in the project's `.gitignore` (append any that are missing).
30
34
  3. Create the workspace: `mkdir -p .agent-cortex/ralph`.
31
35
  4. Initialize state: write `.agent-cortex/ralph/state.json` with `{ "inflight": [] }`.
32
- 5. Read `skills/planning/create-task/pipeline.json` and hold it in memory — you need its `maxFixRounds` for the fix loop.
33
- 6. Run `bd ready` and classify each available bead:
34
- - **Chore with a `stage:*` label**: pipeline stage bead — eligible for dispatch.
35
- - **Task or other type without an `implementation-type:*` label**: unexpected here — classification happens at planning time via `create-task`. Do not invoke `classify-bead`; treat as needs-refinement and note it for the shutdown summary.
36
- - **Task labelled `execution:hitl`** (or the legacy `implementation-type:hitl`): skip — record the ID for the Pending Human Action summary at shutdown.
37
- 7. For each ready chore bead (up to 5), dispatch it from its parent's feature worktree (see _Dispatching a chore bead_ in REFERENCE.md — create branches/worktrees first).
38
- 8. Hand over to your harness's completion-detection mechanism: PI keeps a {{TOOL:wait_for_agents}} call outstanding over every in-flight agent ID. If no chore was dispatched and `pending-gates.mjs` reports a non-empty `pendingHumanAction` (an unblocked `lifecycle:feature-pr` gate, or an epic tagged `awaiting-epic-pr-merge`), go straight to HITL Pause (REFERENCE.md).
39
- 9. Regenerate `.agent-cortex/ralph/progress.md`:
40
- ```bash
41
- # workspace must be the absolute path you cd'd into — never . or $(pwd)
42
- workspace="/absolute/path/to/worktree"
43
- pnpm --prefix skills/workflow/run-pipeline-stage/scripts exec tsx generate-progress.ts --workspace "$workspace" > "$workspace/.agent-cortex/ralph/progress.md"
44
- ```
45
-
46
- ### 2. Event loop
36
+ 5. Read `skills/planning/create-task/pipeline.json` and hold it in memory — you need its `maxFixRounds` for the read-only cap backstop.
37
+ 6. Run **`bd ready -l execution:afk`**. That single query *is* the dispatch predicate — every ready `execution:afk` bead is ralph's work, whether it is a feature, a task or a chore. Classify each result by its shape to decide which procedure carries it:
38
+ - **`feature` bead with no children**: not dispatchable work yet — decompose it (_Feature decomposition_ below) and re-run the query.
39
+ - **Bead carrying a `stage:*` label**: a pipeline stage chore — dispatch it (_Event loop_, and _Dispatching a Chore Bead_ in REFERENCE.md).
40
+ - **`task` or other bead with no `stage:*` chore children**: expand it first (_Expansion guard_ below), then dispatch its ready `stage:code` chore.
41
+ - **Bead that already has its children** (a decomposed feature, an expanded task parent): skip it — it is not dispatchable itself, and its `stage:*` chore is dispatched on its own.
42
+ `execution:hitl` beads are not in this query and are not ralph's to touch: record them for the Pending Human Action summary. That includes every feature still at its default `execution:hitl` label.
43
+ 7. Dispatch each unit from its parent's worktree, up to 5 in flight: a stage chore via the event loop, a childless feature via a decomposition worker (_Feature decomposition_), a chore-less task via an expansion worker (_Expansion guard_). Create branches and worktrees first (REFERENCE.md, _Feature Branches and Worktrees_).
44
+ 8. Hand over to your harness's completion-detection mechanism: PI keeps a {{TOOL:wait_for_agents}} call outstanding over every in-flight agent ID, and Claude re-invokes you as each worker completes. If no **agent work** was dispatched — `state.json`'s `inflight` holds no entries, so no stage, decomposition or expansion worker is running — and `skills/workflow/ralph/scripts/pending-gates.mjs` reports a non-empty `pendingHumanAction` (an unblocked `lifecycle:feature-pr` gate, or an epic tagged `awaiting-epic-pr-merge`), go straight to HITL Pause (REFERENCE.md). A decomposition- or expansion-only init is in flight, not idle: keep the completion mechanism running and continue at the event loop.
45
+
46
+ ### 2. Expansion guard (stage chores are pre-created)
47
+
48
+ A ready `execution:afk` task bead with no `stage:*` chore children has nothing to dispatch, so it is not dispatched as work. Expand it first: dispatch a worker in the feature worktree that runs `create-chores.mjs --parent <id> --priority <parent-priority>` against the existing bead and reports the returned `code`/`verify`/`review`/`document`/`featurePrReview` mapping — the next `bd ready -l execution:afk` pass then picks up `stage:code` (see REFERENCE.md, _Expansion Guard_).
49
+
50
+ **Never expand an existing bead with `create-task`.** It creates a bead first and expands second, so the original would stay chore-less and gain a **second parent** beside it. `create-chores.mjs` expands; only `create-task` creates parents.
51
+
52
+ ### 3. Feature decomposition
53
+
54
+ A ready `execution:afk` bead of type `feature` with no children is not dispatchable work — there is nothing to stage and nothing to expand. Decompose it: dispatch a worker in `.agent-cortex/worktrees/<feature-id>` that turns the feature into one `execution:hitl` planning bead plus `execution:afk` implementation children that depend on it, then continue (REFERENCE.md, _Feature Decomposition_).
55
+
56
+ A feature carries `execution:hitl` by default, so this only runs when a human has deliberately relabelled a feature `execution:afk` to make its delivery agent-routable. Decomposition is then the last thing ralph does with it for a while: the children depend on the planning bead, so once the worker reports, `bd ready -l execution:afk` returns only the feature itself — no dispatchable child — and skipping that row is the *correct* behaviour, not re-expanding. **Never re-dispatch a decomposition**: the bead creation it runs is not idempotent, so a second run duplicates the whole hierarchy.
57
+
58
+ ### 4. Event loop
47
59
 
48
60
  On each completion notification (a background agent finished):
49
61
 
50
62
  1. Poll that parent's log for new lines — `tail -n +<nextLine> .agent-cortex/ralph/ralph-<parent-id>.log` (logs are keyed by parent bead ID, so every stage of a feature shares one file) — and post only new key events (stage transitions, test/lint results), never empty updates.
51
- 2. Read the completed agent's output with {{TOOL:read_agent}} and parse its `---REPORT---` block for `BEAD_ID`, `STAGE_COMPLETED`, and the outcome.
52
- 3. **Verify the delivery, then close the chore bead.** Run `node scripts/lib/verify-worker-tree.mjs --worktree .agent-cortex/worktrees/<parent-id> --base <base>` (REFERENCE.md, _Verified Completion_) and close only when it exits 0: `bd close <bead-id>`.
53
- 4. Advance the parent per the dispatch table:
63
+ 2. Read the completed agent's output with {{TOOL:read_agent}} and parse its `---REPORT---` block for `BEAD_ID`, `STAGE_COMPLETED`, and the outcome. A **decomposition** (`kind: "decompose"`) or **expansion** (`kind: "expand"`) worker has no REPORT and no leaf bead to confirm. An **expansion worker** owns no bead — confirm the parent now has `stage:*` chores (`bd children <parent-id> --json | grep -c '"stage:'`) and skip to step 5 to dispatch its ready `stage:code` chore. A **decomposition worker** — confirm the feature now has children (`bd children <feature-id> --json` returns a non-empty list), record that nothing is dispatchable for it until a human closes the planning bead, and skip to step 5; never re-decompose. If either confirmation comes back empty, the worker failed: surface its output, record the parent for the shutdown summary, and do not re-dispatch.
64
+ 3. Confirm the stage worker closed its chore bead: `bd show <bead-id>` should read `closed` with the outcome in its close reason. If it is still open the worker died mid-stage — read its notes and re-dispatch; never close it yourself.
65
+ 4. Route the parent per the dispatch table — nothing is created here: the pre-created chain already encodes the order, and the worker owns any remediation it needs.
54
66
 
55
67
  | Stage completed | Condition | Next action |
56
68
  |-----------------|-----------|-------------|
57
- | `code` | — | Closing the code chore unblocks the verify chore |
58
- | `fix` | — | Closing the fix chore unblocks the verify chore |
59
- | `verify` | `VERIFY_OUTCOME: PASS` | Closing the verify chore unblocks the review chore |
60
- | `verify` | `VERIFY_OUTCOME: FAIL` | Run the fix loop (REFERENCE.md) |
61
- | `review` | `REVIEW_OUTCOME: APPROVED` | Closing the review chore unblocks the document chore |
62
- | `review` | `REVIEW_OUTCOME: CHANGES_REQUESTED` | Run the fix loop (REFERENCE.md) |
63
- | `document` | — | Open/update the feature PR now (`feature/<parent-id>` → its base branch), report the URL, and update the child HITL gate bead (`lifecycle:feature-pr`). Wait for a human to close that bead after merge, then `bd close <parent-id>` |
69
+ | `code` | — | Closing the code chore unblocks the pre-created verify chore |
70
+ | `fix` | — | Closing the fix chore unblocks the fresh stage chore it was wired to |
71
+ | `verify` | `OUTCOME: SUCCESS` | Closing the verify chore unblocks the review chore |
72
+ | `verify` | `OUTCOME: BLOCKED` | Create nothing — the worker built `stage:fix` + a fresh `stage:verify`; dispatch the ready fix chore |
73
+ | `review` | `OUTCOME: SUCCESS` | Closing the review chore unblocks the document chore |
74
+ | `review` | `OUTCOME: BLOCKED` | Create nothing — the worker built `stage:fix` + a fresh `stage:review`; dispatch the ready fix chore |
75
+ | `document` | `OUTCOME: SUCCESS` | Open/update the feature PR now (`feature/<parent-id>` → its base branch), report the URL, and update the child HITL gate bead (`lifecycle:feature-pr`). Wait for a human to close that bead after merge, then `bd close <parent-id>` |
76
+ | any | parent status `blocked` | Nothing — the worker hit `maxFixRounds`; record the parent for the shutdown summary |
77
+
78
+ 5. Run `bd ready -l execution:afk` and dispatch new ready work while the in-flight count is under 5 — max 5 parent features, counted from `state.json`'s `inflight` (a parent counts while any of its workers — stage, `kind: "decompose"` or `kind: "expand"` — sits in `inflight`; REFERENCE.md, _State Files_). A ready childless feature is decomposed, not staged, and a ready bead with no chore tree is expanded (see _Feature decomposition_ and _Expansion guard_ above). Before each dispatch run the read-only cap backstop (REFERENCE.md, _Cap Backstop_): at `maxFixRounds` block the parent and create nothing. Do not schedule new parent features while `pending-gates.mjs` reports a non-empty `pendingHumanAction` — that is, while a `lifecycle:feature-pr` gate is **unblocked**. Gates still blocked behind their own pipeline (pre-created for a feature that has not reached its PR stage) are parked and never stop dispatch.
79
+ 6. If nothing is in flight (no stage, decomposition or expansion workers) and nothing is dispatchable (`bd ready -l execution:afk` returns no stage chore, no childless feature to decompose, and no ready, claimable chore-less task awaiting expansion — a queued `execution:afk` bead behind an open `lifecycle:feature-pr` HITL gate cannot be claimed, so it is paused work, not dispatchable work), proceed to HITL Pause (REFERENCE.md) when `pendingHumanAction` is non-empty, otherwise to Shutdown (REFERENCE.md).
80
+
81
+ ### 5. Reporting status (beads are the view)
64
82
 
65
- 5. Run `bd ready` and dispatch new ready `stage:*` chore beads while the in-flight count (`bd list --status=in_progress --type=chore`) is under 5. Do not schedule new parent features while `pending-gates.mjs` reports a non-empty `pendingHumanAction` — that is, while a `lifecycle:feature-pr` gate is **unblocked**. Gates still blocked behind their own pipeline (pre-created for a feature that has not reached its PR stage) are parked and never stop dispatch.
66
- 6. If no chores are in-flight and `bd ready` returns no `stage:*` chores, proceed to HITL Pause (REFERENCE.md) when `pendingHumanAction` is non-empty, otherwise to Shutdown (REFERENCE.md).
67
- 7. Regenerate `.agent-cortex/ralph/progress.md`.
83
+ There is no status document to render. Report status in chat straight from `bd`, and give the human the same copy-paste command when they want the view themselves:
68
84
 
69
- ### 3. Branching and review model
85
+ ```bash
86
+ bd list --parent <parent-id> # every chore for a feature, with its state
87
+ bd ready -l execution:afk # the next dispatchable work
88
+ bd show <id> # full detail, including the worker's notes
89
+ ```
90
+
91
+ ### 6. Branching and review model
70
92
 
71
93
  - **Single-feature epics** (exactly one feature task child — count with `bd children <epic-id>`, excluding chores): no epic branch. `feature/<parent-id>` is based directly on `origin/main`, its feature PR targets `main`, and no epic PR is opened.
72
- - **Multi-feature epics** (two or more feature task children): the epic runs on `epic/<epic-id>`, based on `origin/main` — never local `main`. Each AFK parent task runs on `feature/<parent-id>`, based from its epic branch, in the dedicated worktree `.agent-cortex/worktrees/<parent-id>`.
94
+ - **Multi-feature epics** (two or more feature task children): the epic runs on `epic/<epic-id>`, based on `origin/main` — never local `main`. Each `execution:afk` parent task runs on `feature/<parent-id>`, based from its epic branch, in the dedicated worktree `.agent-cortex/worktrees/<parent-id>`.
73
95
  - Feature PR gate: `feature/<parent-id>` → `epic/<epic-id>` (or → `main` for single-feature epics). Epic PR gate: `epic/<epic-id>` → `main`.
96
+ - **Never stack branches.** `feature/<parent-id>` is based on `epic/<epic-id>` (or `origin/main`), never on another `feature/*`. A dependency between two tasks lives in the bead graph (`bd dep add <waiting> <blocked-on>`) so the dependent task stays out of `bd ready` until its dependency has merged — stacking the branch defeats that gate by hand and costs a rebase-on-squash later (see `git-workflow` rule 3).
74
97
  - Branch/worktree setup and the PR commands live in REFERENCE.md (_Feature branches and worktrees_, _Feature PR gate_).
75
98
 
76
- ### 4. HITL pause and shutdown
99
+ ### 7. HITL pause and shutdown
100
+
101
+ Both paths end in a **gated** `bd dolt push`: on a non-zero exit, retry once, then stop and report the command, exit code and stderr as a sync blocker instead of printing any completion or Pending Human Action summary. A sync that never reached the remote is a failed shutdown, not a finished one.
77
102
 
78
- - **HITL Pause** — when no chores are in-flight, none ready, and `pending-gates.mjs` reports a non-empty `pendingHumanAction`: regenerate `progress.md`, open/update epic PRs to `main` for multi-feature epics and tag each epic `awaiting-epic-pr-merge` (single-feature epics need none — their feature PRs already target `main`), run `bd dolt push`, output the Pending Human Action table, then stop completely until re-prompted.
79
- - **Shutdown** — when all work is complete: regenerate `progress.md`, open/update epic PRs to `main` for multi-feature epics and tag them (single-feature epics need none), run `bd dolt push`, then output the Pending Human Action / Needs Refinement / cap-blocked / Pending Epic Review summaries that apply, or "All beads complete."
103
+ - **HITL Pause** — when nothing is in flight (no stage, decomposition or expansion workers), nothing is dispatchable (nothing returned by `bd ready -l execution:afk`, including no ready, claimable chore-less task awaiting expansion), and `pending-gates.mjs` reports a non-empty `pendingHumanAction` (an unblocked `lifecycle:feature-pr` gate, or an epic tagged `awaiting-epic-pr-merge`; gates still parked behind their own pipeline do not count): open/update epic PRs to `main` for multi-feature epics and tag each epic `awaiting-epic-pr-merge` (single-feature epics need none — their feature PRs already target `main`), run the gated `bd dolt push`, output the Pending Human Action table, then stop completely until re-prompted.
104
+ - **Shutdown** — when all work is complete: open/update epic PRs to `main` for multi-feature epics and tag them (single-feature epics need none), run the gated `bd dolt push`, then output the Pending Human Action / Needs Refinement / cap-blocked / Pending Epic Review summaries that apply, or "All beads complete."
80
105
 
81
106
  ## Red Flags
82
107
 
83
108
  - Running as a background or delegated subagent instead of the interactive foreground agent.
84
109
  - Spawning a stage runner via {{TOOL:bash}} or running a stage inline instead of {{TOOL:task}}.
85
- - Substituting a backgrounded CLI run for a missing subagent tool — stop and report instead; that launch has no completion signal.
86
- - Advancing a parent on a worker's `OUTCOME: SUCCESS` without verifying the worktree — the report is a claim, not evidence.
110
+ - Closing a leaf execution bead, or creating a `stage:fix`/feedback bead — both belong to the worker.
111
+ - Creating a stage chore, or running `create-task` for an existing bead — the chain is pre-created and `create-task` would add a second parent.
112
+ - Re-dispatching a decomposition because "the feature still looks idle" — the children are blocked on the planning bead, which is Q5b working, not a failure. Never re-create the hierarchy.
113
+ - Reaching for a narrower dispatch query (`bd ready -t chore`, "chores with `stage:*`") — an `execution:afk` bead with no stage chores is work waiting for expansion, not work that does not exist.
114
+ - Loop counting from a stage runner's prose when the same fact is queryable from beads.
87
115
  - Editing bead files directly instead of using `bd` commands.
88
116
  - Auto-merging a PR, or continuing past a feature/epic gate before a human merge.
89
117
 
@@ -94,29 +122,40 @@ On each completion notification (a background agent finished):
94
122
  | "I'll just run this one stage inline" | An orchestrator that executes stages stops being an orchestrator — the review gates exist to catch exactly that shortcut. |
95
123
  | "One more task in flight won't hurt" | The 5-task cap bounds log polling, state bookkeeping, and PR sequencing; exceeding it loses track of in-flight work. |
96
124
  | "The review passed, so I can merge" | Feature and epic PR merges are human-controlled; the gate exists so a person sees every change. |
125
+ | "The worker left the chore open — I'll close it" | The worker owns that bead; an open one means it died mid-stage, so read its notes and re-dispatch instead of closing over the missing record. |
126
+ | "This bead has no chores — I'll create them as I go" | The whole chain is pre-created with `blocks` deps; hand-creating stages duplicates chores and loses the order. Expand with `create-chores.mjs` instead. |
127
+ | "That feature came back ready again, so I'll decompose it a second time" | The implementation children depend on the planning bead, so nothing is ready until a human closes it. Re-decomposing duplicates the hierarchy; idling *is* the correct outcome. |
97
128
 
98
129
  ## Philosophy / rationale
99
130
 
100
131
  - Orchestration state derives from beads so a crash loses nothing but an in-memory ID mapping: `state.json` holds only the agent-ID→bead mapping, never task state.
101
- - Classification happens up-front at planning time (`create-task`), so the loop can trust `bd ready` instead of re-interpreting each bead's intent.
132
+ - Every control-flow predicate — is anything in flight, is there work, is there room, may we pause or shut down — derives from `state.json`'s `inflight` (`kind: "stage"`, `kind: "decompose"` or `kind: "expand"`) plus `bd ready -l execution:afk`, never from a chore-type `bd` query: an expansion or decomposition worker owns no stage chore, so a chore-only predicate reports idle while an agent is running (REFERENCE.md, _The in-flight invariant_).
133
+ - One predicate answers both *who runs this* and *when*: `execution:afk` says it is agent work and the bead graph says it is ready, so ralph needs no label that encodes "not really work yet" — a childless feature is routed by its type, not excluded by a filter. Classification happens up-front at planning time (`create-task`), so the loop can trust the query instead of re-interpreting each bead's intent.
102
134
  - Human review gates are non-negotiable because agent-authored changes still need a person to merge them.
135
+ - One owner per lifecycle: the actor that did the work records the outcome, so beads never carry an outcome written by someone who was not there.
103
136
 
104
137
  ## Phase-gate checklists
105
138
 
106
- - [ ] Init complete: `bd prime` held, gitignore entries present, workspace and state.json created, pipeline.json read, first `bd ready` classified, first chores dispatched.
107
- - [ ] Event loop handed off: completion-detection mechanism running (or HITL Pause/Shutdown started) and `progress.md` regenerated.
139
+ - [ ] Init complete: `bd prime` held, gitignore entries present, workspace and state.json created, pipeline.json read, first `bd ready -l execution:afk` classified, first agent work dispatched (a stage chore, a decomposition worker or an expansion worker).
140
+ - [ ] Event loop handed off: completion-detection mechanism running (or HITL Pause/Shutdown started) — a decomposition- or expansion-only init is in flight, not idle.
141
+
142
+ ## See Also
108
143
 
109
- ## Cross-skill references
144
+ - [run-pipeline-stage](../run-pipeline-stage/SKILL.md) — owns the stage-runner prompt, per-stage playbooks, the `---REPORT---` format, and the worker's remediation chain. Read it before dispatching any stage.
145
+ - [create-task](../../planning/create-task/SKILL.md) — owns `pipeline.json` and the HITL gate beads; its `scripts/pending-gates.mjs` is the only home of the gate queries.
146
+ - [prd-to-tasks](../../planning/prd-to-tasks/SKILL.md) — load when the decomposition worker expands a feature into slices.
110
147
 
111
- - The `run-pipeline-stage` skill owns the stage-runner prompt, per-stage playbooks, the `---REPORT---` format, and fix-loop feedback beads — read it before dispatching any stage.
112
- - The `create-task` skill owns `pipeline.json` and creates the `lifecycle:feature-pr` HITL gate beads. `skills/workflow/ralph/scripts/pending-gates.mjs` owns the gate predicate — parked vs pending — and is the only place the gate queries live.
113
- - Do not invoke `classify-bead` from this loop — classification was already applied at planning time.
148
+ Do not invoke `classify-bead` from this loop — classification was applied at planning time.
114
149
 
115
150
  ## Verification checklist
116
151
 
117
- - [ ] Init ran once with observable results: `state.json` exists, `bd ready` was parsed, and the first chore beads are claimed.
152
+ - [ ] Init ran once with observable results: `state.json` exists, `bd ready -l execution:afk` was parsed, and agent work is in flight — a stage chore claimed, or a decomposition or expansion worker dispatched for a bead that needed one.
118
153
  - [ ] Every stage runner was spawned with {{TOOL:task}} from the parent's feature worktree, with the `---REPORT---` instruction in its prompt.
119
- - [ ] Every stage delivery was confirmed with `scripts/lib/verify-worker-tree.mjs` before the parent advanced, and no stage was dispatched from a session with no subagent tool.
120
- - [ ] In-flight count never exceeded 5, and fix loops respect `maxFixRounds` from `pipeline.json`.
154
+ - [ ] Every dispatch came from `bd ready -l execution:afk` — no narrower chore-only filter was used to decide that a bead was not work.
155
+ - [ ] A childless `execution:afk` feature was decomposed exactly once into a planning bead plus `execution:afk` children depending on it, and was not re-decomposed on later idle passes.
156
+ - [ ] In-flight count never exceeded 5, and the read-only cap backstop ran before every `stage:*` dispatch.
157
+ - [ ] Every in-flight, dispatchable-work, HITL-pause, and shutdown predicate was read from `state.json`'s `inflight` (stage, decomposition **and** expansion workers) plus `bd ready -l execution:afk`, with the ready, claimable scope of a chore-less `execution:afk` task bead — never from a chore-only `bd` query, and never counting a bead an open `lifecycle:feature-pr` gate blocks from being claimed.
158
+ - [ ] Ralph closed no leaf execution bead and created no fix bead; every closed chore carries its worker's close reason.
159
+ - [ ] Any chore-less `execution:afk` task bead was expanded with `create-chores.mjs` (one parent bead), never with `create-task`.
121
160
  - [ ] Feature and epic PRs were pushed and reported immediately at their gates, and nothing was auto-merged.
122
- - [ ] `bd dolt push` and a final `progress.md` regeneration ran before HITL Pause/Shutdown, and the chat received no empty poll updates.
161
+ - [ ] Every `bd dolt push` before HITL Pause/Shutdown exited 0 — a non-zero exit was retried once, then surfaced as a blocker (command, exit code, stderr) with no completion or Pending Human Action summary printed; status was reported from `bd` commands rather than a generated file, and the chat received no empty poll updates.