@jaybeeuu/agent-cortex 2.7.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 (56) hide show
  1. package/CHANGELOG.md +239 -0
  2. package/README.md +61 -5
  3. package/agents/README.md +2 -2
  4. package/agents/ralph/agent.md +17 -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 +20 -1
  8. package/extensions/post-merge-watch/README.md +133 -0
  9. package/extensions/post-merge-watch/index.test.ts +247 -0
  10. package/extensions/post-merge-watch/index.ts +123 -0
  11. package/extensions/post-merge-watch/package.json +16 -0
  12. package/extensions/post-merge-watch/watch.test.ts +469 -0
  13. package/extensions/post-merge-watch/watch.ts +431 -0
  14. package/extensions/session-clear/README.md +74 -0
  15. package/extensions/session-clear/index.test.ts +524 -0
  16. package/extensions/session-clear/index.ts +159 -0
  17. package/extensions/session-clear/package.json +16 -0
  18. package/lib/cli.mjs +42 -1
  19. package/lib/self-update.mjs +553 -0
  20. package/package.json +1 -1
  21. package/skills/engineering/implement-task/SKILL.md +124 -0
  22. package/skills/engineering/tdd/SKILL.md +2 -0
  23. package/skills/planning/create-task/REFERENCE.md +15 -6
  24. package/skills/planning/create-task/SKILL.md +1 -1
  25. package/skills/planning/create-task/pipeline.json +8 -0
  26. package/skills/planning/create-task/scripts/create-chores.mjs +27 -18
  27. package/skills/planning/create-task/templates/code.md +8 -3
  28. package/skills/planning/create-task/templates/document.md +8 -3
  29. package/skills/planning/create-task/templates/fix.md +8 -3
  30. package/skills/planning/create-task/templates/housekeeping.md +8 -4
  31. package/skills/planning/create-task/templates/post-merge.md +67 -0
  32. package/skills/planning/create-task/templates/review.md +8 -3
  33. package/skills/planning/create-task/templates/verify.md +8 -3
  34. package/skills/productivity/bd-tool/SKILL.md +55 -0
  35. package/skills/review/review-defects/EXAMPLES.md +122 -0
  36. package/skills/review/review-defects/SKILL.md +91 -0
  37. package/skills/style/style-tests/EXAMPLES.md +30 -0
  38. package/skills/style/style-tests/SKILL.md +10 -6
  39. package/skills/workflow/plan/SKILL.md +14 -3
  40. package/skills/workflow/ralph/REFERENCE.md +124 -27
  41. package/skills/workflow/ralph/SKILL.md +24 -15
  42. package/skills/workflow/ralph/scripts/post-merge-check.mjs +651 -0
  43. package/skills/workflow/run-pipeline-stage/SKILL.md +37 -22
  44. package/skills/workflow/run-pipeline-stage/playbooks/code.md +14 -8
  45. package/skills/workflow/run-pipeline-stage/playbooks/document.md +2 -2
  46. package/skills/workflow/run-pipeline-stage/playbooks/fix.md +2 -2
  47. package/skills/workflow/run-pipeline-stage/playbooks/housekeeping.md +1 -1
  48. package/skills/workflow/run-pipeline-stage/playbooks/post-merge.md +54 -0
  49. package/skills/workflow/run-pipeline-stage/playbooks/review.md +34 -3
  50. package/skills/workflow/run-pipeline-stage/playbooks/verify.md +2 -2
  51. package/skills/workflow/run-pipeline-stage/prompts/stage-runner.md +55 -11
  52. package/skills/workflow/run-pipeline-stage/scripts/recover-brief.mjs +805 -0
  53. package/skills/workflow/run-pipeline-stage/scripts/trail-entry.mjs +702 -0
  54. package/skills/workflow/using-agent-skills/SKILL.md +15 -7
  55. package/token-map.README.md +27 -0
  56. package/token-map.json +10 -4
@@ -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, 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".
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: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` is the single exception: it never closes its bead over a worktree the pruner did not remove, and it builds no remediation children. 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 (`housekeeping` excepted: it leaves its bead open), 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,8 +58,10 @@ 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 |
61
62
  | `housekeeping` | `OUTCOME: SUCCESS` | Create nothing — this is the last stage; its closed chore ends the pipeline |
62
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 |
63
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 |
64
66
  | any | parent status `blocked` | Nothing — the worker or the cap backstop blocked it; record it for shutdown |
65
67
 
@@ -81,32 +83,46 @@ On `OUTCOME: BLOCKED` the worker creates its own chain — a `stage:fix` chore c
81
83
  | `document` | `stage:fix` → fresh `stage:document` |
82
84
  | `fix` | `stage:fix` → fresh `stage:fix` |
83
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 |
84
87
 
85
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.
86
89
 
87
- ## Progress Logging
90
+ ## Trail Entries
88
91
 
89
- 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.
90
93
 
91
- ```
92
- [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>]
93
100
  ```
94
101
 
95
- 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:
96
103
 
97
- ```bash
98
- 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
99
- ```
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`.
100
107
 
101
- ## 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.
102
109
 
103
- 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.
104
117
 
105
118
  ```bash
106
- 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]
107
121
  ```
108
122
 
109
- `--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.
110
126
 
111
127
  ## Report Format
112
128
 
@@ -115,7 +131,7 @@ Every stage-runner prompt ends with the literal REPORT instruction (see `prompts
115
131
  ```
116
132
  ---REPORT---
117
133
  BEAD_ID: <id>
118
- STAGE_COMPLETED: <code|verify|review|document|housekeeping|fix>
134
+ STAGE_COMPLETED: <code|verify|review|document|post-merge|housekeeping|fix>
119
135
  SUMMARY: <2-3 sentence summary of what was done>
120
136
  FILES_CHANGED: <comma-separated list, or "none">
121
137
  COMMIT: <sha of the stage commit, or "none">
@@ -154,9 +170,9 @@ stage: the commit is the evidence, the report is the claim.
154
170
 
155
171
  - [create-task](../../planning/create-task/SKILL.md) — owns `pipeline.json`: stages, `maxFixRounds`, and the stage templates.
156
172
  - [bd-tool](../../productivity/bd-tool/SKILL.md) — bead mechanics beyond the commands used here.
157
- - [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.
158
174
 
159
- 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.
160
176
 
161
177
  ## Examples
162
178
 
@@ -175,6 +191,5 @@ Each playbook delegates to a stage skill: `tdd`/`style-code`/`style-tests` (code
175
191
  - [ ] `bd tag <id> stage:<stage>` run before dispatch.
176
192
  - [ ] Correct playbook read and followed for the stage; stage skills invoked where the playbook says.
177
193
  - [ ] Composed prompt carries the lifecycle, remediation, and REPORT contract from `prompts/stage-runner.md`.
178
- - [ ] Progress log lines written for every stage transition and key result.
179
- - [ ] 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.
180
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
@@ -46,7 +46,7 @@ closed beads and changes no files.
46
46
 
47
47
  - **This stage is the exception to close-on-both-outcomes.** Nothing downstream waits on its close,
48
48
  so the bead's own state is the report.
49
- - `OUTCOME: SUCCESS` — append the notes and the progress log, then
49
+ - `OUTCOME: SUCCESS` — record the trail entry, then
50
50
  `bd close <id> --reason="SUCCESS: <removed/kept summary>"`. Create nothing: this is the last stage
51
51
  and its closed chore ends the pipeline.
52
52
  - `OUTCOME: BLOCKED` — **do not close the bead.** Leave it open: return it to `open` status
@@ -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.
20
+
21
+ ```bash
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>]
27
+ ```
28
+
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:
22
54
 
23
55
  ```bash
24
- bd update <id> --append-notes "[<ISO-timestamp>] [<stage>] <what changed / what's next>"
56
+ node <run-pipeline-stage-scripts>/recover-brief.mjs --bead <id>
25
57
  ```
26
58
 
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.
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
 
@@ -41,7 +77,8 @@ not a transcript.
41
77
 
42
78
  **Exception — `housekeeping`.** It closes its bead only when the pruner removed every
43
79
  `closed-bead` worktree. On `BLOCKED` it leaves the bead **open** and builds nothing (see
44
- _Remediation_ below).
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.
45
82
  3. **Do not create the next stage on success.** Routing forward is the orchestrator's job.
46
83
 
47
84
  ## Remediation (only when your outcome is BLOCKED)
@@ -51,6 +88,11 @@ not a transcript.
51
88
  bead open, reports `OUTCOME: BLOCKED` with the surviving worktrees, and hands the chore to a human.
52
89
  Every step below applies to every other stage.
53
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
+
54
96
  A fresh instance of this stage is required: the bead you are closing cannot re-run itself.
55
97
 
56
98
  1. **Cap check.** Read `maxFixRounds` from `skills/planning/create-task/pipeline.json` and count
@@ -100,6 +142,8 @@ dirty worktree counts as a failed stage whatever the outcome line claims.
100
142
 
101
143
  **Exception — `housekeeping`.** It changes no files, so it commits and pushes nothing. Report
102
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.
103
147
 
104
148
  ## Instructions
105
149
  1. Read and follow the playbook file listed above.
@@ -113,7 +157,7 @@ End your response with a `---REPORT---` block in exactly this format:
113
157
  ```
114
158
  ---REPORT---
115
159
  BEAD_ID: <id>
116
- STAGE_COMPLETED: <code|verify|review|document|housekeeping|fix>
160
+ STAGE_COMPLETED: <code|verify|review|document|post-merge|housekeeping|fix>
117
161
  SUMMARY: <2-3 sentence summary of what was done>
118
162
  FILES_CHANGED: <comma-separated list, or "none">
119
163
  COMMIT: <sha of the stage commit, or "none">