@jaybeeuu/agent-cortex 2.6.0 → 2.8.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 (64) hide show
  1. package/CHANGELOG.md +269 -0
  2. package/README.md +102 -8
  3. package/agents/README.md +2 -2
  4. package/agents/ralph/agent.md +19 -16
  5. package/agents/ralph/claude/wake.md +4 -4
  6. package/agents/ralph/pi/wake.md +15 -20
  7. package/bin/agent-cortex.mjs +176 -67
  8. package/bin/installers/claude.mjs +33 -8
  9. package/bin/installers/pi.mjs +11 -1
  10. package/docs/skills/skill-anatomy.md +212 -0
  11. package/extensions/post-merge-watch/README.md +133 -0
  12. package/extensions/post-merge-watch/index.test.ts +247 -0
  13. package/extensions/post-merge-watch/index.ts +123 -0
  14. package/extensions/post-merge-watch/package.json +16 -0
  15. package/extensions/post-merge-watch/watch.test.ts +469 -0
  16. package/extensions/post-merge-watch/watch.ts +431 -0
  17. package/extensions/session-clear/README.md +74 -0
  18. package/extensions/session-clear/index.test.ts +524 -0
  19. package/extensions/session-clear/index.ts +159 -0
  20. package/extensions/session-clear/package.json +16 -0
  21. package/lib/cli.mjs +88 -1
  22. package/lib/harness-update.mjs +254 -0
  23. package/lib/harness-versions.mjs +36 -2
  24. package/lib/self-update.mjs +553 -0
  25. package/package.json +2 -1
  26. package/scripts/lib/docs.mjs +67 -0
  27. package/skills/engineering/implement-task/SKILL.md +124 -0
  28. package/skills/engineering/tdd/SKILL.md +2 -0
  29. package/skills/planning/create-task/REFERENCE.md +20 -3
  30. package/skills/planning/create-task/SKILL.md +1 -1
  31. package/skills/planning/create-task/pipeline.json +16 -0
  32. package/skills/planning/create-task/scripts/create-chores.mjs +51 -24
  33. package/skills/planning/create-task/templates/code.md +8 -3
  34. package/skills/planning/create-task/templates/document.md +8 -3
  35. package/skills/planning/create-task/templates/fix.md +8 -3
  36. package/skills/planning/create-task/templates/housekeeping.md +69 -0
  37. package/skills/planning/create-task/templates/post-merge.md +67 -0
  38. package/skills/planning/create-task/templates/review.md +8 -3
  39. package/skills/planning/create-task/templates/verify.md +8 -3
  40. package/skills/productivity/bd-tool/SKILL.md +55 -0
  41. package/skills/productivity/write-a-skill/SKILL.md +2 -2
  42. package/skills/review/refactor-skill/SKILL.md +2 -2
  43. package/skills/review/review-defects/EXAMPLES.md +122 -0
  44. package/skills/review/review-defects/SKILL.md +91 -0
  45. package/skills/style/style-tests/EXAMPLES.md +30 -0
  46. package/skills/style/style-tests/SKILL.md +10 -6
  47. package/skills/workflow/plan/SKILL.md +14 -3
  48. package/skills/workflow/ralph/REFERENCE.md +137 -30
  49. package/skills/workflow/ralph/SKILL.md +26 -16
  50. package/skills/workflow/ralph/scripts/post-merge-check.mjs +651 -0
  51. package/skills/workflow/run-pipeline-stage/SKILL.md +41 -23
  52. package/skills/workflow/run-pipeline-stage/playbooks/code.md +14 -8
  53. package/skills/workflow/run-pipeline-stage/playbooks/document.md +2 -2
  54. package/skills/workflow/run-pipeline-stage/playbooks/fix.md +2 -2
  55. package/skills/workflow/run-pipeline-stage/playbooks/housekeeping.md +58 -0
  56. package/skills/workflow/run-pipeline-stage/playbooks/post-merge.md +54 -0
  57. package/skills/workflow/run-pipeline-stage/playbooks/review.md +34 -3
  58. package/skills/workflow/run-pipeline-stage/playbooks/verify.md +2 -2
  59. package/skills/workflow/run-pipeline-stage/prompts/stage-runner.md +66 -10
  60. package/skills/workflow/run-pipeline-stage/scripts/recover-brief.mjs +805 -0
  61. package/skills/workflow/run-pipeline-stage/scripts/trail-entry.mjs +702 -0
  62. package/skills/workflow/using-agent-skills/SKILL.md +15 -7
  63. package/token-map.README.md +41 -4
  64. package/token-map.json +16 -5
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  name: run-pipeline-stage
3
- description: Execute a single pipeline stage for a bead (code, verify, review, document) via its playbook and read-only routing, reporting the outcome in a fixed REPORT shape. Use when you want to "work through beads inline", "pick up a specific stage bead", or run one stage "without the full ralph orchestrator".
3
+ description: Execute a single pipeline stage for a bead (code, verify, review, document, post-merge, housekeeping) via its playbook and read-only routing, reporting the outcome in a fixed REPORT shape. Use when you want to "work through beads inline", "pick up a specific stage bead", or run one stage "without the full ralph orchestrator".
4
4
  ---
5
5
 
6
6
  # Run Pipeline Stage
7
7
 
8
- Stage beads (`stage:code`, `stage:verify`, `stage:review`, `stage:document`, `stage:fix`) come from the pipeline definition in `skills/planning/create-task/pipeline.json`. This skill executes one stage and owns that bead's lifecycle: the runner that does the work appends its own notes, closes its own leaf execution bead on **both** outcomes, and builds its own remediation children when the stage fails. The orchestrator dispatches and routes — it never edits or closes a leaf bead.
8
+ Stage beads (`stage:code`, `stage:verify`, `stage:review`, `stage:document`, `stage:post-merge`, `stage:housekeeping`, `stage:fix`) come from the pipeline definition in `skills/planning/create-task/pipeline.json`. This skill executes one stage and owns that bead's lifecycle: the runner that does the work appends its own notes, closes its own leaf execution bead on **both** outcomes, and builds its own remediation children when the stage fails. `housekeeping` and `post-merge` are the exceptions: `housekeeping` never closes its bead over a worktree the pruner did not remove, `post-merge` leaves its bead open when the merge's CI run failed or the check was inconclusive, and neither builds remediation children. The orchestrator dispatches and routes — it never edits or closes a leaf bead.
9
9
 
10
10
  ## When to use
11
11
 
@@ -24,7 +24,7 @@ Stage beads (`stage:code`, `stage:verify`, `stage:review`, `stage:document`, `st
24
24
 
25
25
  | Actor | Owns |
26
26
  |---|---|
27
- | Stage runner (worker) | Milestone notes, progress-log lines, closing its leaf bead on both outcomes, remediation children, the REPORT |
27
+ | Stage runner (worker) | Trail entries through `scripts/trail-entry.mjs`, closing its leaf bead on both outcomes (`housekeeping` and `post-merge` excepted: each may leave its bead open), remediation children, the REPORT |
28
28
  | Orchestrator (ralph or you) | Claim, dispatch, forward routing, the read-only cap backstop, the PR gate |
29
29
 
30
30
  A leaf bead is the worker's record of what happened. The orchestrator reads it; it does not write it.
@@ -33,7 +33,7 @@ A leaf bead is the worker's record of what happened. The orchestrator reads it;
33
33
 
34
34
  1. Run `bd prime` and hold the output; subagents can run it themselves if they need context.
35
35
  2. If no bead was specified, run `bd ready` and ask the user which to work on.
36
- 3. Claim the bead with `bd update <id> --claim` — the bead, not the prompt, is the source of truth. Append a stage-start note immediately (see _Milestone Notes_).
36
+ 3. Claim the bead with `bd update <id> --claim` — the bead, not the prompt, is the source of truth. Record a stage-start trail entry immediately (see _Trail Entries_).
37
37
  4. Read the bead's `stage:*` label — it names the stage to execute.
38
38
  5. Load the universal stage-runner prompt (`skills/workflow/run-pipeline-stage/prompts/stage-runner.md`) — it carries the lifecycle, remediation, and REPORT contract — populate `<stage>`, and read the matching playbook (`playbooks/<stage>.md`) for stage-specific rules.
39
39
  6. Tag the stage — beads are the only status view:
@@ -43,7 +43,7 @@ bd tag <id> stage:<stage>
43
43
  ```
44
44
 
45
45
  7. Dispatch one subagent per stage with the composed prompt — spawn it with {{TOOL:task}}. The prompt already ends with the REPORT contract; never compose one without it. A session with no subagent tool cannot dispatch: stop and say so rather than substituting a backgrounded CLI run, which has no completion signal.
46
- 8. Verify the delivery against the worktree — `node scripts/lib/verify-worker-tree.mjs --worktree <abs-worktree> --base <base>` exits 0 only for a clean tree with a commit ahead of base. A worker whose REPORT claims `OUTCOME: SUCCESS` over a dirty tree has not delivered; re-dispatch it instead of advancing.
46
+ 8. Verify the delivery against the worktree — `node scripts/lib/verify-worker-tree.mjs --worktree <abs-worktree> --base <base>` exits 0 only for a clean tree with a commit ahead of base. A worker whose REPORT claims `OUTCOME: SUCCESS` over a dirty tree has not delivered; re-dispatch it instead of advancing. `post-merge` and `housekeeping` change no files and deliver no commit, so skip this check for those two stages.
47
47
  9. On the REPORT: route forward per _Routing_ below. Do **not** close the leaf bead — the worker closed it before reporting.
48
48
 
49
49
  Each step leaves observable state — a claimed bead, a `stage:` tag, worker notes and a closed bead, a verified commit, and a REPORT that drives the next action.
@@ -58,7 +58,11 @@ The worker built anything this stage needed; routing picks up whatever `bd ready
58
58
  | `review` | `OUTCOME: SUCCESS` | Dispatch the ready `stage:document` chore |
59
59
  | `fix` | `OUTCOME: SUCCESS` | Dispatch the ready re-run chore that was blocked on the fix |
60
60
  | `document` | `OUTCOME: SUCCESS` | Open/update the feature PR and the HITL gate bead |
61
+ | `post-merge` | `OUTCOME: SUCCESS` | Create nothing — the merge commit's CI run is green; the closed chore is the record |
62
+ | `housekeeping` | `OUTCOME: SUCCESS` | Create nothing — this is the last stage; its closed chore ends the pipeline |
61
63
  | `code` / `verify` / `review` / `fix` / `document` | `OUTCOME: BLOCKED` | Create nothing — the worker built `stage:fix` + a fresh instance of its own stage; dispatch the ready fix chore |
64
+ | `post-merge` | `OUTCOME: BLOCKED` | Create nothing — the worker left its chore **open** and the check filed one P1 escalation bead; report the escalation id and the run URL, and do not re-dispatch |
65
+ | `housekeeping` | `OUTCOME: BLOCKED` | Create nothing — the worker left its chore **open**; hand the surviving worktrees to a human. Do not re-dispatch it automatically |
62
66
  | any | parent status `blocked` | Nothing — the worker or the cap backstop blocked it; record it for shutdown |
63
67
 
64
68
  Cap backstop (read-only): before dispatching a `stage:*` chore, count the parent's fix rounds and, if already at `maxFixRounds` (`skills/planning/create-task/pipeline.json`, currently `4`), block the parent and create nothing:
@@ -69,7 +73,7 @@ fix_rounds=$(bd children <parent-id> --json | grep -c '"stage:fix"')
69
73
 
70
74
  ## Remediation Children (worker-built)
71
75
 
72
- On `OUTCOME: BLOCKED` the worker creates its own chain — a `stage:fix` chore carrying the feedback, plus a **fresh instance of the stage that failed**, blocked on the fix. A fresh instance is not optional: the failed chore is already closed, so the pre-created chain cannot re-verify a fix.
76
+ On `OUTCOME: BLOCKED` the worker creates its own chain — a `stage:fix` chore carrying the feedback, plus a **fresh instance of the stage that failed**, blocked on the fix. A fresh instance is not optional: the failed chore is already closed, so the pre-created chain cannot re-verify a fix. `housekeeping` is the exception — it changes no files, its bead stays open, and nothing downstream waits on it, so it builds no chain.
73
77
 
74
78
  | Failed stage | Chain |
75
79
  |---|---|
@@ -78,32 +82,47 @@ On `OUTCOME: BLOCKED` the worker creates its own chain — a `stage:fix` chore c
78
82
  | `review` | `stage:fix` → fresh `stage:review` |
79
83
  | `document` | `stage:fix` → fresh `stage:document` |
80
84
  | `fix` | `stage:fix` → fresh `stage:fix` |
85
+ | `housekeeping` | none — the worker leaves its chore open, reports `BLOCKED`, and hands the surviving worktrees to a human. No `stage:fix` and no fresh `stage:housekeeping`, because the stage repairs no files and sits last in the chain |
86
+ | `post-merge` | none — the worker leaves its chore open, reports `BLOCKED`, and names the escalation bead the check filed. No `stage:fix` and no fresh `stage:post-merge`, because no fix round repairs a commit that already merged |
81
87
 
82
88
  Webbing, at cap, and the exact commands live in `prompts/stage-runner.md` and each playbook's _Remediation and close_ section. In short: both beads are children of the parent task (`--parent <parent-id>`), the fresh stage is `bd dep add <fresh> <fix> --type blocks`, and any not-yet-run later stage is re-blocked behind the fresh bead. Chores carry no required sections, so the feedback description points at the parent/requirements bead (`<parent-id>`) rather than restating its acceptance criteria.
83
89
 
84
- ## Progress Logging
90
+ ## Trail Entries
85
91
 
86
- Inside the ralph orchestrator, write one structured line per transition or key event to `.agent-cortex/ralph/ralph-{bead-id}.log`:
92
+ One script writes the bead trail: `scripts/trail-entry.mjs`, run by the worker at each transition. It appends one checkpoint to the bead's notes with `bd note`, and records any refs the caller names as provenance events.
87
93
 
88
- ```
89
- [ISO-timestamp] [bead-id] [stage] message
94
+ ```bash
95
+ node <run-pipeline-stage-scripts>/trail-entry.mjs \
96
+ --bead <id> --stage <stage> --outcome <done|blocked|partial> \
97
+ --evidence "<test or lint result, commit, command output>" \
98
+ --remaining "<what is left, or none>" \
99
+ [--commit <ref>] [--branch <branch>] [--pr <url>] [--work-id <worktree-id>]
90
100
  ```
91
101
 
92
- Log stage starts and completes, test/lint/build/security results, blockers, and decisions — not file reads or minor actions.
102
+ Three fields are mandatory, and the script refuses an entry without them:
93
103
 
94
- ```bash
95
- mkdir -p .agent-cortex/ralph && echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] [bead-id] [stage] message" >> .agent-cortex/ralph/ralph-bead-id.log
96
- ```
104
+ - **Outcome** — `done`, `blocked` or `partial`, a fixed vocabulary rather than prose.
105
+ - **Evidence** — the result that proves it: a test or lint outcome, the commit SHA, command output.
106
+ - **What is left** — the next concrete action, or `none`.
97
107
 
98
- ## Milestone Notes
108
+ `--commit` accepts any ref and is resolved through `git rev-parse` to the full 40-character lowercase SHA, because `bd provenance record --ref-kind git-sha` refuses an abbreviated one. A ref that does not resolve to 40 lowercase hex characters records nothing at all.
99
109
 
100
- The bead's notes are the recovery contract: if a session dies mid-stage, a fresh agent must resume from `bd show <id>` alone. Append a short checkpoint at stage start and at each milestone — never on every tool call.
110
+ Recording is safe to repeat. The entry carries a fingerprint of its own content, so a repeated fire — a second run after the first finished — finds it present and appends nothing; provenance recording is idempotent in `bd` itself. That holds for one writer at a time: `bd note` has no conditional append, so two writers that read the bead before either appends both write, and the duplicate entries carry the same fingerprint and are deduplicable — fire each transition from one worker. A transient database failure — `failed to open database ... context canceled`, the shape two concurrent writers produce — is retried with bounded backoff, and each retry re-reads the bead first, so a write that landed before its call reported failure is never duplicated. A permanent failure reports on stderr with a non-zero exit and appends nothing twice.
111
+
112
+ Resume with the recovery brief below; reach for `bd show <id>` (entries) or `bd provenance log <id>` (refs) only to widen what it printed. A note appended by hand with `bd note` prints in the brief wherever it lands, so the trail count includes it. There is no progress file: beads stay the single source of truth, and no stage writes a log.
113
+
114
+ ### Reading the trail
115
+
116
+ Run `scripts/recover-brief.mjs` first. One call prints what a session needs to continue: status and state labels, the newest trail entries with their Evidence and What is left, provenance refs, blocking dependencies, and the acceptance criteria. `bd show` on a bare bead carrying 20 entries prints 89 lines and about 6.5 KB, and on a realistic one — 21 entries with acceptance criteria, a blocker, provenance refs and a description — about 120 lines and about 8 KB, most of it history the reader does not need; the brief stays inside a line budget (default 40) that the script enforces on its own output.
101
117
 
102
118
  ```bash
103
- bd update <id> --append-notes "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] [<stage>] <what changed / what's next>"
119
+ node <run-pipeline-stage-scripts>/recover-brief.mjs --bead <id> \
120
+ [--trail 3] [--provenance 4] [--max-lines 40]
104
121
  ```
105
122
 
106
- `--append-notes` preserves the trail; plain `--notes` overwrites it. Record the start (stage, worktree, first action), milestones (completed chunks, tests green, files changed), decisions and rejected options, blocks, and discoveries. One or two lines per entry — a scan-friendly checkpoint trail, not a transcript. No new scratch files; beads stay the single source of truth.
123
+ `bd` returns the whole note — there is no way to ask it for the last few entries — so the brief prints the newest `--trail` entries and summarises the rest by count. It reads only: every `bd` call is a read subcommand carrying `--readonly`, so it cannot write to the tracker, and it never records a note or a provenance event. Its sections state plainly when a bead has no trail, no refs, no acceptance criteria or no blockers, rather than printing an empty heading.
124
+
125
+ Read the whole note with `bd show <id>` only when you need an entry the window left out, and the full event history with `bd provenance log <id>` only when the brief's four events are not enough.
107
126
 
108
127
  ## Report Format
109
128
 
@@ -112,7 +131,7 @@ Every stage-runner prompt ends with the literal REPORT instruction (see `prompts
112
131
  ```
113
132
  ---REPORT---
114
133
  BEAD_ID: <id>
115
- STAGE_COMPLETED: <code|verify|review|document|fix>
134
+ STAGE_COMPLETED: <code|verify|review|document|post-merge|housekeeping|fix>
116
135
  SUMMARY: <2-3 sentence summary of what was done>
117
136
  FILES_CHANGED: <comma-separated list, or "none">
118
137
  COMMIT: <sha of the stage commit, or "none">
@@ -151,9 +170,9 @@ stage: the commit is the evidence, the report is the claim.
151
170
 
152
171
  - [create-task](../../planning/create-task/SKILL.md) — owns `pipeline.json`: stages, `maxFixRounds`, and the stage templates.
153
172
  - [bd-tool](../../productivity/bd-tool/SKILL.md) — bead mechanics beyond the commands used here.
154
- - [ralph](../ralph/SKILL.md) — runs many stage beads concurrently and consumes this skill's log and REPORT contracts.
173
+ - [ralph](../ralph/SKILL.md) — runs many stage beads concurrently and consumes this skill's trail and REPORT contracts.
155
174
 
156
- Each playbook delegates to a stage skill: `tdd`/`style-code`/`style-tests` (code, fix), `review-security` (review), `style-documentation` (document).
175
+ Each playbook delegates to a stage skill: `tdd`/`style-code`/`style-tests` (code, fix), `review-security` (review), `style-documentation` (document). `housekeeping` and `post-merge` delegate to no stage skill — each runs one deterministic script and reports what it printed.
157
176
 
158
177
  ## Examples
159
178
 
@@ -172,6 +191,5 @@ Each playbook delegates to a stage skill: `tdd`/`style-code`/`style-tests` (code
172
191
  - [ ] `bd tag <id> stage:<stage>` run before dispatch.
173
192
  - [ ] Correct playbook read and followed for the stage; stage skills invoked where the playbook says.
174
193
  - [ ] Composed prompt carries the lifecycle, remediation, and REPORT contract from `prompts/stage-runner.md`.
175
- - [ ] Progress log lines written for every stage transition and key result.
176
- - [ ] Milestone notes appended at stage start and each milestone with `--append-notes` (not `--notes`).
194
+ - [ ] A trail entry written at every stage transition, through `trail-entry.mjs`, with Outcome, Evidence and What is left.
177
195
  - [ ] The orchestrator closed no leaf bead and created no fix bead; the cap backstop ran before any dispatch.
@@ -2,12 +2,18 @@
2
2
 
3
3
  ## Stage Instructions
4
4
 
5
- 1. Invoke `style-tests` before writing tests.
6
- 2. Invoke `tdd` for the red-green-refactor implementation loop.
7
- 3. Invoke `style-code` before making code changes.
8
- 4. Do not add speculative code — only what is required by current tests/requirements.
9
- 5. Make only task-scoped changes; avoid unrelated refactors.
10
- 6. Use context7 for third-party libraries when API/version details matter.
5
+ 1. Invoke `implement-task` first. It reads the parent's `## Acceptance Criteria`, writes the
6
+ criteria → evidence table before any code is touched, and holds the scope, boy-scout and
7
+ mutation-check rules for the rest of the stage. A criterion with no check is a blocker: report
8
+ `OUTCOME: BLOCKED` rather than guessing a proof.
9
+ 2. It routes to `style-tests` before writing tests.
10
+ 3. It routes to `tdd` for the red-green-refactor loop, one criterion at a time.
11
+ 4. It routes to `style-code` before making code changes.
12
+ 5. Do not add speculative code — only what is required by current tests/requirements.
13
+ 6. Make only task-scoped changes; record out-of-scope findings as beads instead of editing them.
14
+ 7. Use context7 for third-party libraries when API/version details matter.
15
+ 8. Report the filled criteria → evidence table; the stage's requirements are the rows, not the
16
+ diff.
11
17
 
12
18
  ## Stage Outcome
13
19
 
@@ -19,8 +25,8 @@
19
25
 
20
26
  ## Remediation and close
21
27
 
22
- - You own this leaf bead: append notes, write the progress log, and `bd close <id> --reason=...`
23
- on both outcomes (see `prompts/stage-runner.md`).
28
+ - You own this leaf bead: record the trail entry through `scripts/trail-entry.mjs`, then
29
+ `bd close <id> --reason=...` on both outcomes (see `prompts/stage-runner.md`, _Trail entries_).
24
30
  - `OUTCOME: SUCCESS` — create nothing; the orchestrator routes to `verify`.
25
31
  - `OUTCOME: BLOCKED` — count the parent's existing `stage:fix` children against
26
32
  `maxFixRounds` in `skills/planning/create-task/pipeline.json`. Under cap, create a
@@ -21,8 +21,8 @@
21
21
 
22
22
  ## Remediation and close
23
23
 
24
- - You own this leaf bead: append notes, write the progress log, and `bd close <id> --reason=...`
25
- on both outcomes (see `prompts/stage-runner.md`).
24
+ - You own this leaf bead: record the trail entry through `scripts/trail-entry.mjs`, then
25
+ `bd close <id> --reason=...` on both outcomes (see `prompts/stage-runner.md`, _Trail entries_).
26
26
  - `OUTCOME: SUCCESS` — create nothing; the orchestrator opens the feature PR and updates the
27
27
  HITL gate bead.
28
28
  - `OUTCOME: BLOCKED` — count the parent's existing `stage:fix` children against
@@ -19,8 +19,8 @@
19
19
 
20
20
  ## Remediation and close
21
21
 
22
- - You own this leaf bead: append notes, write the progress log, and `bd close <id> --reason=...`
23
- on both outcomes (see `prompts/stage-runner.md`).
22
+ - You own this leaf bead: record the trail entry through `scripts/trail-entry.mjs`, then
23
+ `bd close <id> --reason=...` on both outcomes (see `prompts/stage-runner.md`, _Trail entries_).
24
24
  - `OUTCOME: SUCCESS` — create nothing; closing this bead unblocks the fresh stage chore that
25
25
  was wired behind it.
26
26
  - `OUTCOME: BLOCKED` — count the parent's existing `stage:fix` children against
@@ -0,0 +1,58 @@
1
+ # Stage Playbook: housekeeping
2
+
3
+ This stage runs after the human merge gate and is last in the chain. It removes the worktrees of
4
+ closed beads and changes no files.
5
+
6
+ ## Stage Instructions
7
+
8
+ 1. **Work from the main checkout.** Run every command from the repository's main checkout — the
9
+ directory that holds `.agent-cortex/worktrees/` — never from a bead worktree. The worktree this
10
+ run removes can be the one you are standing in.
11
+
12
+ 2. **Run the pruner once:**
13
+ ```bash
14
+ node <ralph-scripts>/prune-worktrees.mjs
15
+ ```
16
+ `<ralph-scripts>` is the absolute path to `skills/workflow/ralph/scripts/`, resolved from wherever
17
+ that skill was loaded. Read the per-worktree report it prints: every scanned worktree, its
18
+ classification (`closed-bead`, `open-bead`, `orphan`, `unclassified`) and its outcome (`removed`,
19
+ `kept`, `refused`).
20
+
21
+ 3. **Retry once on a non-zero exit.** Exit status `1` means at least one scanned worktree survived,
22
+ and an open bead counts as survival, so a normal run against a live backlog exits `1`. Run the
23
+ same command a second time when the first run exits non-zero. One retry, never more.
24
+
25
+ 4. **Decide from the per-worktree report, not from the exit status.** After the retry:
26
+ - **SUCCESS** — no `closed-bead` worktree is left in `refused` state. Report every worktree the
27
+ run removed and every one it kept, with the printed reason.
28
+ - **BLOCKED** — a `closed-bead` worktree is still `refused` after the retry, or the pruner could
29
+ not run at all (missing node, unreadable directory). A refused `closed-bead` worktree is a
30
+ worktree this run did not remove, whatever reason it printed.
31
+
32
+ 5. **Never close over a worktree the script did not remove.** Do not delete a worktree by hand, do
33
+ not pass `--remove-orphans`, and do not edit the pruner. This stage reports what the script did.
34
+
35
+ ## Stage Outcome
36
+
37
+ - **No commit and no push.** This stage changes no files, so report `COMMIT: none` and
38
+ `PUSHED: no` on both outcomes. Do not create an empty commit.
39
+ - Set `OUTCOME: SUCCESS` when every `closed-bead` worktree is gone after the retry. `FILES_CHANGED`
40
+ is `none`.
41
+ - Set `OUTCOME: BLOCKED` when a `closed-bead` worktree survived the retry, or the pruner could not
42
+ run. List each surviving worktree with the printed reason under `BLOCKING_ISSUES`.
43
+ - A `kept` or `refused` entry for an open bead is a normal report, not a failure.
44
+
45
+ ## Remediation and close
46
+
47
+ - **This stage is the exception to close-on-both-outcomes.** Nothing downstream waits on its close,
48
+ so the bead's own state is the report.
49
+ - `OUTCOME: SUCCESS` — record the trail entry, then
50
+ `bd close <id> --reason="SUCCESS: <removed/kept summary>"`. Create nothing: this is the last stage
51
+ and its closed chore ends the pipeline.
52
+ - `OUTCOME: BLOCKED` — **do not close the bead.** Leave it open: return it to `open` status
53
+ (`bd update <id> --status open`) if your claim moved it to `in_progress`. Report the surviving
54
+ worktrees and hand the chore back to a human. Create no `stage:fix` chore and no fresh
55
+ `stage:housekeeping` chore — a fix round repairs files, and this stage repairs none.
56
+ - **No downstream re-block.** This stage sits behind the PR gate rather than behind another stage, so
57
+ no later stage needs wiring behind a fresh instance.
58
+ - Report `COMMIT: none`, `PUSHED: no`, and `PR: none`.
@@ -0,0 +1,54 @@
1
+ # Stage Playbook: post-merge
2
+
3
+ ## Stage Instructions
4
+
5
+ 1. Run the check once from the **main checkout** — never from the bead worktree, because the commit
6
+ under test landed on the base branch:
7
+ ```bash
8
+ node <ralph-scripts>/post-merge-check.mjs
9
+ ```
10
+ It prints a JSON report and exits `0` passed, `1` failed, `2` inconclusive.
11
+ 2. Read the exit status as the verdict. `--base <branch>` overrides the base branch (default: the
12
+ repository's default branch). `--commit <sha>` overrides the merge commit (default: the base
13
+ branch's tip). `--wait <seconds>` changes the wait window; the default is 300.
14
+ 3. On `0` — report the run URLs and close the chore. On `1` — the script filed one P1 escalation
15
+ bead carrying the run URL and the failing job; report the bead id and the run URL, and leave the
16
+ chore **open**. On `2` — report the printed `reason` and leave the chore **open**.
17
+ 4. Never retry the check for a different answer, never re-run the GitHub workflow, never revert the
18
+ merge, and never reopen the parent feature bead.
19
+ 5. The check reads `gh run list` for the base branch: GitHub-only in v1. A repository `gh` cannot
20
+ resolve to GitHub, or a commit with no run, is `inconclusive` — reported, never escalated.
21
+
22
+ ## Watch transport
23
+
24
+ The check waits `--wait` seconds (default 300) for the run to settle. A run still in flight at that
25
+ window is exit `2` with a still-running reason: a report, not a verdict, and never something to page
26
+ a human for.
27
+
28
+ The wait past that window belongs to the harness, so never write a poll loop of your own — no
29
+ `sleep` and re-run. Poll with {{TOOL:post_merge_watch}} and end the turn. The session resumes when a
30
+ verdict may exist; run the check again then, and apply step 3 unchanged.
31
+
32
+ Running the check again on a resume is the watch continuing, not the retry step 4 forbids: you read
33
+ the same run's verdict, never ask for a different one. A failure still reaches a human through the
34
+ escalation bead the script files, and this stage still repairs nothing.
35
+
36
+ No harness is assumed to have a watcher. A session with no such mechanism runs the check once with
37
+ a longer window instead — `node <ralph-scripts>/post-merge-check.mjs --wait 1800` — and reports what
38
+ it printed. The verdicts, the escalation rule and the close rule do not change.
39
+
40
+ ## Stage Outcome
41
+
42
+ - `OUTCOME: SUCCESS` only on exit `0`.
43
+ - `OUTCOME: BLOCKED` on exit `1` or `2`, with the report's `reason` under `BLOCKING_ISSUES`.
44
+ - This stage changes no files: report `FILES_CHANGED: none`, `COMMIT: none`, `PUSHED: no`.
45
+
46
+ ## Remediation and close
47
+
48
+ - `OUTCOME: SUCCESS` — close the chore with the run URLs in the close reason. Create nothing.
49
+ - `OUTCOME: BLOCKED` — leave the chore **open**, report the exit status, the reason, and the
50
+ escalation bead id when the script filed one. Build no remediation chain: there is no `stage:fix`
51
+ round that repairs a commit which already merged, and nothing downstream waits on this chore.
52
+ - The escalation bead is the script's to file: one **open** bead per failing run, because the
53
+ `bd list` search behind its marker does not see closed beads, so a run a human already resolved
54
+ can be escalated again. Never file a second one yourself, and never edit or close the one it filed.
@@ -9,7 +9,14 @@
9
9
  - stop further review.
10
10
  3. Invoke `style-code` and `style-tests` for code and test review criteria.
11
11
  4. Review for correctness, requirement alignment, and material quality issues.
12
- 5. Do not request changes for stylistic preferences alone.
12
+ 5. Read the name of every changed test, then find the assertion that proves each clause of it. A
13
+ count in the name needs a count assertion, a state needs that state, and a "not" needs the
14
+ absence. Reject the test when any clause has no assertion, and name the missing clause under
15
+ `BLOCKING_ISSUES`.
16
+ 6. Say in the `SUMMARY` whether the mutation check from `style-tests` was run. A branch that adds
17
+ or changes a test owes that check whether or not the bead asked for it. Block when the branch
18
+ shows no evidence that it ran.
19
+ 7. Do not request changes for stylistic preferences alone.
13
20
 
14
21
  ## Stage Outcome
15
22
 
@@ -18,10 +25,34 @@
18
25
  - If blocked, enumerate required changes under `BLOCKING_ISSUES`.
19
26
  - `FILES_CHANGED` should be `none`.
20
27
 
28
+ ## One defect class per rejection
29
+
30
+ A rejection carries exactly one `defect:<class>` label, from the closed list in the
31
+ `review-defects` skill, plus the specific reason in the rejection text. The label names the kind;
32
+ `BLOCKING_ISSUES` names this instance.
33
+
34
+ ```bash
35
+ bd update <id> --add-label defect:test-unproven
36
+ ```
37
+
38
+ - Apply it to the bead whose work you reject. That bead is normally the code chore, which the
39
+ code stage already closed; the label attaches to it all the same, so the queries in
40
+ `review-defects` pass `--all` and a query without the flag finds nothing. Two findings of
41
+ different kinds are two `BLOCKING_ISSUES` entries and one label: the class of the finding that
42
+ must be fixed first.
43
+ - A class that is not on the closed list is a review defect in itself. Say so under
44
+ `BLOCKING_ISSUES` and use the nearest real class — never invent a `defect:` label.
45
+ - The review that confirms the fix removes the label
46
+ (`bd update <id> --remove-label defect:test-unproven`) and records the removal in its trail
47
+ entry. A closed defect is a trail fact, never a second class.
48
+
49
+ A test whose name outruns its assertions is `defect:test-unproven`; a test that would pass against
50
+ a broken implementation is `defect:test-cannot-fail`.
51
+
21
52
  ## Remediation and close
22
53
 
23
- - You own this leaf bead: append notes, write the progress log, and `bd close <id> --reason=...`
24
- on both outcomes (see `prompts/stage-runner.md`).
54
+ - You own this leaf bead: record the trail entry through `scripts/trail-entry.mjs`, then
55
+ `bd close <id> --reason=...` on both outcomes (see `prompts/stage-runner.md`, _Trail entries_).
25
56
  - `OUTCOME: SUCCESS` — create nothing; the orchestrator routes to `document`.
26
57
  - `OUTCOME: BLOCKED` — count the parent's existing `stage:fix` children against
27
58
  `maxFixRounds` in `skills/planning/create-task/pipeline.json`. Under cap, create a
@@ -15,8 +15,8 @@
15
15
 
16
16
  ## Remediation and close
17
17
 
18
- - You own this leaf bead: append notes, write the progress log, and `bd close <id> --reason=...`
19
- on both outcomes (see `prompts/stage-runner.md`). This is the stage that most often fails —
18
+ - You own this leaf bead: record the trail entry through `scripts/trail-entry.mjs`, then
19
+ `bd close <id> --reason=...` on both outcomes (see `prompts/stage-runner.md`, _Trail entries_). This is the stage that most often fails —
20
20
  closing it is not a failure of the pipeline.
21
21
  - `OUTCOME: SUCCESS` — create nothing; the orchestrator routes to `review`.
22
22
  - `OUTCOME: BLOCKED` — count the parent's existing `stage:fix` children against
@@ -13,20 +13,56 @@ Run `bd prime` if you need project-level context (conventions, tech stack, goals
13
13
  ## Prior stage context (if any)
14
14
  <prior REPORT fields, dependency context, and relevant files>
15
15
 
16
- ## Progress log
17
- Write progress to: `.agent-cortex/ralph/ralph-<bead-id>.log`
18
-
19
- ## Milestone notes
16
+ ## Trail entries
20
17
  The bead's notes are the recovery contract — a fresh session must be able to resume from
21
- `bd show <id>` alone. Append a short checkpoint before starting and at each milestone:
18
+ `bd show <id>` alone. One script writes that trail: run it at stage start, at each milestone, and
19
+ at stage close.
22
20
 
23
21
  ```bash
24
- bd update <id> --append-notes "[<ISO-timestamp>] [<stage>] <what changed / what's next>"
22
+ node <run-pipeline-stage-scripts>/trail-entry.mjs \
23
+ --bead <id> --stage <stage> --outcome <done|blocked|partial> \
24
+ --evidence "<test or lint result, commit, command output>" \
25
+ --remaining "<what is left, or none>" \
26
+ [--commit <ref>] [--branch <branch>] [--pr <url>] [--work-id <worktree-id>]
25
27
  ```
26
28
 
27
- Use `--append-notes` — plain `--notes` overwrites the trail. Record start, milestones, decisions
28
- (with rejected options), blocks, and discoveries. One or two lines per entry: a checkpoint trail,
29
- not a transcript.
29
+ `<run-pipeline-stage-scripts>` is the absolute path to
30
+ `skills/workflow/run-pipeline-stage/scripts/`, resolved from wherever that skill was loaded — never
31
+ hardcode one harness's install path.
32
+
33
+ Every entry carries three mandatory fields:
34
+
35
+ - **Outcome** — `done`, `blocked` or `partial`. A fixed vocabulary, never prose.
36
+ - **Evidence** — what proves it: a test or lint result, the commit SHA, or command output.
37
+ - **What is left** — the next concrete action, or `none`.
38
+
39
+ `--commit` takes any ref — `HEAD`, a short SHA, a branch — and the script resolves it to the full
40
+ 40-character lowercase SHA before recording, because `bd provenance record --ref-kind git-sha`
41
+ refuses anything else. Refs you pass are also recorded as provenance events, visible with
42
+ `bd provenance log <id>`.
43
+
44
+ Run it at each transition instead of writing notes by hand: one entry per transition, decisions and
45
+ blocks included. Recording is idempotent for one worker, so a repeated fire appends nothing
46
+ twice, and a transient database failure is retried. It is not safe under concurrent writers —
47
+ `bd note` has no conditional append — so one worker fires each transition. There is no progress
48
+ file: the bead is the only trail.
49
+
50
+ ### Reading the trail
51
+
52
+ To pick up a bead you did not write — a resumed session, a handoff, a fix round — run the recovery
53
+ brief before anything else:
54
+
55
+ ```bash
56
+ node <run-pipeline-stage-scripts>/recover-brief.mjs --bead <id>
57
+ ```
58
+
59
+ It prints status and state labels, the newest trail entries with their Evidence and What is left,
60
+ the provenance refs, the blocking dependencies, and the acceptance criteria, bounded to about 40
61
+ lines. `bd show` prints the whole note — 89 lines and about 6.5 KB for a bare bead carrying 20
62
+ entries, about 120 lines and about 8 KB for a realistic one with acceptance criteria, a blocker,
63
+ provenance refs and a description — so reach for it only when you need an entry the brief's window
64
+ left out. The brief only reads: every `bd` call is a read subcommand carrying `--readonly`, so it
65
+ never writes to the tracker.
30
66
 
31
67
  ## Leaf bead lifecycle (yours to close)
32
68
 
@@ -38,10 +74,25 @@ not a transcript.
38
74
  ```
39
75
  The outcome lives in the close reason, the milestone notes, and the REPORT. A closed bead
40
76
  with a `BLOCKED` reason is a completed stage, not abandoned work.
77
+
78
+ **Exception — `housekeeping`.** It closes its bead only when the pruner removed every
79
+ `closed-bead` worktree. On `BLOCKED` it leaves the bead **open** and builds nothing (see
80
+ _Remediation_ below). **Exception — `post-merge`.** It closes its bead on exit `0` and leaves it
81
+ **open** on exit `1` or `2`, where the check reported a failed or inconclusive run.
41
82
  3. **Do not create the next stage on success.** Routing forward is the orchestrator's job.
42
83
 
43
84
  ## Remediation (only when your outcome is BLOCKED)
44
85
 
86
+ **Exception — `housekeeping` builds nothing.** It changes no files and sits last in the chain, so a
87
+ `stage:fix` chore and a fresh instance have nothing to repair and nothing to re-block. It leaves its
88
+ bead open, reports `OUTCOME: BLOCKED` with the surviving worktrees, and hands the chore to a human.
89
+ Every step below applies to every other stage.
90
+
91
+ **Exception — `post-merge` builds nothing.** It verified a commit that already merged, so a fix
92
+ round has nothing to repair and no later stage to re-block. It leaves its chore open, reports
93
+ `OUTCOME: BLOCKED` with the check's reason, and names the P1 escalation bead the check filed when
94
+ the run failed. Every step below applies to every other stage.
95
+
45
96
  A fresh instance of this stage is required: the bead you are closing cannot re-run itself.
46
97
 
47
98
  1. **Cap check.** Read `maxFixRounds` from `skills/planning/create-task/pipeline.json` and count
@@ -89,6 +140,11 @@ dirty worktree counts as a failed stage whatever the outcome line claims.
89
140
  3. Report `COMMIT`, `PUSHED`, and `PR`. The `document` stage also opens or updates the feature PR
90
141
  and reports its URL; every earlier stage reports `PR: none`.
91
142
 
143
+ **Exception — `housekeeping`.** It changes no files, so it commits and pushes nothing. Report
144
+ `COMMIT: none` and `PUSHED: no` with `OUTCOME: SUCCESS`; never create an empty commit.
145
+ **Exception — `post-merge`.** It changes no files either: always report `COMMIT: none` and
146
+ `PUSHED: no`, whatever the check's exit status.
147
+
92
148
  ## Instructions
93
149
  1. Read and follow the playbook file listed above.
94
150
  2. Treat the bead as the source-of-truth specification (not a prompt script).
@@ -101,7 +157,7 @@ End your response with a `---REPORT---` block in exactly this format:
101
157
  ```
102
158
  ---REPORT---
103
159
  BEAD_ID: <id>
104
- STAGE_COMPLETED: <code|verify|review|document|fix>
160
+ STAGE_COMPLETED: <code|verify|review|document|post-merge|housekeeping|fix>
105
161
  SUMMARY: <2-3 sentence summary of what was done>
106
162
  FILES_CHANGED: <comma-separated list, or "none">
107
163
  COMMIT: <sha of the stage commit, or "none">