@jaybeeuu/agent-cortex 2.1.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (181) hide show
  1. package/CHANGELOG.md +411 -0
  2. package/README.md +33 -13
  3. package/agents/README.md +22 -10
  4. package/agents/plan/agent.md +2 -2
  5. package/agents/ralph/agent.md +126 -88
  6. package/agents/ralph/claude/frontmatter.json +3 -3
  7. package/agents/ralph/claude/wake.md +46 -0
  8. package/agents/ralph/pi/{polling.md → wake.md} +35 -20
  9. package/agents/ralph-plan/agent.md +23 -11
  10. package/bin/agent-cortex.mjs +66 -4
  11. package/bin/installers/claude.mjs +182 -68
  12. package/bin/installers/pi.mjs +200 -24
  13. package/extensions/agent-guardrails/README.md +1 -1
  14. package/extensions/agent-guardrails/guardrails.ts +1 -1
  15. package/extensions/agent-guardrails/index.ts +1 -1
  16. package/extensions/agent-modes/discover.test.ts +2 -2
  17. package/extensions/output-style/README.md +1 -1
  18. package/extensions/output-style/index.ts +2 -2
  19. package/extensions/output-style/output-style.ts +2 -2
  20. package/hooks/claude/scripts/notify.mjs +8 -1
  21. package/lib/cli.mjs +91 -2
  22. package/package.json +27 -3
  23. package/scripts/check-changeset.mjs +4 -0
  24. package/scripts/check-no-sync.mjs +5 -1
  25. package/scripts/lib/compose-agent.mjs +69 -9
  26. package/scripts/lib/fs.mjs +10 -2
  27. package/scripts/lib/migrate.mjs +736 -0
  28. package/scripts/lib/release-gates.mjs +21 -1
  29. package/scripts/lib/skill-frontmatter.mjs +23 -6
  30. package/scripts/lib/skill-links.mjs +52 -0
  31. package/scripts/lib/verify-worker-tree.mjs +25 -0
  32. package/scripts/resolve-publish-command.mjs +4 -0
  33. package/skills/engineering/design-an-interface/SKILL.md +3 -3
  34. package/skills/engineering/grill-with-docs/SKILL.md +3 -5
  35. package/skills/engineering/improve-codebase-architecture/SKILL.md +5 -4
  36. package/skills/engineering/tdd/SKILL.md +5 -7
  37. package/skills/engineering/technical-direction/SKILL.md +5 -5
  38. package/skills/planning/classify-bead/REFERENCE.md +3 -3
  39. package/skills/planning/classify-bead/SKILL.md +14 -9
  40. package/skills/planning/classify-bead/scripts/classify-bead.mjs +5 -4
  41. package/skills/planning/create-task/REFERENCE.md +52 -3
  42. package/skills/planning/create-task/SKILL.md +70 -26
  43. package/skills/planning/create-task/scripts/{create-chores.ts → create-chores.mjs} +48 -23
  44. package/skills/planning/flesh-out-idea/REFERENCE.md +116 -0
  45. package/skills/planning/flesh-out-idea/SKILL.md +146 -0
  46. package/skills/planning/prd-to-tasks/REFERENCE.md +54 -5
  47. package/skills/planning/prd-to-tasks/SKILL.md +22 -16
  48. package/skills/planning/record-idea/FORMAT.md +66 -17
  49. package/skills/planning/record-idea/SKILL.md +48 -24
  50. package/skills/planning/request-refactor-plan/SKILL.md +4 -4
  51. package/skills/planning/spec-to-tickets/SKILL.md +5 -5
  52. package/skills/planning/write-a-prd/SKILL.md +8 -9
  53. package/skills/planning/write-a-ticket/SKILL.md +4 -6
  54. package/skills/productivity/bd-tool/SKILL.md +15 -10
  55. package/skills/productivity/grill-me/SKILL.md +5 -0
  56. package/skills/productivity/init-beads/SKILL.md +3 -3
  57. package/skills/productivity/migration/REFERENCE.md +227 -0
  58. package/skills/productivity/migration/SKILL.md +188 -0
  59. package/skills/productivity/validate-agent-dir/scripts/{validate-agent-dir.ts → validate-agent-dir.mjs} +49 -28
  60. package/skills/productivity/write-a-skill/SKILL.md +5 -5
  61. package/skills/review/maintain-agent-docs/SKILL.md +5 -7
  62. package/skills/review/refactor-skill/SKILL.md +4 -3
  63. package/skills/review/review-security/SKILL.md +3 -5
  64. package/skills/style/style-code/SKILL.md +5 -10
  65. package/skills/style/style-comms/SKILL.md +5 -7
  66. package/skills/style/style-documentation/SKILL.md +5 -6
  67. package/skills/style/style-tests/SKILL.md +5 -7
  68. package/skills/workflow/git-workflow/SKILL.md +52 -26
  69. package/skills/workflow/hitl-collab/SKILL.md +4 -6
  70. package/skills/workflow/plan/SKILL.md +41 -30
  71. package/skills/workflow/ralph/REFERENCE.md +182 -51
  72. package/skills/workflow/ralph/SKILL.md +89 -50
  73. package/skills/workflow/run-pipeline-stage/SKILL.md +72 -71
  74. package/skills/workflow/run-pipeline-stage/playbooks/code.md +11 -0
  75. package/skills/workflow/run-pipeline-stage/playbooks/document.md +12 -0
  76. package/skills/workflow/run-pipeline-stage/playbooks/fix.md +12 -0
  77. package/skills/workflow/run-pipeline-stage/playbooks/review.md +11 -0
  78. package/skills/workflow/run-pipeline-stage/playbooks/verify.md +13 -0
  79. package/skills/workflow/run-pipeline-stage/prompts/stage-runner.md +73 -1
  80. package/token-map.README.md +9 -4
  81. package/token-map.json +13 -6
  82. package/.agents/skills/style-versioning/SKILL.md +0 -172
  83. package/.changeset/README.md +0 -8
  84. package/.changeset/config.json +0 -11
  85. package/.github/workflows/ci.yml +0 -302
  86. package/.junie/guidelines.md +0 -87
  87. package/.junie/mcp/mcp.json +0 -10
  88. package/AGENTS.md +0 -153
  89. package/agents/ralph/claude/polling.md +0 -31
  90. package/agents-native/ralph.md +0 -203
  91. package/docs/claude-hooks.md +0 -144
  92. package/docs/commit-signing.md +0 -231
  93. package/docs/ideas/auto-model-selection.md +0 -75
  94. package/docs/ideas/ban-content-assertion-tests.md +0 -75
  95. package/docs/ideas/bead-progress-notes-for-session-resumption.md +0 -75
  96. package/docs/ideas/classify-beads-via-deterministic-script-with-agent-fallback.md +0 -70
  97. package/docs/ideas/ctx-alias-version-and-update-commands.md +0 -65
  98. package/docs/ideas/ctx-feedback-command-for-capturing-ideas-from-any-machine.md +0 -67
  99. package/docs/ideas/dedicated-review-tests-skill.md +0 -71
  100. package/docs/ideas/deployment-beads-for-post-merge-pipelines.md +0 -36
  101. package/docs/ideas/design-and-delivery-as-separate-bead-trees/design-and-delivery-as-separate-bead-trees.md +0 -99
  102. package/docs/ideas/enable-signed-commit-enforcement-changesets-bot-commits-must-be-signed.md +0 -42
  103. package/docs/ideas/extension-manifests.md +0 -121
  104. package/docs/ideas/improve-pi-system-prompt.md +0 -43
  105. package/docs/ideas/map-every-cortex-tool-to-a-real-pi-equivalent.md +0 -95
  106. package/docs/ideas/model-selector.md +0 -40
  107. package/docs/ideas/pi-task-memory.md +0 -34
  108. package/docs/ideas/qa-extension.md +0 -43
  109. package/docs/ideas/record-idea-implementation-questions.md +0 -68
  110. package/docs/ideas/record-ideas-as-beads.md +0 -115
  111. package/docs/ideas/self-flushing-session.md +0 -72
  112. package/docs/ideas/state-in-beads-not-md.md +0 -69
  113. package/docs/ideas/subagent-visibility.md +0 -72
  114. package/docs/ideas/task-session-context.local.md +0 -95
  115. package/docs/ideas/task-session-context.md +0 -89
  116. package/docs/ideas/test-data-creation-helpers.md +0 -92
  117. package/docs/ideas/test-planning-stage-bead-in-feature-planning.md +0 -68
  118. package/docs/ideas/unified-ci-pipeline.md +0 -28
  119. package/docs/ideas/unify-the-ticket-and-task-decomposition-workflows.md +0 -71
  120. package/docs/ideas/worktree-housekeeping-for-closed-beads.md +0 -39
  121. package/docs/inspirations.md +0 -33
  122. package/docs/research/disable-model-invocation.md +0 -82
  123. package/docs/research/gas-city-research.md +0 -256
  124. package/docs/research/skill-design-research.md +0 -286
  125. package/docs/research/skill-improvements-analysis.md +0 -117
  126. package/docs/research/skill-patterns-research.md +0 -24
  127. package/docs/skills/skill-anatomy.md +0 -200
  128. package/docs/technical-direction/harness-config.md +0 -177
  129. package/docs/technical-direction/migration-execution-labels.md +0 -177
  130. package/docs/user-preferences.md +0 -17
  131. package/extensions/agent-guardrails/tsconfig.json +0 -12
  132. package/extensions/agent-modes/tsconfig.json +0 -12
  133. package/extensions/output-style/tsconfig.json +0 -12
  134. package/extensions/session-start/tsconfig.json +0 -12
  135. package/extensions/skill-stats/pnpm-lock.yaml +0 -329
  136. package/extensions/skill-stats/tsconfig.json +0 -12
  137. package/extensions/subagent/agents/planner.md +0 -37
  138. package/extensions/subagent/agents/reviewer.md +0 -35
  139. package/extensions/subagent/agents/scout.md +0 -50
  140. package/extensions/subagent/agents/worker.md +0 -24
  141. package/extensions/subagent/prompts/implement-and-review.md +0 -10
  142. package/extensions/subagent/prompts/implement.md +0 -10
  143. package/extensions/subagent/prompts/scout-and-plan.md +0 -9
  144. package/extensions/subagent/tsconfig.json +0 -12
  145. package/pi/keybindings.json +0 -3
  146. package/pi/settings.json +0 -34
  147. package/pnpm-workspace.yaml +0 -14
  148. package/skills/planning/create-task/scripts/package.json +0 -14
  149. package/skills/planning/create-task/scripts/pnpm-lock.yaml +0 -342
  150. package/skills/planning/create-task/scripts/tsconfig.json +0 -12
  151. package/skills/planning/record-idea/scripts/new-idea.sh +0 -89
  152. package/skills/productivity/validate-agent-dir/scripts/package.json +0 -15
  153. package/skills/productivity/validate-agent-dir/scripts/pnpm-lock.yaml +0 -329
  154. package/skills/productivity/validate-agent-dir/scripts/pnpm-workspace.yaml +0 -2
  155. package/skills/productivity/validate-agent-dir/scripts/tsconfig.json +0 -19
  156. package/skills/productivity/validate-agent-dir/scripts/validate-agent-dir.test.ts +0 -317
  157. package/skills/workflow/run-pipeline-stage/REFERENCE.md +0 -22
  158. package/skills/workflow/run-pipeline-stage/scripts/generate-progress.test.ts +0 -682
  159. package/skills/workflow/run-pipeline-stage/scripts/generate-progress.ts +0 -588
  160. package/skills/workflow/run-pipeline-stage/scripts/package.json +0 -15
  161. package/skills/workflow/run-pipeline-stage/scripts/pnpm-lock.yaml +0 -342
  162. package/skills/workflow/run-pipeline-stage/scripts/pnpm-workspace.yaml +0 -2
  163. package/skills/workflow/run-pipeline-stage/scripts/tsconfig.json +0 -12
  164. package/test/classify-bead.test.mjs +0 -277
  165. package/test/claude-installer.test.mjs +0 -308
  166. package/test/cli.test.mjs +0 -314
  167. package/test/create-chores.test.mjs +0 -85
  168. package/test/fake-bd.test.mjs +0 -72
  169. package/test/fs.test.mjs +0 -76
  170. package/test/helpers/fake-bd.mjs +0 -87
  171. package/test/helpers/fake-claude.mjs +0 -152
  172. package/test/helpers/fake-pi.mjs +0 -132
  173. package/test/installer.test.mjs +0 -806
  174. package/test/notify-hook.test.mjs +0 -63
  175. package/test/pending-gates.test.mjs +0 -147
  176. package/test/pi-installer.test.mjs +0 -785
  177. package/test/pi-register.test.mjs +0 -342
  178. package/test/pi-sweep.test.mjs +0 -619
  179. package/test/release-gates.test.mjs +0 -190
  180. package/test/skill-frontmatter.test.mjs +0 -137
  181. package/test/verify-worker-tree.test.mjs +0 -120
@@ -1,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 dispatch rules, 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) 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`) are created by the `create-task` skill from the pipeline definition in `skills/planning/create-task/pipeline.json`. This skill executes one stage at a time and reports the outcome.
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.
9
9
 
10
10
  ## When to use
11
11
 
@@ -20,65 +20,66 @@ Stage beads (`stage:code`, `stage:verify`, `stage:review`, `stage:document`, `st
20
20
  - Creating or planning beads — use `create-task` or `plan`.
21
21
  - Exploratory bead bookkeeping without a stage — that is `bd-tool`.
22
22
 
23
+ ## Ownership split
24
+
25
+ | Actor | Owns |
26
+ |---|---|
27
+ | Stage runner (worker) | Milestone notes, progress-log lines, closing its leaf bead on both outcomes, remediation children, the REPORT |
28
+ | Orchestrator (ralph or you) | Claim, dispatch, forward routing, the read-only cap backstop, the PR gate |
29
+
30
+ A leaf bead is the worker's record of what happened. The orchestrator reads it; it does not write it.
31
+
23
32
  ## Workflow
24
33
 
25
34
  1. Run `bd prime` and hold the output; subagents can run it themselves if they need context.
26
35
  2. If no bead was specified, run `bd ready` and ask the user which to work on.
27
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_).
28
37
  4. Read the bead's `stage:*` label — it names the stage to execute.
29
- 5. Load the universal stage-runner prompt (`skills/workflow/run-pipeline-stage/prompts/stage-runner.md`), populate `<stage>`, and read the matching playbook (`skills/workflow/run-pipeline-stage/playbooks/<stage>.md`) for stage-specific rules.
30
- 6. Tag the stage and regenerate the progress doc so pairing sessions stay current:
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
+ 6. Tag the stage — beads are the only status view:
31
40
 
32
41
  ```bash
33
42
  bd tag <id> stage:<stage>
34
- # workspace must be the absolute path of the worktree — never . or $(pwd)
35
- workspace="/absolute/path/to/worktree"
36
- pnpm --prefix skills/workflow/run-pipeline-stage/scripts exec tsx generate-progress.ts --workspace "$workspace" > "$workspace/.agent-cortex/ralph/progress.md"
37
43
  ```
38
44
 
39
- 7. Dispatch one subagent per stage with the composed prompt — spawn it with {{TOOL:task}} and end the prompt with the REPORT contract below. A session with no subagent tool cannot dispatch: stop and say so rather than substituting a backgrounded CLI run, which has no completion signal.
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.
40
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.
41
- 9. Route the REPORT through the Dispatch Rules: advance to the next stage, create a feedback bead, or close the parent.
47
+ 9. On the REPORT: route forward per _Routing_ below. Do **not** close the leaf bead — the worker closed it before reporting.
42
48
 
43
- Each step leaves observable state — a claimed bead, a `stage:` tag, a regenerated progress doc, a verified commit, and a REPORT that drives the next action.
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.
44
50
 
45
- ## Dispatch Rules
51
+ ## Routing (read-only)
46
52
 
47
- | Stage complete | Condition | Next action |
48
- |---|---|---|
49
- | `code` | — | Run **verify** |
50
- | `verify` | `OUTCOME: SUCCESS` | Run **review** |
51
- | `verify` | `OUTCOME: BLOCKED` | Create a `stage:fix` chore (see _Feedback Beads_) |
52
- | `review` | `OUTCOME: SUCCESS` | Run **document** |
53
- | `review` | `OUTCOME: BLOCKED` and fixRounds < maxFixRounds | Create a `stage:fix` chore; increment fixRounds |
54
- | `review` | `OUTCOME: BLOCKED` and fixRounds ≥ maxFixRounds | `bd update <parent-id> --status blocked --notes "max fix rounds reached"`; record for shutdown |
55
- | `document` | — | `bd close <id>` — done |
56
-
57
- `maxFixRounds` is read from `skills/planning/create-task/pipeline.json` (currently `4`). A fix chore re-runs the stage that failed — fix after verify → verify; fix after review → review.
53
+ The worker built anything this stage needed; routing picks up whatever `bd ready` returns.
58
54
 
59
- ## Feedback Beads
55
+ | Stage complete | Condition | Next action |
56
+ | `code` | `OUTCOME: SUCCESS` | Dispatch the ready `stage:verify` chore |
57
+ | `verify` | `OUTCOME: SUCCESS` | Dispatch the ready `stage:review` chore |
58
+ | `review` | `OUTCOME: SUCCESS` | Dispatch the ready `stage:document` chore |
59
+ | `fix` | `OUTCOME: SUCCESS` | Dispatch the ready re-run chore that was blocked on the fix |
60
+ | `document` | `OUTCOME: SUCCESS` | Open/update the feature PR and the HITL gate bead |
61
+ | `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 |
62
+ | any | parent status `blocked` | Nothing — the worker or the cap backstop blocked it; record it for shutdown |
60
63
 
61
- On stage failure, create a chore bead whose description carries the feedback so the orchestrator's dispatch path stays uniform — it just picks up whatever `bd ready` returns:
64
+ 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:
62
65
 
63
66
  ```bash
64
- new_id=$(bd create "[<parent-id>] <title>" --type chore \
65
- --description "Requirements: see <parent-id> acceptance criteria (`bd show <parent-id>`).
66
-
67
- <feedback content from REPORT>" --priority <parent-priority> -q)
68
- bd tag $new_id stage:<next-stage>
69
- bd tag $new_id workflow:ralph
70
- bd dep add $new_id <parent-id> --type parent-child
67
+ fix_rounds=$(bd children <parent-id> --json | grep -c '"stage:fix"')
71
68
  ```
72
69
 
73
- Chore beads carry no required sections, so the feedback description must point at the
74
- parent/requirements bead (`<parent-id>`) rather than restating its acceptance criteria.
70
+ ## Remediation Children (worker-built)
71
+
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.
75
73
 
76
- | Triggering outcome | Suggested title | Next stage tag | Description content |
77
- |---|---|---|---|
78
- | `OUTCOME: BLOCKED` from verify | `Fix: verify failures` | `stage:code` | Full BLOCKING_ISSUES list |
79
- | `OUTCOME: BLOCKED` from review | `Fix: reviewer feedback` | `stage:fix` | Full BLOCKING_ISSUES list |
74
+ | Failed stage | Chain |
75
+ |---|---|
76
+ | `code` | `stage:fix` → fresh `stage:code` |
77
+ | `verify` | `stage:fix` → fresh `stage:verify` |
78
+ | `review` | `stage:fix` → fresh `stage:review` |
79
+ | `document` | `stage:fix` → fresh `stage:document` |
80
+ | `fix` | `stage:fix` → fresh `stage:fix` |
80
81
 
81
- Do not dispatch a new agent right after creating the feedback bead — it appears in `bd ready` on the next cycle and flows through the normal scheduling path.
82
+ 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.
82
83
 
83
84
  ## Progress Logging
84
85
 
@@ -106,23 +107,21 @@ bd update <id> --append-notes "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] [<stage>] <what
106
107
 
107
108
  ## Report Format
108
109
 
109
- Every subagent prompt must end with the REPORT instruction:
110
-
111
- > End your response with a `---REPORT---` block in exactly this format:
112
- > ```
113
- > ---REPORT---
114
- > BEAD_ID: <id>
115
- > STAGE_COMPLETED: <code|verify|review|document>
116
- > SUMMARY: <2-3 sentence summary of what was done>
117
- > FILES_CHANGED: <comma-separated list, or "none">
118
- > COMMIT: <sha of the stage commit, or "none">
119
- > PUSHED: <yes|no>
120
- > PR: <feature PR url, or "none">
121
- > OUTCOME: <SUCCESS|BLOCKED>
122
- > BLOCKING_ISSUES: ← only if OUTCOME is BLOCKED
123
- > - <specific blocking issue>
124
- > ---
125
- > ```
110
+ Every stage-runner prompt ends with the literal REPORT instruction (see `prompts/stage-runner.md`):
111
+
112
+ ```
113
+ ---REPORT---
114
+ BEAD_ID: <id>
115
+ STAGE_COMPLETED: <code|verify|review|document|fix>
116
+ SUMMARY: <2-3 sentence summary of what was done>
117
+ FILES_CHANGED: <comma-separated list, or "none">
118
+ COMMIT: <sha of the stage commit, or "none">
119
+ PUSHED: <yes|no>
120
+ PR: <feature PR url, or "none">
121
+ OUTCOME: <SUCCESS|BLOCKED>
122
+ BLOCKING_ISSUES: ← only if OUTCOME is BLOCKED
123
+ - <specific blocking issue>
124
+ ```
126
125
 
127
126
  Subagents report facts — do not ask them to suggest or predict the next step. A REPORT claiming
128
127
  `OUTCOME: SUCCESS` with `PUSHED: no`, or a `COMMIT` that is not on the branch, records a failed
@@ -131,8 +130,9 @@ stage: the commit is the evidence, the report is the claim.
131
130
  ## Red Flags
132
131
 
133
132
  - Dispatching a subagent before tagging the stage — beads are the only source of truth for stage progress.
133
+ - Closing a leaf bead from the orchestrator — the worker closed it; a second close hides who owned the outcome.
134
+ - Creating a feedback or fix bead from the orchestrator — that is the worker's contract and bypasses its cap accounting.
134
135
  - Composing a subagent prompt without the REPORT contract — the output cannot be routed.
135
- - Creating a feedback bead and then dispatching anyway — bypasses the fix-round accounting and parent-child dependency graph.
136
136
  - Skipping the playbook "because the stage is simple" — playbooks carry the per-stage discipline the pipeline relies on.
137
137
  - Advancing on `OUTCOME: SUCCESS` without verifying the worktree — the commit is the evidence, the report is the claim.
138
138
  - Leaving bead notes to the end of the stage — a session that dies mid-stage then loses the whole trail.
@@ -140,34 +140,35 @@ stage: the commit is the evidence, the report is the claim.
140
140
  ## Common Rationalizations
141
141
 
142
142
  | "The stage is small — I'll just run it directly" | The stage skills and playbook keep output conformant; skipping them produces work that loops back as a fix chore. |
143
- | "I'll dispatch the fix right away — faster than a chore bead" | Feedback beads keep dispatch uniform and durable; direct re-dispatch breaks fix-round accounting and the dependency graph. |
144
- | "The stage is obvious from the prompt — no tag needed" | Beads are the source of truth; prompt drift desynchronises the progress doc, the log, and downstream dispatch. |
143
+ | "I'll close the chore — the worker forgot" | The worker closing it is the contract; an unclosed bead means the worker died, so read its notes and re-dispatch, do not paper over it. |
144
+ | "I'll wire the fix chain myself — faster" | Two owners of one lifecycle is what this skill exists to remove; worker-built chains keep cap accounting and the dependency graph truthful. |
145
+ | "The stage is obvious from the prompt — no tag needed" | Beads are the source of truth; prompt drift desynchronises the log and downstream dispatch. |
146
+
147
+ ## See Also
145
148
 
146
- ## Cross-skill references
149
+ - [create-task](../../planning/create-task/SKILL.md) — owns `pipeline.json`: stages, `maxFixRounds`, and the stage templates.
150
+ - [bd-tool](../../productivity/bd-tool/SKILL.md) — bead mechanics beyond the commands used here.
151
+ - [ralph](../ralph/SKILL.md) — runs many stage beads concurrently and consumes this skill's log and REPORT contracts.
147
152
 
148
- - `create-task` owns `pipeline.json` — stages, `maxFixRounds`, and the stage templates.
149
- - `bd-tool` covers bead mechanics beyond the commands in this skill.
150
- - `ralph` runs many stage beads concurrently and consumes this skill's log and REPORT contracts.
151
- - Playbooks delegate to stage skills: `tdd`/`style-code`/`style-tests` (code), `review-security` (review), `style-documentation` (document).
153
+ Each playbook delegates to a stage skill: `tdd`/`style-code`/`style-tests` (code, fix), `review-security` (review), `style-documentation` (document).
152
154
 
153
155
  ## Examples
154
156
 
155
- - Input: a `stage:verify` bead reporting `OUTCOME: BLOCKED` with two failing tests → Output: a `Fix: verify failures` chore tagged `stage:code` whose description lists both failures; verify closes and the chore is picked up on the next `bd ready` cycle.
156
- - Input: a `stage:document` bead reporting `OUTCOME: SUCCESS` → Output: the parent bead is closed with `bd close <id>` and that task's pipeline ends.
157
+ - Input: a `stage:verify` runner reporting `OUTCOME: BLOCKED` with two failing tests → Output: a `Fix (round 1)` chore plus a fresh `Verify (re-run 1)` chore blocked on it, `review` re-blocked behind the fresh verify, verify's own bead closed, and one `---REPORT---` block.
158
+ - Input: a `stage:document` runner reporting `OUTCOME: SUCCESS` → Output: document's bead already closed by the runner; the orchestrator opens the feature PR and updates the HITL gate bead.
157
159
 
158
160
  ## Philosophy / rationale
159
161
 
160
162
  - Beads hold all orchestration state — there is no separate state file to drift out of sync.
161
- - Subagents return facts in one fixed REPORT shape so routing stays mechanical across stages and harnesses.
162
- - Feedback as beads, not direct re-dispatches, puts every agent on a single scheduling path and keeps every decision visible in the dependency graph.
163
+ - Whoever does the work owns the record: a worker that closes its own bead leaves an auditable trail the orchestrator can only read.
164
+ - Self-contained remediation keeps the dependency graph truthful, so `bd ready` alone is enough to schedule the next step.
163
165
 
164
166
  ## Verification checklist
165
167
 
166
168
  - [ ] Bead claimed (`bd update <id> --claim`) before any executor works it.
167
- - [ ] `bd tag <id> stage:<stage>` run and progress doc regenerated before dispatch.
169
+ - [ ] `bd tag <id> stage:<stage>` run before dispatch.
168
170
  - [ ] Correct playbook read and followed for the stage; stage skills invoked where the playbook says.
169
- - [ ] Composed prompt ends with the complete REPORT contract block.
171
+ - [ ] Composed prompt carries the lifecycle, remediation, and REPORT contract from `prompts/stage-runner.md`.
170
172
  - [ ] Progress log lines written for every stage transition and key result.
171
173
  - [ ] Milestone notes appended at stage start and each milestone with `--append-notes` (not `--notes`).
172
- - [ ] REPORT routed per the Dispatch Rules — next stage, feedback bead, or `bd close <id>`.
173
- - [ ] Feedback beads carry the full BLOCKING_ISSUES content and the parent-child dependency.
174
+ - [ ] The orchestrator closed no leaf bead and created no fix bead; the cap backstop ran before any dispatch.
@@ -16,4 +16,15 @@
16
16
  - Set `OUTCOME: BLOCKED` if tests fail or requirements cannot be met.
17
17
  - If blocked, list issues under `BLOCKING_ISSUES`.
18
18
  - `FILES_CHANGED` lists all modified source/test files.
19
+
20
+ ## Remediation and close
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`).
24
+ - `OUTCOME: SUCCESS` — create nothing; the orchestrator routes to `verify`.
25
+ - `OUTCOME: BLOCKED` — count the parent's existing `stage:fix` children against
26
+ `maxFixRounds` in `skills/planning/create-task/pipeline.json`. Under cap, create a
27
+ `stage:fix` chore **plus a fresh `stage:code` chore** blocked on it (`bd dep add <fresh>
28
+ <fix> --type blocks`), and re-block later stages behind the fresh bead. At cap, block the
29
+ parent and create nothing.
19
30
  - Report `COMMIT`, `PUSHED`, and `PR` (`PR: none` outside the document stage).
@@ -18,4 +18,16 @@
18
18
  - Set `OUTCOME: BLOCKED` if unable to update or content guidance is unclear.
19
19
  - If blocked, list issues under `BLOCKING_ISSUES`.
20
20
  - `FILES_CHANGED` lists docs touched, or `none` if no doc change is needed.
21
+
22
+ ## Remediation and close
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`).
26
+ - `OUTCOME: SUCCESS` — create nothing; the orchestrator opens the feature PR and updates the
27
+ HITL gate bead.
28
+ - `OUTCOME: BLOCKED` — count the parent's existing `stage:fix` children against
29
+ `maxFixRounds` in `skills/planning/create-task/pipeline.json`. Under cap, create a
30
+ `stage:fix` chore **plus a fresh `stage:document` chore** blocked on it
31
+ (`bd dep add <fresh> <fix> --type blocks`) so documentation is retried after the fix. At cap,
32
+ block the parent and create nothing.
21
33
  - Report `COMMIT`, `PUSHED`, and the feature `PR` URL.
@@ -16,4 +16,16 @@
16
16
  - Set `OUTCOME: BLOCKED` if unable to apply changes or guidance is unclear.
17
17
  - If blocked, list issues under `BLOCKING_ISSUES`.
18
18
  - `FILES_CHANGED` lists files updated to address requested changes.
19
+
20
+ ## Remediation and close
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`).
24
+ - `OUTCOME: SUCCESS` — create nothing; closing this bead unblocks the fresh stage chore that
25
+ was wired behind it.
26
+ - `OUTCOME: BLOCKED` — count the parent's existing `stage:fix` children against
27
+ `maxFixRounds` in `skills/planning/create-task/pipeline.json`. Under cap, create another
28
+ `stage:fix` chore carrying what remains **plus a fresh `stage:fix` chore** blocked on it
29
+ (`bd dep add <fresh> <fix> --type blocks`) and leave the downstream re-run chore blocked on
30
+ the fresh fix. At cap, block the parent and create nothing.
19
31
  - Report `COMMIT`, `PUSHED`, and `PR` (`PR: none`).
@@ -17,3 +17,14 @@
17
17
  - Set `OUTCOME: BLOCKED` if changes are requested.
18
18
  - If blocked, enumerate required changes under `BLOCKING_ISSUES`.
19
19
  - `FILES_CHANGED` should be `none`.
20
+
21
+ ## Remediation and close
22
+
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`).
25
+ - `OUTCOME: SUCCESS` — create nothing; the orchestrator routes to `document`.
26
+ - `OUTCOME: BLOCKED` — count the parent's existing `stage:fix` children against
27
+ `maxFixRounds` in `skills/planning/create-task/pipeline.json`. Under cap, create a
28
+ `stage:fix` chore carrying the full `BLOCKING_ISSUES` list **plus a fresh `stage:review`
29
+ chore** blocked on it (`bd dep add <fresh> <fix> --type blocks`), and re-block `document`
30
+ behind the fresh bead. At cap, block the parent and create nothing.
@@ -12,3 +12,16 @@
12
12
  - Set `OUTCOME: BLOCKED` when any command fails.
13
13
  - If blocked, summarize failures under `BLOCKING_ISSUES`.
14
14
  - `FILES_CHANGED` should be `none`.
15
+
16
+ ## Remediation and close
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 —
20
+ closing it is not a failure of the pipeline.
21
+ - `OUTCOME: SUCCESS` — create nothing; the orchestrator routes to `review`.
22
+ - `OUTCOME: BLOCKED` — count the parent's existing `stage:fix` children against
23
+ `maxFixRounds` in `skills/planning/create-task/pipeline.json`. Under cap, create a
24
+ `stage:fix` chore carrying the failure list **plus a fresh `stage:verify` chore** blocked on
25
+ it (`bd dep add <fresh> <fix> --type blocks`) — the chore you are closing can never verify
26
+ the fix — and re-block `review` behind the fresh bead. At cap, block the parent and create
27
+ nothing.
@@ -4,6 +4,8 @@ Run `bd prime` if you need project-level context (conventions, tech stack, goals
4
4
  ## Stage metadata
5
5
  - Stage: `<stage>`
6
6
  - Playbook: `skills/workflow/run-pipeline-stage/playbooks/<stage>.md`
7
+ - Leaf execution bead: `<bead-id>` — **you own its lifecycle**. No orchestrator,
8
+ dispatcher, or parent agent writes to it or closes it.
7
9
 
8
10
  ## Bead specification
9
11
  <bd show <id> output — verbatim>
@@ -24,7 +26,57 @@ bd update <id> --append-notes "[<ISO-timestamp>] [<stage>] <what changed / what'
24
26
 
25
27
  Use `--append-notes` — plain `--notes` overwrites the trail. Record start, milestones, decisions
26
28
  (with rejected options), blocks, and discoveries. One or two lines per entry: a checkpoint trail,
27
- not a transcript. The REPORT below remains the authoritative stage outcome.
29
+ not a transcript.
30
+
31
+ ## Leaf bead lifecycle (yours to close)
32
+
33
+ 1. **Chain before close.** Build remediation children (below) *before* you close the bead, so
34
+ the parent never shows a later stage as ready while remediation is outstanding.
35
+ 2. **Close on both outcomes** — success and failure alike:
36
+ ```bash
37
+ bd close <bead-id> --reason="<SUCCESS|BLOCKED>: <one-line outcome>"
38
+ ```
39
+ The outcome lives in the close reason, the milestone notes, and the REPORT. A closed bead
40
+ with a `BLOCKED` reason is a completed stage, not abandoned work.
41
+ 3. **Do not create the next stage on success.** Routing forward is the orchestrator's job.
42
+
43
+ ## Remediation (only when your outcome is BLOCKED)
44
+
45
+ A fresh instance of this stage is required: the bead you are closing cannot re-run itself.
46
+
47
+ 1. **Cap check.** Read `maxFixRounds` from `skills/planning/create-task/pipeline.json` and count
48
+ the parent's existing fix rounds (closed ones count):
49
+ ```bash
50
+ fix_rounds=$(bd children <parent-id> --json | grep -c '"stage:fix"')
51
+ ```
52
+ 2. **At cap** (`fix_rounds >= maxFixRounds`): create **nothing**. Block the parent and record why:
53
+ ```bash
54
+ bd update <parent-id> --status blocked \
55
+ --append-notes "[<ISO-timestamp>] max fix rounds reached (<fix_rounds>/<maxFixRounds>) after <stage> BLOCKED"
56
+ ```
57
+ Then close your own bead and report `OUTCOME: BLOCKED`.
58
+ 3. **Under cap**: create the fix chore plus the fresh stage, then wire the ordering.
59
+ `--parent` sets the parent-child dep and inherits the parent's labels.
60
+ ```bash
61
+ fix_id=$(bd create "[<parent-id>] Fix (round <fix_rounds + 1>)" \
62
+ --type chore --priority <parent-priority> --parent <parent-id> \
63
+ --labels stage:fix \
64
+ --description "Requirements: see <parent-id> (bd show <parent-id>).
65
+
66
+ <BLOCKING_ISSUES from your run>" --silent)
67
+ fresh_id=$(bd create "[<parent-id>] <Stage title> (re-run <fix_rounds + 1>)" \
68
+ --type chore --priority <parent-priority> --parent <parent-id> \
69
+ --labels stage:<stage> \
70
+ --description "<this stage's description from pipeline.json>" --silent)
71
+ bd dep add $fresh_id $fix_id --type blocks # fresh stage waits for the fix
72
+ ```
73
+ 4. **Re-block the later stages.** Any not-yet-run stage chore of the same parent is already
74
+ unblocked by your bead closing. Wire each one behind the fresh stage:
75
+ ```bash
76
+ bd dep add <downstream-chore-id> $fresh_id --type blocks
77
+ ```
78
+ Skip stages that already ran (closed) and the HITL PR gate bead.
79
+ 5. Do **not** dispatch anything yourself — the new beads flow through `bd ready`.
28
80
 
29
81
  ## Deliver before reporting
30
82
 
@@ -41,3 +93,23 @@ dirty worktree counts as a failed stage whatever the outcome line claims.
41
93
  1. Read and follow the playbook file listed above.
42
94
  2. Treat the bead as the source-of-truth specification (not a prompt script).
43
95
  3. Keep output factual and stage-scoped.
96
+
97
+ ## Report
98
+
99
+ End your response with a `---REPORT---` block in exactly this format:
100
+
101
+ ```
102
+ ---REPORT---
103
+ BEAD_ID: <id>
104
+ STAGE_COMPLETED: <code|verify|review|document|fix>
105
+ SUMMARY: <2-3 sentence summary of what was done>
106
+ FILES_CHANGED: <comma-separated list, or "none">
107
+ COMMIT: <sha of the stage commit, or "none">
108
+ PUSHED: <yes|no>
109
+ PR: <feature PR url, or "none">
110
+ OUTCOME: <SUCCESS|BLOCKED>
111
+ BLOCKING_ISSUES: <- only if OUTCOME is BLOCKED
112
+ - <specific blocking issue>
113
+ ```
114
+
115
+ Report facts only — do not suggest or predict the next step.
@@ -62,10 +62,15 @@ rather than inventing a dotted form:
62
62
  actually runs from. A literal home path in substituted files would break under
63
63
  cache-copy, so the installer passes the env form through verbatim.
64
64
  - **`agents`** — the `agent-cortex:` name-prefix convention per harness (claude strips the
65
- prefix during conversion) and the deferred-agent exception (claude's `ralph` is authored
66
- natively, never generated). Agent names themselves do not get per-row mappings because
67
- the prefix rule covers all of them; the deferred list captures the only structural
68
- difference.
65
+ prefix during conversion). Agent names themselves do not get per-row mappings because
66
+ the prefix rule covers all of them — every agent is composed from `agents/<name>/` for
67
+ every harness, so there is no structural exception to record.
68
+ - **`wake`** — the completion mechanism per harness (`pi`: blocking-wait,
69
+ `claude`: event-driven). Informational only — no installer substitutes a
70
+ token from it. It records the fact that the shared ralph body deliberately does not
71
+ state, so `{{SECTION:wake}}` → `agents/ralph/<harness>/wake.md` is the single place
72
+ harness specifics live, and the mechanism stays checkable instead of being inferred from
73
+ prose. `agents/README.md` carries the same table for humans.
69
74
  - **Deliberately not mapped:** hook patterns, MCP servers, and tool descriptions. Those
70
75
  differ *structurally* per harness (different hook event names, different config files),
71
76
  not by a single substitutable token; each installer already hardcodes its own shape. The
package/token-map.json CHANGED
@@ -46,12 +46,20 @@
46
46
  "claude": "",
47
47
  "pi": "agent-cortex:"
48
48
  },
49
- "deferred": {
50
- "ralph": ["claude"]
51
- },
52
49
  "sources": {
53
50
  "pi": "agents/<name>/ composable dirs (canonical) — composed at runtime by the agent-modes extension",
54
- "claude": "agents/<name>/ composable dirs (canonical) — composed by bin/installers/claude.mjs (install-time generator, the only generator — the generated claude/ plugin subtree is not committed), plus agents-native/*.md for deferred agents"
51
+ "claude": "agents/<name>/ composable dirs (canonical) — composed by bin/installers/claude.mjs (install-time generator, the only generator — the generated claude/ plugin subtree is not committed)"
52
+ }
53
+ },
54
+ "wake": {
55
+ "description": "How each harness tells ralph that a background worker finished. `{{SECTION:wake}}` in agents/ralph/agent.md resolves to agents/ralph/<harness>/wake.md; this table is the machine-readable form of the same fact, so the mechanism is recorded rather than inferred from prose (see the wake table in agents/README.md).",
56
+ "mechanism": {
57
+ "pi": "blocking-wait",
58
+ "claude": "event-driven"
59
+ },
60
+ "notes": {
61
+ "pi": "Blocking wait: wait_for_agents returns as soon as one worker finishes, carrying its result inline. No timer to start, nothing to kill — there is no poll loop.",
62
+ "claude": "Event-driven: the harness re-invokes ralph when a worker completes and delivers the result inline. No poll timer, no sleep, no log flush."
55
63
  }
56
64
  },
57
65
  "notes": {
@@ -70,8 +78,7 @@
70
78
  "claude": "plugin_root stays ${CLAUDE_PLUGIN_ROOT} (env var) for the materialised plugin — never a literal ~/.agent-cortex/claude. Claude Code copies marketplace-installed plugins (including local directory sources like ~/.agent-cortex/claude) into its own cache and expands the env var per context, so a literal home path in substituted files would break under cache-copy; the installer passes the env form through verbatim."
71
79
  },
72
80
  "agents": {
73
- "prefix": "Claude strips the agent-cortex: name prefix during conversion (NAME_PREFIX in bin/installers/claude.mjs): pi agents are agent-cortex:<slug>, claude agents are <slug>.",
74
- "deferred": "ralph has no generated claude counterpart — it is authored natively as agents-native/ralph.md (its event-driven orchestration cannot be produced by section composition from the polling pi source)."
81
+ "prefix": "Claude strips the agent-cortex: name prefix during conversion (NAME_PREFIX in bin/installers/claude.mjs): pi agents are agent-cortex:<slug>, claude agents are <slug>."
75
82
  }
76
83
  },
77
84
  "contract": {
@@ -1,172 +0,0 @@
1
- ---
2
- name: style-versioning
3
- description: Automated release workflow using changesets. Use when completing work that needs a release, asking "how do I version this?", or when any change needs to be shipped to npm.
4
- ---
5
-
6
- # style-versioning
7
-
8
- This repo uses **changesets** for fully automated versioning and publishing. No manual version bumps, no manual releases.
9
-
10
- ## When to use
11
-
12
- Trigger this skill when:
13
- - Completing work that needs a release
14
- - Asking "how do I version this change?"
15
- - Creating a PR that changes shipped behaviour
16
-
17
- ## Creating a changeset (agent instructions)
18
-
19
- **Do NOT run `pnpm changeset`** — it is interactive and will waste tokens on prompts and ANSI codes. Instead, write the changeset file directly.
20
-
21
- ### File format
22
-
23
- A changeset is a markdown file in `.changeset/` with YAML frontmatter:
24
-
25
- ```markdown
26
- ---
27
- "@jaybeeuu/agent-cortex": <bump>
28
- ---
29
-
30
- <Short description of the change>
31
- ```
32
-
33
- Where `<bump>` is one of: `patch`, `minor`, or `major`.
34
-
35
- ### How to create one
36
-
37
- 1. Choose a descriptive kebab-case filename (e.g., `fix-status-bug.md`, `add-webhook-skill.md`)
38
- 2. Choose the bump type:
39
- - `patch` — bug fix, clarification, no behaviour change
40
- - `minor` — new skill, agent, feature, or meaningful behaviour change
41
- - `major` — breaking change (removed skill, renamed agent, incompatible workflow)
42
- 3. Write the file directly using the `write` tool:
43
-
44
- ```
45
- write(".changeset/fix-status-bug.md", `---
46
- "@jaybeeuu/agent-cortex": patch
47
- ---
48
-
49
- Fix status bead showing wrong priority after update
50
- `)
51
- ```
52
-
53
- 4. Commit the changeset file along with the code changes
54
-
55
- ### Rules
56
-
57
- - **Every PR adds a changeset.** CI fails otherwise. The only opt-out is the
58
- `no-publish` label (see below).
59
- - The frontmatter package name must match exactly: `"@jaybeeuu/agent-cortex"`
60
- - The description should be one or two sentences, user-facing (it goes into CHANGELOG.md)
61
- - One changeset per PR. If a PR has multiple unrelated changes, use multiple changeset files.
62
- - The filename doesn't matter to changesets — only the frontmatter and description do.
63
-
64
- ## The PR gate
65
-
66
- `changeset-check` runs on every pull request and fails it unless the PR adds a
67
- `.changeset/*.md` file. **Publishing is the default; `no-publish` is the only
68
- opt-out** — skipping a release is an explicit, reviewable decision, never an accident.
69
-
70
- | Exemption | Applies to |
71
- |---|---|
72
- | `changeset-release/*` head branch, or actor `github-actions[bot]` | the changesets bot's Version Packages PR — it consumes changesets and adds none of its own |
73
- | `no-publish` label | a PR that genuinely ships nothing |
74
-
75
- The `no-publish` label must exist in the repository's label settings — a one-off
76
- human step (`gh label create no-publish`), not something a PR can ship. If the gate
77
- fails and the PR really ships nothing, ask for the label; do not manufacture a
78
- changeset to make it green.
79
-
80
- ## After merge to main
81
-
82
- The `release` job in `.github/workflows/ci.yml` handles everything automatically:
83
-
84
- 1. **Detects new changesets** on main
85
- 2. **Creates a "Version Packages" PR** — the `version` step runs `pnpm version-packages` (`changeset version`), which bumps `package.json` and rewrites `CHANGELOG.md`. That is the whole release surface: every plugin this package ships is materialised at install time with the package version, so there is no generated output to regenerate and no drift gates to satisfy on a version bump
86
- 3. **When "Version Packages" is merged**:
87
- - Creates a git tag
88
- - Publishes to npm — `pnpm publish-package` packs with `pnpm pack` and publishes with `npm publish --provenance --access public`. Authenticates via npm Trusted Publishing (OIDC): the release job's `id-token` permission lets npm exchange a GitHub OIDC token for a short-lived npm token at publish time, so no `NPM_TOKEN` secret or `.npmrc` auth config is required — only the one-time npm-side Trusted Publishing setup on npmjs.com (package → Access → Trusted Publishing → GitHub repo `jaybeeuu/agent-cortex` + workflow `.github/workflows/ci.yml`)
89
- - Creates a GitHub release automatically
90
-
91
- `changesets/action` execs the `version`/`publish` inputs without a shell, so each
92
- must be a single unquoted command token — keep release logic in pnpm scripts
93
- (`version-packages`, `publish-package`, `publish-noop`), never inline shell strings.
94
-
95
- ### Approve CI on the Version Packages PR
96
-
97
- The version PR arrives `BLOCKED` with an empty check list, and nothing is broken:
98
- `changesets/action` pushes that branch with `GITHUB_TOKEN`, so GitHub parks the CI
99
- run the push creates behind **“Approve workflows to run”** (`action_required`, zero
100
- jobs). A parked run reports no checks, so the five required contexts are
101
- unsatisfiable until someone approves it. Approve it from the PR's merge box, or:
102
-
103
- ```bash
104
- run=$(gh run list --branch changeset-release/main --limit 20 \
105
- --json databaseId,conclusion --jq 'map(select(.conclusion=="action_required"))[0].databaseId')
106
- gh api -X POST "repos/{owner}/{repo}/actions/runs/$run/approve"
107
- ```
108
-
109
- An approval is per head commit. Every merge to `main` force-updates the version
110
- branch and starts a fresh parked run, so approve immediately before merging the
111
- version PR — not once per release. Do not reach for a PAT or GitHub App token to
112
- skip this: one click is cheaper than a long-lived credential in repository
113
- secrets, and the `GITHUB_TOKEN` the job already holds cannot approve its own run.
114
-
115
- Which of the two publish scripts runs is decided per push, not hard-coded: labels are
116
- invisible on a push event, so the job resolves the PR merged for the pushed commit via
117
- the GitHub API and reads its labels — `publish-noop` when the PR carried `no-publish`,
118
- `publish-package` otherwise. That needs no new secret or scope; the job already holds
119
- `GITHUB_TOKEN` and `pull-requests: write`. A direct push with no merged PR resolves to
120
- no labels and so publishes, which keeps a genuine publish of an already-published
121
- version failing loudly — there is deliberately no idempotency guard.
122
-
123
- ### Merge method and commit signatures
124
-
125
- Land a Version Packages PR with `gh pr merge <n> --squash`. Agent and human commits here are
126
- GPG-signed by the environment and verify as `valid`; the `github-actions[bot]` commit is
127
- `unsigned` because `GITHUB_TOKEN` cannot sign. The commit that lands is signed by GitHub,
128
- which is why `main`'s history reads `valid`: PR #161's unsigned head `fe7ef84` landed as
129
- `dd347471b1` with `committer=GitHub`, `verified=true`.
130
-
131
- Squash re-signs the landing commit; it does not escape an enforced signature rule. GitHub
132
- evaluates a pull request by creating a test merge commit and checking the commits it
133
- introduces — head-branch commits included — so an enforced `required_signatures` rule blocks
134
- a squash merge too, and the remedy is then a signed commit on the branch, not another merge
135
- method. `allow_merge_commit` is off and `required_linear_history` is on, so a merge commit is
136
- not an option — squash or rebase only, and only squash lands a commit GitHub signs.
137
-
138
- See `docs/commit-signing.md` for the evidence, the ruleset reads that show only
139
- repository-level rules applying to `main` (a read that covers organization rules too), and the
140
- human-only follow-ups, including the merge probe that closes AC1.
141
-
142
- ### Version lockstep
143
-
144
- Two files carry the version, in lockstep automatically:
145
-
146
- 1. `package.json` → bumped by changesets
147
- 2. `CHANGELOG.md` → generated by changesets
148
-
149
- **Never bump versions manually.** Always create a changeset file.
150
-
151
- ## Common mistakes
152
-
153
- - **Running `pnpm changeset`**: Interactive, wastes tokens. Write the file directly.
154
- - **Bumping versions manually**: Don't touch `"version"` in `package.json`. Create a changeset.
155
- - **Omitting the changeset**: CI fails the PR. Publishing is the default; the only
156
- opt-out is the `no-publish` label, which must already exist in the repo's settings.
157
- - **Wrong bump type**: `patch` for fixes, `minor` for additions, `major` for breakage. When in doubt, ask the user.
158
- - **Wrong package name in frontmatter**: Must be `"@jaybeeuu/agent-cortex"` exactly.
159
- - **Merging a Version Packages PR with anything but squash**: the bot's commit is unsigned,
160
- and squash is the path this repo has landed on (a rebase merge adds the head-branch commit
161
- without signature verification).
162
- Squash does not, however, bypass an enforced signature rule — if one is confirmed, the
163
- branch needs a signed commit. See `docs/commit-signing.md`.
164
-
165
- ## What changed from the old workflow
166
-
167
- | Before (manual) | After (changesets) |
168
- |---|---|
169
- | Agent bumps versions locally | Agent writes a changeset file |
170
- | Manual GitHub release creation | Automated by the `release` job in `ci.yml` |
171
- | `publish.yml` triggered by release | `ci.yml` release job on push to main |
172
- | Version files synced by hand | changesets bumps `package.json` + `CHANGELOG.md` |