@jaybeeuu/agent-cortex 2.7.0 → 2.9.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 (87) hide show
  1. package/CHANGELOG.md +412 -0
  2. package/README.md +87 -8
  3. package/agents/README.md +4 -4
  4. package/agents/guppi/agent.md +162 -0
  5. package/agents/guppi/claude/frontmatter.json +6 -0
  6. package/agents/guppi/pi/frontmatter.json +6 -0
  7. package/agents/plan/agent.md +6 -0
  8. package/agents/ralph/agent.md +17 -16
  9. package/agents/ralph/claude/wake.md +4 -4
  10. package/agents/ralph/pi/wake.md +15 -20
  11. package/agents/ralph-plan/agent.md +6 -0
  12. package/bin/agent-cortex.mjs +20 -1
  13. package/bin/installers/claude.mjs +1 -20
  14. package/bin/installers/pi.mjs +8 -2
  15. package/extensions/interrupt-bookmark/README.md +129 -0
  16. package/extensions/interrupt-bookmark/index.test.ts +717 -0
  17. package/extensions/interrupt-bookmark/index.ts +354 -0
  18. package/extensions/interrupt-bookmark/package.json +20 -0
  19. package/extensions/post-merge-watch/README.md +133 -0
  20. package/extensions/post-merge-watch/index.test.ts +247 -0
  21. package/extensions/post-merge-watch/index.ts +123 -0
  22. package/extensions/post-merge-watch/package.json +16 -0
  23. package/extensions/post-merge-watch/watch.test.ts +469 -0
  24. package/extensions/post-merge-watch/watch.ts +431 -0
  25. package/extensions/session-clear/README.md +74 -0
  26. package/extensions/session-clear/index.test.ts +524 -0
  27. package/extensions/session-clear/index.ts +159 -0
  28. package/extensions/session-clear/package.json +16 -0
  29. package/extensions/skill-stats/README.md +84 -3
  30. package/extensions/skill-stats/index.ts +62 -3
  31. package/extensions/skill-stats/package.json +1 -1
  32. package/extensions/skill-stats/rollup.test.ts +643 -0
  33. package/extensions/skill-stats/rollup.ts +415 -0
  34. package/extensions/skill-stats/timeline.ts +101 -0
  35. package/lib/cli.mjs +42 -1
  36. package/lib/self-update.mjs +553 -0
  37. package/package.json +1 -1
  38. package/scripts/lib/manifest.mjs +29 -0
  39. package/skills/engineering/implement-task/SKILL.md +124 -0
  40. package/skills/engineering/tdd/SKILL.md +2 -0
  41. package/skills/planning/create-task/REFERENCE.md +15 -6
  42. package/skills/planning/create-task/SKILL.md +1 -1
  43. package/skills/planning/create-task/pipeline.json +8 -0
  44. package/skills/planning/create-task/scripts/create-chores.mjs +27 -18
  45. package/skills/planning/create-task/templates/code.md +8 -3
  46. package/skills/planning/create-task/templates/document.md +8 -3
  47. package/skills/planning/create-task/templates/fix.md +8 -3
  48. package/skills/planning/create-task/templates/housekeeping.md +8 -4
  49. package/skills/planning/create-task/templates/post-merge.md +67 -0
  50. package/skills/planning/create-task/templates/review.md +8 -3
  51. package/skills/planning/create-task/templates/verify.md +8 -3
  52. package/skills/productivity/bd-tool/SKILL.md +55 -0
  53. package/skills/review/review-defects/EXAMPLES.md +198 -0
  54. package/skills/review/review-defects/SKILL.md +121 -0
  55. package/skills/review/review-report/EXAMPLES.md +114 -0
  56. package/skills/review/review-report/SKILL.md +138 -0
  57. package/skills/review/review-report/scripts/report.mjs +1032 -0
  58. package/skills/style/style-tests/EXAMPLES.md +30 -0
  59. package/skills/style/style-tests/SKILL.md +10 -6
  60. package/skills/workflow/hitl-queue/SKILL.md +134 -0
  61. package/skills/workflow/hitl-queue/scripts/queue.mjs +626 -0
  62. package/skills/workflow/plan/SKILL.md +27 -3
  63. package/skills/workflow/prioritise-work/CHALLENGE.md +139 -0
  64. package/skills/workflow/prioritise-work/SKILL.md +150 -0
  65. package/skills/workflow/prioritise-work/scripts/challenge.mjs +505 -0
  66. package/skills/workflow/prioritise-work/scripts/strategy.mjs +566 -0
  67. package/skills/workflow/prioritise-work/templates/strategy.md +61 -0
  68. package/skills/workflow/ralph/REFERENCE.md +124 -27
  69. package/skills/workflow/ralph/SKILL.md +24 -15
  70. package/skills/workflow/ralph/scripts/post-merge-check.mjs +651 -0
  71. package/skills/workflow/run-pipeline-stage/SKILL.md +37 -22
  72. package/skills/workflow/run-pipeline-stage/playbooks/code.md +14 -8
  73. package/skills/workflow/run-pipeline-stage/playbooks/document.md +2 -2
  74. package/skills/workflow/run-pipeline-stage/playbooks/fix.md +2 -2
  75. package/skills/workflow/run-pipeline-stage/playbooks/housekeeping.md +1 -1
  76. package/skills/workflow/run-pipeline-stage/playbooks/post-merge.md +54 -0
  77. package/skills/workflow/run-pipeline-stage/playbooks/review.md +37 -3
  78. package/skills/workflow/run-pipeline-stage/playbooks/verify.md +2 -2
  79. package/skills/workflow/run-pipeline-stage/prompts/stage-runner.md +55 -11
  80. package/skills/workflow/run-pipeline-stage/scripts/recover-brief.mjs +805 -0
  81. package/skills/workflow/run-pipeline-stage/scripts/trail-entry.mjs +702 -0
  82. package/skills/workflow/score-bead/FORMAT.md +73 -0
  83. package/skills/workflow/score-bead/SKILL.md +112 -0
  84. package/skills/workflow/score-bead/scripts/rice.mjs +664 -0
  85. package/skills/workflow/using-agent-skills/SKILL.md +21 -8
  86. package/token-map.README.md +27 -0
  87. package/token-map.json +16 -4
@@ -20,6 +20,8 @@ Covers everything needed to prepare work for autonomous execution: understand th
20
20
 
21
21
  ## When NOT to use
22
22
 
23
+ - Choosing which feature to plan next, or re-ranking the backlog — that is the **guppi** agent, which
24
+ decides what gets planned and hands one feature to this skill.
23
25
  - User already has a PRD and just needs it broken into tasks — use `prd-to-tasks` directly.
24
26
  - Single well-understood task that just needs a bead — use `create-task`.
25
27
  - Raw idea not ready for implementation planning — use `record-idea`.
@@ -28,6 +30,16 @@ Covers everything needed to prepare work for autonomous execution: understand th
28
30
 
29
31
  ## Workflow
30
32
 
33
+ ### Phase 0 — Report the HITL queue
34
+
35
+ Before asking anything, presenting a plan, or dispatching a task, load the `hitl-queue` skill and
36
+ report its queue exactly as the script prints it. Then name the top item in one sentence: its id,
37
+ its title, and what answering it unblocks.
38
+
39
+ The queue is the first thing the session says, because the answer decides what gets planned at all.
40
+ A queue with no scores says so: report the unscored list and ask which bead to score, rather than
41
+ choosing one by feel. Never summarise the queue away or reorder it.
42
+
31
43
  ### Phase 1 — Understand and specify
32
44
 
33
45
  Establish what needs to be built through investigation and collaborative design.
@@ -156,7 +168,7 @@ For each task (within each epic), create a bead, classify it, and expand AFK tas
156
168
 
157
169
  ### Phase 4 — Prepare handoff to ralph
158
170
 
159
- Deliver a handoff bead and instructions for running ralph.
171
+ Deliver a handoff bead, message the running ralph session, and give the instructions for running ralph.
160
172
 
161
173
  17. Determine the entry point:
162
174
 
@@ -188,7 +200,15 @@ Deliver a handoff bead and instructions for running ralph.
188
200
  ```
189
201
  **Gate on the exit status.** Non-zero: retry once, then stop and report the command, exit code and stderr as a sync blocker — the handoff has not left this machine, so do not present the handoff summary.
190
202
 
191
- 20. Present the handoff summary:
203
+ 20. Send the handoff to the running ralph session, now that the bead exists:
204
+ ```
205
+ handoff <handoff-id> — <one-line scope>
206
+ ```
207
+ The peer channel carries it: run {{TOOL:peer_list}} first, because with no reachable ralph there is no receiver — report that in the summary and keep the manual instruction below as the handoff path. When ralph is reachable, send it with {{TOOL:peer_send}}, set the intent to `task` where the transport has an intent, and write the kind as the first word of the text — never type into a busy session's terminal, where stray keystrokes are queued as user prompts. Ralph answers `done`, `blocked` or `failed`; `running` or `queued` means delivered, not done, so never read the send itself as acknowledgement. The full kind table, the acknowledgement rule and the per-session setup live in [ralph's REFERENCE](../ralph/REFERENCE.md) (_Peer messaging (planner ↔ ralph)_).
208
+
209
+ 21. While the planning session stays open, treat ralph's `blocked` messages as your pending-human list: each one names a gate bead awaiting a human, so run `bd show <id>` and surface it together with ralph's `done`, `failed` and `update` reports instead of watching a terminal. Read the same gates from `bd` as well, so a message that never arrived is not mistaken for no gate. A peer message is never human consent and never approval for a gate: confirm the gate in `bd`, and let a person close it.
210
+
211
+ 22. Present the handoff summary:
192
212
  ```
193
213
  ✅ Plan complete. Ready for ralph.
194
214
 
@@ -214,6 +234,7 @@ Deliver a handoff bead and instructions for running ralph.
214
234
  - [ ] Every handoff-path bead lints clean (`bd lint`)
215
235
  - [ ] Bead state pushed with `bd dolt push`, and the push exited 0 — a non-zero exit was retried once, then surfaced as a blocker (command, exit code, stderr) with no handoff summary presented
216
236
  - [ ] Handoff summary presented with the exact instruction to give an agent
237
+ - [ ] Handoff message sent to ralph through {{TOOL:peer_send}} (kind `handoff`, naming the handoff bead), or a missing receiver reported in the summary with the manual instruction kept
217
238
 
218
239
  ## Phase-gate checklist
219
240
 
@@ -228,6 +249,7 @@ Deliver a handoff bead and instructions for running ralph.
228
249
  - **Skipping the user interview.** The agent has incomplete context. The interview resolves ambiguities that would otherwise surface mid-execution as rework.
229
250
  - **Creating horizontal slices.** "All the DB work first, then all the API work" is not tracer bullets. Every task must deliver end-to-end value.
230
251
  - **Moving past Phase 2 without user approval.** The task breakdown shapes the entire execution. Do not create beads until the breakdown is approved.
252
+ - **Treating a sent handoff as an accepted one.** A `handoff` message carries no receipt: ralph's status stays `running` or `queued` until it answers `done`, `blocked` or `failed`, so a send that returned is not proof the work started.
231
253
 
232
254
  ## Common Rationalizations
233
255
 
@@ -251,7 +273,8 @@ Deliver a handoff bead and instructions for running ralph.
251
273
  - [prd-to-tasks](../../planning/prd-to-tasks/SKILL.md) — load when the PRD is already written and only decomposition is needed.
252
274
  - [spec-to-tickets](../../planning/spec-to-tickets/SKILL.md) — load instead when the PRD must become external tickets rather than beads.
253
275
  - [create-task](../../planning/create-task/SKILL.md) — Phase 3's per-task bead creation and pipeline expansion; it invokes `classify-bead` internally, so this skill never classifies directly.
254
- - [ralph](../ralph/SKILL.md) — the downstream consumer of the handoff bead — hand off by running a separate agent with "Use the ralph skill. Start from bead #<handoff-id>".
276
+ - [ralph](../ralph/SKILL.md) — the downstream consumer of the handoff bead — hand off by sending ralph a `handoff` message naming the bead, with "Use the ralph skill. Start from bead #<handoff-id>" as the manual fallback when no ralph session is online. Its [REFERENCE.md](../ralph/REFERENCE.md) owns the planner ↔ ralph message convention.
277
+ - **guppi** (the `agent-cortex:guppi` agent) — the upstream entry point: it decides what gets planned and hands this skill one feature. Load this skill for that feature. The strategy guppi recommends from is the committed file that `prioritise-work` owns; `score-bead` records the score and `hitl-queue` prints the order.
255
278
 
256
279
  ## Examples
257
280
 
@@ -293,3 +316,4 @@ Full bead tree:
293
316
  - [ ] Handoff bead tagged `workflow:ralph`
294
317
  - [ ] Bead state pushed with `bd dolt push`, and the push exited 0 — a non-zero exit was retried once, then surfaced as a blocker (command, exit code, stderr) with no handoff summary presented
295
318
  - [ ] Handoff summary includes the exact instruction to give an agent
319
+ - [ ] Handoff message sent to ralph (kind `handoff`, naming the handoff bead) through {{TOOL:peer_send}}; ralph's `done`/`blocked`/`failed` replies were the only evidence of completion, never the send itself
@@ -0,0 +1,139 @@
1
+ # A challenged priority
2
+
3
+ Detail behind `SKILL.md`. When the owner says "this should be higher", "that is not the priority",
4
+ or "why is this above that?", the queue is being challenged. Read this before you touch a score.
5
+
6
+ ## A challenge is a strategy signal
7
+
8
+ A challenge does not mean one score is wrong. It means the rubric that produced the score is
9
+ wrong, stale, or has shifted: the owner is optimising something else this month, or the value
10
+ rule reads differently against this bead than the scorer read it.
11
+
12
+ So the reply is a **strategy review**, never an edit. The rule is one sentence, and every refusal
13
+ below enforces it:
14
+
15
+ > No score and no position moves without the strategy version moving first.
16
+
17
+ An ad-hoc override does not exist. The only way an item legitimately ranks higher is for a
18
+ sentence in the rubric to say why it should, so the next scorer reaches the same answer.
19
+
20
+ ## The sequence
21
+
22
+ 1. **Note the version you are challenging.** `node <skill-scripts>/strategy.mjs validate` prints
23
+ `version N`. Keep `N`: it becomes `--from-version`, and it is what proves the rubric moved.
24
+ 2. **Write down the order before.** The candidate bead ids, highest first, comma-separated. This
25
+ is the baseline the diff is taken against.
26
+ 3. **Read the challenge back as a claim about one section.** Which section disagrees — the theme,
27
+ the value rule, the confidence rule, the effort anchor? Ask; do not guess.
28
+ 4. **Offer the interview.** Say plainly that the order is produced by the rubric, so a reorder
29
+ means a rubric change, and ask the questions in `SKILL.md` § Workflow, "Later runs".
30
+ 5. **Decide.** The rubric changes, or it stands. Both are legitimate outcomes; see below.
31
+ 6. **Re-rank** against the rubric as it now reads.
32
+ 7. **Record** the challenge on the bead, and show the owner what moved.
33
+
34
+ ## Outcome: the rubric changed
35
+
36
+ Edit the sections the interview changed, then bump with the reason. A bump without a reason is
37
+ refused, because a version that moved with no recorded reason is a change nobody can review.
38
+
39
+ ```bash
40
+ node <skill-scripts>/strategy.mjs bump --reason "review turnaround is the theme now"
41
+ ```
42
+
43
+ That writes the version, the date, and one change-log line. Then re-rank and record:
44
+
45
+ ```bash
46
+ node <skill-scripts>/challenge.mjs record --bead agnt-ctx-abc.1 \
47
+ --challenge "the review queue should be above the installer fix" \
48
+ --resolution changed \
49
+ --reason "review turnaround is the theme now" \
50
+ --from-version 3 \
51
+ --before agnt-ctx-abc.1,agnt-ctx-abc.2,agnt-ctx-def.1 \
52
+ --after agnt-ctx-def.1,agnt-ctx-abc.1,agnt-ctx-abc.2 \
53
+ --out /tmp/challenge-entry.txt
54
+ bd note agnt-ctx-abc.1 --file /tmp/challenge-entry.txt
55
+ ```
56
+
57
+ `--out` writes the entry to a file, so the tracker appends it as data. Never paste the entry's own
58
+ words into a shell string: the entry repeats what the human said, so a `"` in those words would end
59
+ the quoting early and a `$(…)` would run a command. Pasting a **path** is safe instead —
60
+ `bd note <bead> "$(cat <path>)"` reads the file and never parses the entry — but every example
61
+ here uses `--file`, which needs no shell at all, so that is the one form to copy. `record` also
62
+ prints the movement, which is what you show the owner:
63
+
64
+ ```
65
+ [2026-12-01T09:30:00.000Z] [challenge] trail:2f9c4b1e7a3d5c60
66
+ Outcome: done
67
+ Evidence: challenged "the review queue should be above the installer fix"; strategy v3 → v4
68
+ (updated 2026-12-01); rubric reason: review turnaround is the theme now; order 3 items, 2 moved:
69
+ agnt-ctx-def.1 #3→#1, agnt-ctx-abc.1 #1→#2
70
+ What is left: nothing — scores are re-ranked against strategy v4
71
+ ```
72
+
73
+ ## Outcome: no change to the rubric
74
+
75
+ Valid, and common: the rubric already answers the challenge, or the owner decides the challenge
76
+ does not outweigh the theme. The order does not move either — nothing changed that could move it.
77
+
78
+ Record it anyway. An outcome that leaves no trace is a defect: the next session would rediscover
79
+ the same challenge, and the owner would see the same question asked again.
80
+
81
+ ```bash
82
+ node <skill-scripts>/challenge.mjs record --bead agnt-ctx-abc.1 \
83
+ --challenge "the review queue should be above the installer fix" \
84
+ --resolution no-change \
85
+ --reason "the value rule already requires a human gate, and the installer fix unblocks one" \
86
+ --from-version 3 \
87
+ --out /tmp/challenge-entry.txt
88
+ bd note agnt-ctx-abc.1 --file /tmp/challenge-entry.txt
89
+ ```
90
+
91
+ The entry carries the words that raised the challenge and the reasoning that answered it, under
92
+ `Evidence`, so `bd show <bead>` recovers both. The strategy file is not touched.
93
+
94
+ ## The refusals
95
+
96
+ `record` exits 1, writes nothing, and names the problem in four cases. Each is a shortcut worth
97
+ refusing:
98
+
99
+ | You tried | What it says |
100
+ |---|---|
101
+ | Reordered, rubric untouched | the order moved, but the strategy stayed at vN — a reorder without a rubric change |
102
+ | "changed" with no bump | resolution "changed", but the version did not rise (v3 → v3) |
103
+ | "no-change" after a bump | the version moved (v3 → v4), so the resolution is "changed" |
104
+ | Challenged against a broken rubric | the strategy is not valid, so no score can be judged against it |
105
+
106
+ `validate` adds a fifth, after the fact, and it needs one surviving entry: the newest change-log
107
+ line must name the version the file carries, so a hand-raised version, or a bump whose log line was
108
+ deleted, fails the next validation. The section is optional, so a log emptied of every entry passes
109
+ — and `record` is what catches a silent reorder then, because it refuses an order that moved while
110
+ the version stayed put.
111
+
112
+ ## How the order is computed
113
+
114
+ The order is a plain list of candidate bead ids, highest first — from a scorer when one produced
115
+ the queue, otherwise from re-reading the rubric yourself. `record` does not rank; it compares
116
+ positions, which is what makes the movement deterministic and repeatable:
117
+
118
+ - An id in both lists at a different position **moved**. Positions are 1-based, and the delta is
119
+ old minus new, so a positive delta is upward movement.
120
+ - An id only in the new list is **new at** its position.
121
+ - An id only in the old list **dropped from** its position.
122
+
123
+ Moved items are reported in new-position order, then the arrivals, then the departures in
124
+ old-position order. The same two lists therefore print the same clause every time.
125
+
126
+ `--before` and `--after` are required for `changed`, because a recording that does not name what
127
+ moved does not show the owner the consequence. They are optional for `no-change`, where they can
128
+ only agree with each other — and are refused when they do not.
129
+
130
+ ## Where each record goes
131
+
132
+ | Record | Lives in | Why |
133
+ |---|---|---|
134
+ | Why the rubric changed | the strategy file's change log, written by `bump` | a reviewer diffs it, and it is versioned next to the rubric |
135
+ | The challenge, its reasoning and the movement | the bead trail, written by `bd note` from `record` | it is the progress record for that one bead, and a cold session reads it from `bd show` |
136
+
137
+ Neither script writes to the other's store: `strategy.mjs` never calls the tracker, and
138
+ `challenge.mjs` never edits the strategy file. A challenge recorded on a bead is not a rubric
139
+ change, and a rubric change with no bead is not a challenge.
@@ -0,0 +1,150 @@
1
+ ---
2
+ name: prioritise-work
3
+ description: Sets, updates and validates the committed prioritisation strategy that bead scoring ranks against. Use when choosing what to work on next, when the strategy file is missing or stale, or when asked to "set the strategy".
4
+ ---
5
+
6
+ # Prioritise Work
7
+
8
+ Owns one artefact: the **strategy file**, the rubric a scorer reads before it judges a bead's reach, impact, confidence and effort. The skill interviews the owner to write or update it, and validates it before any scorer reads it.
9
+
10
+ The strategy is a **committed file**, never a bead and never a scratch note. A rubric is reviewed, diffed and versioned as text; a bead carries progress and decisions about *work*, not the durable document that judges work. The tracker convention draws the same line: operational state — progress, decisions, refs — goes in the bead trail, and a document a reviewer diffs stays a file. Keep the strategy a file even when a bead could hold the same words, because then nobody can review a change to the rubric.
11
+
12
+ ## When to use
13
+
14
+ - "What should I work on next?" — and there is no strategy file, or the one there is predates the current month.
15
+ - "Set the strategy", "update the priorities", "we are optimising something else this month".
16
+ - "This should be higher", "that is not the priority" — a challenge to the order, which is a strategy signal. See [CHALLENGE.md](CHALLENGE.md).
17
+ - A scorer reports a score with no `strategyVersion`, or with one older than the file's.
18
+ - Before ranking a backlog: the rubric has to be valid first.
19
+
20
+ ## When NOT to use
21
+
22
+ - Shaping one feature — use `plan`; that skill scopes a feature, this one orders the work.
23
+ - Recording an idea for later — use `record-idea`.
24
+ - Tracker questions, or where a bead's state lives — use `bd-tool`.
25
+ - Writing a PRD or a design document — use `write-a-prd`.
26
+
27
+ ## The strategy file
28
+
29
+ | Item | Value |
30
+ |---|---|
31
+ | Default path | `.agent-cortex/working-docs/strategy.md`, relative to the repository root |
32
+ | Override | `--file <path>` on every subcommand |
33
+ | Contents | a version integer, a date, and five required sections |
34
+ | Lifetime | committed; edited by interview, then versioned with `bump` |
35
+
36
+ The working-docs root is the scratch directory the HITL handoff also uses: `.agent-cortex/working-docs/hitl/<bead-id>/handoff.md`. The strategy sits beside it and is the one file in that directory the repository commits.
37
+
38
+ The default path resolves against the **repository root**, found by walking up for a `.git` entry, not against the directory the shell is in. Run `init` from any subdirectory and you still get the one strategy the repository owns. An override behaves differently: a relative `--file` resolves against the current directory, and an absolute one is taken as given.
39
+
40
+ That directory's contents are usually ignored (`working-docs/*`), so track the strategy explicitly. Add the un-ignore line to the consuming repository's `.gitignore` once:
41
+
42
+ ```gitignore
43
+ !.agent-cortex/working-docs/strategy.md
44
+ ```
45
+
46
+ Use that rather than `git add -f`: an ignored file disappears from `git status`, so the next update is committed by nobody.
47
+
48
+ ## Workflow
49
+
50
+ ### First run — no strategy file
51
+
52
+ 1. Confirm the file is absent:
53
+
54
+ ```bash
55
+ node <skill-scripts>/strategy.mjs validate
56
+ ```
57
+
58
+ It exits 1 and names the path it looked for. Do not search the repository for an alternative: one strategy, one location, or two scorers rank against two rubrics.
59
+
60
+ 2. Write the shipped template to that path. This is the copy step — the script resolves its own template, so it works from either install layout:
61
+
62
+ ```bash
63
+ node <skill-scripts>/strategy.mjs init
64
+ ```
65
+
66
+ It stamps the date and leaves the version at `1`, and refuses to overwrite an existing file.
67
+
68
+ 3. Interview the owner. Ask one question at a time and write the answer under the section the table below names. Replace the guidance comment with the owner's own words; do not paraphrase a figure they gave.
69
+
70
+ 4. Validate before committing. `validate` prints the filled rubric to stdout only when it passes, and names every defective field or section on stderr otherwise:
71
+
72
+ ```bash
73
+ node <skill-scripts>/strategy.mjs validate
74
+ ```
75
+
76
+ 5. Commit the file with the un-ignore line. The interview is finished only when `validate` exits 0 and `git ls-files --error-unmatch .agent-cortex/working-docs/strategy.md` succeeds.
77
+
78
+ ### Later runs — the file exists
79
+
80
+ 6. Read the current strategy and check its `**Updated:**` date. A date from an earlier month is stale: re-run the interview before scoring anything against it.
81
+
82
+ 7. Ask the four questions again, plus the confidence question, and edit the sections that changed. Leave a section alone when the answer has not changed.
83
+
84
+ 8. Bump the version and record the date and the reason, then validate:
85
+
86
+ ```bash
87
+ node <skill-scripts>/strategy.mjs bump --reason "<why the rubric changed>"
88
+ ```
89
+
90
+ The bump refuses a file that is not already valid and refuses an empty reason, raises the version by exactly one, writes today's date in UTC, and appends `- <date> v<n>: <reason>` to the change log. Report the old and new version to the owner.
91
+
92
+ 9. Commit the file. The version is what a score's `strategyVersion` points at, so a bump with no commit leaves scores pointing at a rubric nobody else has.
93
+
94
+ ### Interview questions
95
+
96
+ One question produces one section. Ask them in this order; each answer is one to four lines.
97
+
98
+ | Ask | Write into |
99
+ |---|---|
100
+ | What are you optimising this month? Name the outcome, not the feature. | `## Current themes` |
101
+ | What must a bead change to be worth doing now? | `## What counts as value` |
102
+ | When should a score be distrusted — which evidence is missing? | `## How to judge confidence` |
103
+ | What are you deliberately not doing this month, however good it looks? | `## Explicitly out of scope` |
104
+ | How long did comparable work take recently? Anchor the effort scale to it. | `## How to calibrate effort` |
105
+
106
+ The confidence question matters as much as the other four: effort and impact estimates are judgements, and the strategy is the only place the owner states how far to trust one.
107
+
108
+ ## The scripts
109
+
110
+ Two scripts, four subcommands, zero dependencies, no tracker access. `strategy.mjs` reads and writes the strategy file; `challenge.mjs` reads it and prints a trail entry. No run creates, tags or closes a bead.
111
+
112
+ | Command | Behaviour | Exit |
113
+ |---|---|---|
114
+ | `init` | Writes the template, stamped with today's date; refuses an existing file | 0 written, 1 refused |
115
+ | `validate` | Checks the version integer, the date, the change log and every required section; prints the file to stdout when valid | 0 valid, 1 invalid |
116
+ | `bump` | Refuses an invalid file or an empty `--reason`, raises the version by one, records today, appends the change-log line | 0 bumped, 1 refused |
117
+ | `record` (`challenge.mjs`) | Refuses an order or a resolution the strategy does not support; prints one bead-trail entry | 0 recorded, 1 refused |
118
+
119
+ `validate` splits its output: status and errors go to stderr, the rubric goes to stdout. `validate > rubric.md` captures the rubric alone, which is how a scorer loads it. A failing run names the file and lists one line per defect, so one fix round clears the whole file.
120
+
121
+ The date is checked as a **calendar** date, not as a shape. `2026-02-31` and `2026-04-31` fail in both `validate` and `--today`, because V8's ISO parser rolls them into the next month and accepts them; `2024-02-29` passes and `2026-02-29` does not. A rolled date records a change on a day it did not happen.
122
+
123
+ Exit code 2 means a malformed call — an unknown subcommand or a bad `--today`. `--today YYYY-MM-DD` exists so a test pins the recorded date; a person accepts the default.
124
+
125
+ ## Hand edits and forgotten bumps
126
+
127
+ A hand edit that changes a section but forgets `bump` still passes `validate`: the shape is intact, so nothing can tell the content moved. The protection is the version a score records — a scorer stores the `strategyVersion` it scored against, so a reader compares the two numbers and re-scores when they differ. The change log closes the rest of the gap: `validate` fails when its newest line names a version the header does not, so a raised version with no recorded reason is caught.
128
+
129
+ ## Red Flags
130
+
131
+ - Red flag: moving the strategy into a bead, a label or a scratch file because it is "just a rubric".
132
+ - Red flag: editing a strategy and skipping `bump`, or hand-raising the version, so the record hides the change.
133
+ - Red flag: editing a score to satisfy a challenge, instead of changing the rubric that produced it.
134
+ - Red flag: scoring against a file whose `validate` was never run — a malformed rubric scores silently.
135
+
136
+ ## Verification checklist
137
+
138
+ - [ ] `node <skill-scripts>/strategy.mjs validate` exits 0 and printed the rubric, and every section carries the owner's words.
139
+ - [ ] The version is one higher than the previous file for an update, or `1` for a new one, and the change log names it.
140
+ - [ ] A challenged order moved only after a bump, and the record names what moved.
141
+ - [ ] `git ls-files --error-unmatch .agent-cortex/working-docs/strategy.md` succeeds.
142
+ - [ ] No bead was created, tagged or closed by this skill.
143
+
144
+ ## See Also
145
+
146
+ - [CHALLENGE.md](CHALLENGE.md) — the sequence, the refusals and the no-change path when the order is challenged.
147
+ - [plan](../../workflow/plan/SKILL.md) — shapes one feature into beads; this skill orders the beads that exist.
148
+ - [bd-tool](../../productivity/bd-tool/SKILL.md) — where operational state lives, and why a durable document does not belong there.
149
+ - [score-bead](../../workflow/score-bead/SKILL.md) — turns this rubric into a RICE record on a bead.
150
+ - [hitl-collab](../../workflow/hitl-collab/SKILL.md) — the handoff document that shares the working-docs root with the strategy.