cclaw-cli 0.31.0 → 0.33.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.
@@ -0,0 +1,292 @@
1
+ /**
2
+ * Per-harness parity playbooks.
3
+ *
4
+ * cclaw's subagent contracts (planner / reviewer / security-reviewer /
5
+ * test-author / doc-updater) assume Claude-style isolated workers. On
6
+ * harnesses without that primitive, the agent has to fulfil the role via a
7
+ * documented fallback (generic Task dispatch, role-switch in-session, …).
8
+ *
9
+ * Each playbook is:
10
+ * 1. short (≤ ~150 lines markdown),
11
+ * 2. executable — reproducible by an agent without reading the whole repo,
12
+ * 3. evidence-first — always records a delegation-log entry with
13
+ * `fulfillmentMode` and `evidenceRefs` so `cclaw doctor` can tell the
14
+ * role was actually performed.
15
+ *
16
+ * Playbooks are materialised at
17
+ * `.cclaw/references/harnesses/<harness>-playbook.md` by install/sync/upgrade.
18
+ */
19
+ import { HARNESS_ADAPTERS } from "../harness-adapters.js";
20
+ export const HARNESS_PLAYBOOKS_DIR = "references/harnesses";
21
+ export function harnessPlaybookRelativePath(harness) {
22
+ return `${HARNESS_PLAYBOOKS_DIR}/${harness}-playbook.md`;
23
+ }
24
+ export function harnessPlaybookFileName(harness) {
25
+ return `${harness}-playbook.md`;
26
+ }
27
+ const CLAUDE_PLAYBOOK = `---
28
+ harness: claude
29
+ fallback: native
30
+ description: "Claude Code has real isolated subagent workers with user-defined named types. No fallback required — this playbook is reference-only."
31
+ ---
32
+
33
+ # Claude Code — Parity Playbook
34
+
35
+ **Status: native.** Claude Code supports isolated subagent workers via the
36
+ \`Task\` tool with user-defined \`subagent_type\` (\`planner\`, \`reviewer\`,
37
+ \`security-reviewer\`, \`test-author\`, \`doc-updater\`). Each dispatch runs in
38
+ its own context and produces a return message visible only to the parent
39
+ agent.
40
+
41
+ This playbook exists so the harness matrix has one reference shape; Claude
42
+ itself has no parity gap to close.
43
+
44
+ ## Dispatch pattern
45
+
46
+ 1. Pick the \`subagent_type\` matching the cclaw agent (e.g. \`reviewer\`).
47
+ 2. Provide a specific, self-contained \`prompt\` — the subagent cannot see
48
+ prior assistant turns.
49
+ 3. Record a delegation entry before dispatch:
50
+
51
+ \`\`\`json
52
+ {
53
+ "stage": "review",
54
+ "agent": "reviewer",
55
+ "mode": "mandatory",
56
+ "status": "scheduled",
57
+ "fulfillmentMode": "isolated",
58
+ "spanId": "dspan-..."
59
+ }
60
+ \`\`\`
61
+
62
+ 4. After the subagent returns, update the entry to \`status: "completed"\`
63
+ and attach \`evidenceRefs\` pointing at the artifact section that
64
+ captures the subagent's output.
65
+
66
+ ## Verification
67
+
68
+ \`cclaw doctor\` will pass the \`delegation:mandatory:current_stage\` check
69
+ when each mandatory agent has a \`completed\` row for the active run.
70
+ `;
71
+ const CURSOR_PLAYBOOK = `---
72
+ harness: cursor
73
+ fallback: generic-dispatch
74
+ description: "Cursor has a generic Task dispatcher with subagent_type (generalPurpose, explore, shell, …) but no user-defined named subagents. cclaw maps planner/reviewer/test-author/… onto generic dispatch with a structured role prompt."
75
+ ---
76
+
77
+ # Cursor — Parity Playbook
78
+
79
+ **Fallback: generic-dispatch.** Cursor's \`Task\` tool supports
80
+ \`subagent_type\` from a fixed vocabulary (\`generalPurpose\`, \`explore\`,
81
+ \`shell\`, \`browser-use\`, …). Real isolation, but no user-defined agent
82
+ names. cclaw closes the gap by mapping each named cclaw agent onto the
83
+ generic dispatcher with a strict role prompt.
84
+
85
+ ## Named-agent → Cursor subagent_type map
86
+
87
+ | cclaw agent | Cursor \`subagent_type\` | Readonly? | Rationale |
88
+ |----------------------|-------------------------|-----------|-----------|
89
+ | \`planner\` | \`explore\` | yes | Pure research, no writes. |
90
+ | \`reviewer\` | \`explore\` | yes | Reads diff + context, emits findings. |
91
+ | \`security-reviewer\`| \`explore\` | yes | Reads code, produces report; no fixes. |
92
+ | \`test-author\` | \`generalPurpose\` | no | Writes tests, runs them, iterates. |
93
+ | \`doc-updater\` | \`generalPurpose\` | no | Edits docs, re-runs build. |
94
+
95
+ ## Dispatch pattern
96
+
97
+ 1. Pick the mapped \`subagent_type\` from the table above.
98
+ 2. Build the \`prompt\` from the cclaw agent contract in
99
+ \`.cclaw/agents/<agent>.md\`, prefaced with a single line naming the
100
+ cclaw role (\`You are the cclaw <agent>. Follow the contract below.\`).
101
+ 3. Set \`readonly: true\` when the table says yes — Cursor enforces it.
102
+ 4. Before dispatch, append a delegation row:
103
+
104
+ \`\`\`json
105
+ {
106
+ "stage": "tdd",
107
+ "agent": "test-author",
108
+ "mode": "mandatory",
109
+ "status": "scheduled",
110
+ "fulfillmentMode": "generic-dispatch",
111
+ "spanId": "dspan-..."
112
+ }
113
+ \`\`\`
114
+
115
+ 5. After dispatch returns, transition the row to \`completed\` with
116
+ \`evidenceRefs\` citing the artifact anchor where the result landed.
117
+
118
+ ## Why not upgrade Cursor to a full tier-1?
119
+
120
+ Cursor has dispatch + hooks + \`AskQuestion\`. The missing piece is
121
+ **user-defined named subagents**. Semantically this is the difference
122
+ between Claude's \`test-author\` (a distinct runtime worker registered by
123
+ cclaw) and Cursor's \`generalPurpose\` worker that cclaw *asks* to act as a
124
+ test-author. Good enough for parity; different enough to keep the labels
125
+ honest.
126
+
127
+ ## Verification
128
+
129
+ \`cclaw doctor\` passes when the delegation row exists with
130
+ \`fulfillmentMode: "generic-dispatch"\` (or \`completed\` rows for the
131
+ mandatory agents in general). No evidenceRef requirement applies here —
132
+ Cursor dispatch is real isolation.
133
+ `;
134
+ const OPENCODE_PLAYBOOK = `---
135
+ harness: opencode
136
+ fallback: role-switch
137
+ description: "OpenCode has plugin-based dispatch hooks but no isolated subagent worker primitive. cclaw uses an in-session role-switch with a delegation-log entry + evidenceRefs."
138
+ ---
139
+
140
+ # OpenCode — Parity Playbook
141
+
142
+ **Fallback: role-switch.** OpenCode exposes tool/session event hooks via a
143
+ plugin but does not provide an isolated subagent worker. cclaw closes the
144
+ delegation gate by role-switching inside the same session: the agent
145
+ announces the role, performs the work against the contract, and records
146
+ evidence.
147
+
148
+ ## Role-switch protocol
149
+
150
+ 1. Announce the role explicitly in a single message:
151
+
152
+ > Acting as cclaw **<agent>** per \`.cclaw/agents/<agent>.md\`. No other
153
+ > role may be assumed until the delegation row is closed.
154
+
155
+ 2. Execute the role's contract. Do NOT interleave other roles' work.
156
+ 3. Write the result into the stage artifact (e.g. TDD work lands in
157
+ \`.cclaw/artifacts/06-tdd.md\`).
158
+ 4. Append a delegation row:
159
+
160
+ \`\`\`json
161
+ {
162
+ "stage": "tdd",
163
+ "agent": "test-author",
164
+ "mode": "mandatory",
165
+ "status": "completed",
166
+ "fulfillmentMode": "role-switch",
167
+ "evidenceRefs": [
168
+ ".cclaw/artifacts/06-tdd.md#red-run",
169
+ ".cclaw/artifacts/06-tdd.md#green-run"
170
+ ],
171
+ "spanId": "dspan-..."
172
+ }
173
+ \`\`\`
174
+
175
+ 5. \`evidenceRefs\` **must** point at concrete artifact anchors — not
176
+ placeholder text. \`cclaw doctor\` will report \`missingEvidence\` if
177
+ the array is empty under a role-switch fallback.
178
+
179
+ ## Exception: OpenCode plugin dispatch
180
+
181
+ If the project configures a plugin-based dispatch path (e.g. a tool that
182
+ spawns a worker process), set \`fulfillmentMode: "generic-dispatch"\`
183
+ instead of \`role-switch\` and omit the role-announce step. evidenceRefs
184
+ remain optional but recommended.
185
+
186
+ ## Verification
187
+
188
+ \`cclaw doctor\` passes when every mandatory agent for the active stage
189
+ has either a \`completed\` row with evidenceRefs (role-switch) or a
190
+ \`completed\` row under plugin dispatch.
191
+ `;
192
+ const CODEX_PLAYBOOK = `---
193
+ harness: codex
194
+ fallback: role-switch
195
+ description: "OpenAI Codex has no subagent dispatch primitive. cclaw uses role-switch with evidenceRefs; silent auto-waiver is explicitly disabled."
196
+ ---
197
+
198
+ # OpenAI Codex — Parity Playbook
199
+
200
+ **Fallback: role-switch.** Codex has no subagent dispatch — neither named
201
+ nor generic. cclaw used to silently auto-waive mandatory delegations on
202
+ Codex; v0.33 disables that shortcut. The agent must role-switch in-session
203
+ and record evidence, or the delegation gate blocks stage completion.
204
+
205
+ ## Role-switch protocol
206
+
207
+ Identical to OpenCode. Key requirements:
208
+
209
+ 1. **Explicit announce.** Before performing the role, emit a single
210
+ message naming the role and citing \`.cclaw/agents/<agent>.md\`.
211
+ 2. **No role interleaving.** Do not mix, for example, reviewer and
212
+ test-author work into the same turn — close one delegation before
213
+ opening another.
214
+ 3. **EvidenceRefs are mandatory.** Under Codex's role-switch fallback a
215
+ \`completed\` row without \`evidenceRefs\` is treated as
216
+ \`missingEvidence\` by \`cclaw doctor\` and blocks the gate.
217
+
218
+ ## Stage-specific role maps
219
+
220
+ | Stage | Mandatory roles | Artifact to cite in evidenceRefs |
221
+ |------------|----------------------------------|--------------------------------------|
222
+ | scope | \`planner\` | \`.cclaw/artifacts/02-scope.md\` |
223
+ | design | \`planner\` | \`.cclaw/artifacts/03-design.md\` |
224
+ | plan | \`planner\` | \`.cclaw/artifacts/05-plan.md\` |
225
+ | tdd | \`test-author\` | \`.cclaw/artifacts/06-tdd.md\` |
226
+ | review | \`reviewer\`, \`security-reviewer\` | \`.cclaw/artifacts/07-review.md\` |
227
+ | ship | \`doc-updater\` | \`.cclaw/artifacts/08-ship.md\` |
228
+
229
+ ## Why no auto-waiver anymore?
230
+
231
+ Silent auto-waiver on Codex let entire stages complete without any
232
+ reviewer or test-author work. That defeats cclaw's hard gates. v0.33
233
+ replaces it with an explicit role-switch obligation: the agent still gets
234
+ a path forward, but the path is visible in the delegation log.
235
+
236
+ If a team genuinely wants to skip a delegation on Codex, they must
237
+ manually append a \`status: "waived"\` row with a one-line
238
+ \`waiverReason\` — the same audit trail any Claude/Cursor install would
239
+ need.
240
+
241
+ ## Verification
242
+
243
+ \`cclaw doctor\` passes when every mandatory agent for the active stage
244
+ has a \`completed\` row with \`fulfillmentMode: "role-switch"\` and at
245
+ least one \`evidenceRef\`.
246
+ `;
247
+ const PLAYBOOK_BY_HARNESS = {
248
+ claude: CLAUDE_PLAYBOOK,
249
+ cursor: CURSOR_PLAYBOOK,
250
+ opencode: OPENCODE_PLAYBOOK,
251
+ codex: CODEX_PLAYBOOK
252
+ };
253
+ export function harnessPlaybookMarkdown(harness) {
254
+ const body = PLAYBOOK_BY_HARNESS[harness];
255
+ if (!body) {
256
+ throw new Error(`No playbook defined for harness "${harness}".`);
257
+ }
258
+ return body;
259
+ }
260
+ export function harnessPlaybooksIndexMarkdown() {
261
+ const rows = Object.keys(HARNESS_ADAPTERS)
262
+ .map((h) => {
263
+ const fallback = HARNESS_ADAPTERS[h].capabilities.subagentFallback;
264
+ return `| \`${h}\` | ${fallback} | [\`${harnessPlaybookFileName(h)}\`](./${harnessPlaybookFileName(h)}) |`;
265
+ })
266
+ .join("\n");
267
+ return `# Harness parity playbooks
268
+
269
+ Each playbook describes the concrete pattern cclaw expects when the
270
+ harness does not natively satisfy a mandatory delegation contract.
271
+
272
+ | Harness | Fallback | Playbook |
273
+ |---|---|---|
274
+ ${rows}
275
+
276
+ ## How cclaw uses these files
277
+
278
+ - \`cclaw doctor\` verifies that every installed harness has its playbook
279
+ present under \`.cclaw/references/harnesses/\`.
280
+ - Stage skills (TDD, review, ship) cite the active harness's playbook
281
+ instead of inlining the fallback pattern.
282
+ - The \`delegation:mandatory:current_stage\` check expects
283
+ \`fulfillmentMode\` to match the harness's declared \`subagentFallback\`
284
+ (\`isolated\`, \`generic-dispatch\`, or \`role-switch\`).
285
+
286
+ ## When to edit
287
+
288
+ Playbooks are generated by \`cclaw upgrade\`. Local edits are overwritten.
289
+ To customise the parity pattern for a specific repository, override the
290
+ skill that cites the playbook, not the playbook itself.
291
+ `;
292
+ }
@@ -1,5 +1,6 @@
1
1
  import { HARNESS_ADAPTERS, harnessTier } from "../harness-adapters.js";
2
2
  import { HOOK_EVENTS_BY_HARNESS, HOOK_SEMANTIC_EVENTS } from "./hook-events.js";
3
+ import { HARNESS_PLAYBOOKS_DIR, harnessPlaybookFileName } from "./harness-playbooks.js";
3
4
  function harnessTitle(harness) {
4
5
  switch (harness) {
5
6
  case "claude":
@@ -25,7 +26,9 @@ export function harnessIntegrationDocMarkdown() {
25
26
  .map((harness) => {
26
27
  const adapter = HARNESS_ADAPTERS[harness];
27
28
  const tier = harnessTier(harness);
28
- return `| ${harnessTitle(harness)} | \`${harness}\` | \`${tier}\` (${tierDescription(tier)}) | ${adapter.capabilities.nativeSubagentDispatch} | ${adapter.capabilities.hookSurface} | ${adapter.capabilities.structuredAsk} |`;
29
+ const caps = adapter.capabilities;
30
+ const playbook = `\`${HARNESS_PLAYBOOKS_DIR}/${harnessPlaybookFileName(harness)}\``;
31
+ return `| ${harnessTitle(harness)} | \`${harness}\` | \`${tier}\` (${tierDescription(tier)}) | ${caps.nativeSubagentDispatch} | ${caps.subagentFallback} | ${caps.hookSurface} | ${caps.structuredAsk} | ${playbook} |`;
29
32
  })
30
33
  .join("\n");
31
34
  const hookRows = HOOK_SEMANTIC_EVENTS.map((eventName) => {
@@ -43,10 +46,17 @@ Generated from \`src/harness-adapters.ts\` capabilities and hook event mappings.
43
46
 
44
47
  ## Capability tiers
45
48
 
46
- | Harness | ID | Tier | Native subagent dispatch | Hook surface | Structured ask |
47
- |---|---|---|---|---|---|
49
+ | Harness | ID | Tier | Native dispatch | Fallback | Hook surface | Structured ask | Playbook |
50
+ |---|---|---|---|---|---|---|---|
48
51
  ${capabilityRows}
49
52
 
53
+ Fallback legend:
54
+
55
+ - \`native\` — first-class named subagent dispatch (Claude).
56
+ - \`generic-dispatch\` — generic Task dispatcher mapped to cclaw roles (Cursor).
57
+ - \`role-switch\` — in-session role announce + delegation-log entry with evidenceRefs (OpenCode, Codex).
58
+ - \`waiver\` — no parity path; reserved for harnesses that cannot role-switch (none shipped).
59
+
50
60
  ## Semantic hook event coverage
51
61
 
52
62
  | Event | Claude | Cursor | OpenCode | Codex |
@@ -33,7 +33,7 @@ This is the only progression command the user needs to drive the entire flow. St
33
33
 
34
34
  - **Do not** invent gate completion: use only \`${flowPath}\` plus observable evidence in repo artifacts.
35
35
  - **Do not** skip stages: advance only from \`currentStage\` to its configured successor.
36
- - If the flow reaches terminal ship completion, route closeout in order: **/cc-ops retro -> /cc-ops compound (optional) -> /cc-ops archive**.
36
+ - After ship completes, the closeout chain **retro -> compound -> archive** runs automatically, driven by \`closeout.shipSubstate\`. Do not ask the user to type those commands manually — follow the substate switch in Path B below.
37
37
 
38
38
  ## Algorithm (mandatory)
39
39
 
@@ -55,9 +55,24 @@ This is the only progression command the user needs to drive the entire flow. St
55
55
  ### Path B: Current stage IS complete (all gates passed, all delegations satisfied)
56
56
 
57
57
  → If current stage's \`next\` is **\`done\`**:
58
- - if \`currentStage === "ship"\` and \`retro.completedAt\` is missing -> route to \`/cc-ops retro\`,
59
- - if \`currentStage === "ship"\` and \`retro.completedAt\` is present -> suggest \`/cc-ops compound\` then route to \`/cc-ops archive\`,
60
- - otherwise report **"Flow complete. All stages finished."** and stop.
58
+
59
+ When \`currentStage === "ship"\`, route by **\`closeout.shipSubstate\`**:
60
+ - \`"idle"\` or missing -> set \`closeout.shipSubstate = "retro_review"\`, then
61
+ load \`${RUNTIME_ROOT}/commands/retro.md\` + \`${RUNTIME_ROOT}/skills/flow-retro/SKILL.md\`
62
+ and execute the retro protocol (draft + one structured accept/edit/skip ask).
63
+ - \`"retro_review"\` -> continue the retro protocol (re-ask the structured
64
+ question; the draft already exists — do not regenerate it).
65
+ - \`"compound_review"\` -> load \`${RUNTIME_ROOT}/commands/compound.md\` +
66
+ \`${RUNTIME_ROOT}/skills/flow-compound/SKILL.md\`, execute the compound
67
+ scan, ask user **one** structured question (apply / skip) per candidate
68
+ cluster or a single accept-all / skip choice, and advance substate on
69
+ completion or skip.
70
+ - \`"ready_to_archive"\` -> load \`${RUNTIME_ROOT}/commands/archive.md\` +
71
+ \`${RUNTIME_ROOT}/skills/flow-archive/SKILL.md\`, run archive, reset state.
72
+ - \`"archived"\` (transient) -> report "run archived" and stop.
73
+
74
+ Otherwise report **"Flow complete. All stages finished."** and stop.
75
+
61
76
  → Otherwise: load **\`${RUNTIME_ROOT}/skills/<skillFolder>/SKILL.md\`** and **\`${RUNTIME_ROOT}/commands/<nextStage>.md\`** for the successor stage. Execute that stage's protocol.
62
77
 
63
78
  ### Track-aware successor resolution
@@ -74,6 +89,9 @@ This is the only progression command the user needs to drive the entire flow. St
74
89
  \`/cc-next\` in a **new session** = resume from where you left off:
75
90
  - Flow-state records \`currentStage\` and which gates have passed.
76
91
  - The stage skill reads upstream artifacts and picks up context.
92
+ - \`closeout.shipSubstate\` carries the post-ship substate, so a crashed
93
+ session during retro/compound/archive resumes at the exact step without
94
+ regenerating the retro draft.
77
95
  - No special resume command needed — \`/cc-next\` IS the resume command.
78
96
 
79
97
  ## Primary skill
@@ -149,11 +167,25 @@ Execute the stage protocol. The stage skill handles interaction, STOP points, ga
149
167
 
150
168
  If \`next\` is \`done\`:
151
169
 
152
- - If \`currentStage\` is \`ship\` and \`retro.completedAt\` is missing -> route to \`/cc-ops retro\`.
153
- - If \`currentStage\` is \`ship\` and \`retro.completedAt\` exists -> suggest \`/cc-ops compound\`, then route to \`/cc-ops archive\`.
154
- - Otherwise report **"Flow complete. All stages finished."** and stop.
170
+ When \`currentStage\` is \`ship\`, automatically drive the **closeout chain**
171
+ by inspecting \`closeout.shipSubstate\`:
172
+
173
+ | shipSubstate | Action |
174
+ |-----------------------|-----------------------------------------------------|
175
+ | \`idle\` / missing | Flip to \`retro_review\` and start retro protocol |
176
+ | \`retro_review\` | Continue retro protocol (re-ask accept/edit/skip) |
177
+ | \`compound_review\` | Run compound scan with a single approve/skip ask |
178
+ | \`ready_to_archive\` | Run archive skill; reset flow-state on success |
179
+ | \`archived\` | Report "run archived"; stop |
180
+
181
+ Each step owns its own state transition. \`/cc-next\` never shells out to
182
+ \`cclaw doctor\` or \`cclaw archive\` automatically — it loads the matching
183
+ skill and command contract and executes the protocol in-session.
184
+
185
+ Otherwise report **"Flow complete. All stages finished."** and stop.
155
186
 
156
- Otherwise load the next stage's skill and command contract, begin execution.
187
+ Otherwise (non-terminal \`next\`): load the next stage's skill and command
188
+ contract, begin execution.
157
189
 
158
190
  ## Stage order
159
191
 
@@ -46,20 +46,47 @@ Shared closeout sequence applied by every stage skill.
46
46
  - update \`guardEvidence\`.
47
47
  3. Persist stage artifact under \`.cclaw/artifacts/\`.
48
48
  4. Run \`npx cclaw doctor\` and resolve failures.
49
- 5. Capture reusable learnings from this stage artifact:
50
- - append 1-3 strict-schema JSONL entries when the stage produced non-obvious
51
- decisions, patterns, or lessons,
52
- - use \`type=rule|pattern|lesson\` (\`compound\` stays retro-focused).
49
+ 5. **Capture through-flow learnings** see the policy below. Knowledge
50
+ accrues continuously across stages, not just at retro.
53
51
  6. Notify user with stage completion and next action (\`/cc-next\`).
54
52
  7. Stop; do not auto-run the next stage unless user asks.
55
53
 
54
+ ## Through-flow knowledge capture
55
+
56
+ Knowledge is recorded **throughout the run**, not saved up for retro.
57
+ Each stage contributes a different kind of insight:
58
+
59
+ | Stage | Typical \`type\` | What to capture |
60
+ |-------------|-----------------|-------------------------------------------------------|
61
+ | brainstorm | \`lesson\` | rejected framings and why (only when non-obvious) |
62
+ | scope | \`rule\` | explicit out-of-scope boundaries worth remembering |
63
+ | design | \`pattern\` | architectural trade-offs and their rationale |
64
+ | spec | \`rule\` | non-negotiable acceptance criteria shape |
65
+ | plan | \`pattern\` | effective decomposition / risk-ordering heuristics |
66
+ | tdd | \`pattern\` | red→green→refactor cycle lessons, test-design notes |
67
+ | review | \`lesson\` | recurring defects / blockers caught in this codebase |
68
+ | ship | \`lesson\` | rollback triggers, preflight gotchas |
69
+ | retro | \`compound\` | process accelerators for the **next** run |
70
+
71
+ Rules:
72
+
73
+ - Append 1–3 strict-schema JSONL lines to \`.cclaw/knowledge.jsonl\` per
74
+ stage when that stage produced non-obvious decisions, patterns, or
75
+ lessons. Obvious restatements of the checklist do not count.
76
+ - Use \`type=rule|pattern|lesson\` during stages; reserve \`type=compound\`
77
+ for the retro step so the retro vs. through-flow signal stays
78
+ distinguishable.
79
+ - Set \`origin_stage\` to the stage that emitted the entry and
80
+ \`origin_feature\` to the active feature slug.
81
+
56
82
  ## Automatic learning capture policy
57
83
 
58
84
  - \`standard\` / \`medium\` tracks: required for \`design\`, \`tdd\`, and \`review\`;
59
85
  recommended for other stages.
60
86
  - \`quick\` track: recommended only (avoid overhead for tiny fixes).
61
87
  - "No learning captured" is acceptable only when explicitly justified (e.g. pure
62
- mechanical change, no new trade-offs).
88
+ mechanical change, no new trade-offs). Record the justification in the
89
+ stage artifact, not in knowledge.jsonl.
63
90
 
64
91
  ## Resume protocol
65
92
 
@@ -108,9 +135,13 @@ No release shortcuts:
108
135
 
109
136
  ## 6) Compound, Don't Repeat
110
137
 
111
- When a reusable lesson appears, add one strict-schema JSONL entry via
112
- \`/cc-learn add\`. Repeated lessons should be lifted into stable rules/skills so
113
- the same class of mistake gets harder to repeat.
138
+ Knowledge is recorded **throughout** the run, not saved for the retro.
139
+ When a reusable lesson appears in design, plan, tdd, or review, append one
140
+ strict-schema JSONL entry to \`.cclaw/knowledge.jsonl\` using
141
+ \`type=rule|pattern|lesson\`. Reserve \`type=compound\` for post-ship retro.
142
+ Repeated lessons (frequency ≥ 3) are lifted into stable
143
+ rules/protocols/skills during the automatic compound pass so the same
144
+ class of mistake gets harder to repeat.
114
145
 
115
146
  ## Turn Announce Discipline
116
147
 
@@ -15,28 +15,62 @@ export function retroCommandContract() {
15
15
 
16
16
  ## Purpose
17
17
 
18
- Mandatory retrospective gate before archive once ship is complete.
18
+ Auto-triggered retrospective after ship. \`/cc-next\` drafts \`${retroArtifactPath()}\`
19
+ from run artifacts and knowledge, then asks the user exactly ONE structured
20
+ question: **edit / accept / skip**. Default = accept.
21
+
22
+ This command is normally invoked indirectly by \`/cc-next\` when
23
+ \`closeout.shipSubstate === "retro_review"\`. Invoking it directly is still
24
+ supported for manual re-runs.
19
25
 
20
26
  ## HARD-GATE
21
27
 
22
- - Do not mark retro complete without writing \`${retroArtifactPath()}\`.
23
- - Do not finish retro without appending at least one \`type=compound\` entry into \`${knowledgePath()}\`.
28
+ - Do not finalize retro without \`${retroArtifactPath()}\` on disk (or an explicit
29
+ \`retroSkipped: true\` in closeout with a one-line reason).
30
+ - Do not finalize without appending **at least one** \`type=compound\` entry to
31
+ \`${knowledgePath()}\` (skipped runs set \`compoundEntries: 0\` instead).
32
+ - Never advance to compound/archive with \`shipSubstate\` still at
33
+ \`"retro_review"\`.
34
+
35
+ ## Inputs
36
+
37
+ \`/cc-ops retro\` (no flags). If the user wants to skip, they answer **skip**
38
+ in the structured ask; there is no \`--skip\` flag.
24
39
 
25
40
  ## Algorithm
26
41
 
27
- 1. Read \`${flowStatePath()}\`; confirm ship stage is complete for current run.
28
- 2. Synthesize retrospective artifact \`${retroArtifactPath()}\` with:
29
- - what slowed this run
30
- - what accelerated this run
31
- - concrete repeatable rule for next run
32
- 3. Append >=1 strict-schema JSONL entry to \`${knowledgePath()}\` with:
33
- - \`type: "compound"\`
34
- - \`stage: "ship"\` or \`"retro"\`
35
- 4. Update flow-state \`retro\` block:
36
- - \`required: true\`
37
- - \`completedAt: <ISO>\`
38
- - \`compoundEntries: <count>\`
39
- 5. Report completion summary and remind user that \`/cc-ops compound\` (optional) can lift repeated learnings before \`/cc-ops archive\`.
42
+ 1. Read \`${flowStatePath()}\`; confirm \`completedStages\` contains \`"ship"\`.
43
+ 2. If \`closeout.shipSubstate !== "retro_review"\`, and \`retro.completedAt\`
44
+ is already set, report "retro already complete" and stop.
45
+ 3. Draft \`${retroArtifactPath()}\` from available evidence:
46
+ - scan \`.cclaw/artifacts/01..08-*.md\` for decisions, blockers, rewinds,
47
+ - scan \`.cclaw/state/delegation-log.json\` for subagent outcomes,
48
+ - scan \`${knowledgePath()}\` for entries recorded during this run,
49
+ - structure the draft as: Outcomes / Slowed / Accelerated / Repeatable rule.
50
+ 4. Update \`closeout.retroDraftedAt = <ISO>\` in flow-state.
51
+ 5. Present **one** structured ask (AskUserQuestion on Claude, AskQuestion on
52
+ Cursor, plain-text options elsewhere):
53
+ - \`accept\` (default) — keep the draft as-is,
54
+ - \`edit\` user edits \`${retroArtifactPath()}\` in-place, then re-runs \`/cc-next\`,
55
+ - \`skip\` — record \`retroSkipped: true\` + one-line reason, no compound entry required.
56
+ 6. On **accept**:
57
+ - append >=1 strict-schema JSONL line to \`${knowledgePath()}\` with
58
+ \`type: "compound"\` and \`stage: "retro"\`,
59
+ - set \`retro.required = true\`, \`retro.completedAt = <ISO>\`,
60
+ \`retro.compoundEntries = <count>\`,
61
+ - set \`closeout.retroAcceptedAt = <ISO>\`,
62
+ - set \`closeout.shipSubstate = "compound_review"\`.
63
+ 7. On **edit**:
64
+ - leave \`shipSubstate = "retro_review"\`,
65
+ - tell user to edit \`${retroArtifactPath()}\` and run \`/cc-next\` again.
66
+ 8. On **skip**:
67
+ - require a one-line reason; if empty, re-ask once then escalate,
68
+ - set \`closeout.retroSkipped = true\`, \`closeout.retroSkipReason = <text>\`,
69
+ \`closeout.retroAcceptedAt = <ISO>\`,
70
+ - set \`retro.completedAt = <ISO>\` (marks gate satisfied for archive), and
71
+ \`retro.compoundEntries = 0\`,
72
+ - set \`closeout.shipSubstate = "compound_review"\`.
73
+ 9. Emit a one-line summary: \`retro: accepted|edited|skipped | next: /cc-next\`.
40
74
 
41
75
  ## Primary skill
42
76
 
@@ -46,33 +80,71 @@ Mandatory retrospective gate before archive once ship is complete.
46
80
  export function retroCommandSkillMarkdown() {
47
81
  return `---
48
82
  name: ${RETRO_SKILL_NAME}
49
- description: "Run mandatory retrospective and record compound knowledge before archive."
83
+ description: "Auto-drafted retrospective with a single structured accept/edit/skip ask. Triggered from /cc-next when shipSubstate=retro_review."
50
84
  ---
51
85
 
52
86
  # /cc-ops retro
53
87
 
54
88
  ## HARD-GATE
55
89
 
56
- Archive must remain blocked until retro artifact exists and compound knowledge was appended.
90
+ Archive stays blocked until one of:
91
+ - retro artifact exists **and** one compound knowledge entry was appended, OR
92
+ - retro was explicitly skipped with a one-line reason recorded in closeout.
93
+
94
+ Do not silently skip. Do not finalize without updating \`flow-state.json\`.
57
95
 
58
96
  ## Protocol
59
97
 
60
- 1. Confirm ship completion from \`${flowStatePath()}\`.
61
- 2. Create/update \`${retroArtifactPath()}\` with concise retrospective sections:
62
- - outcomes
63
- - bottlenecks
64
- - reusable acceleration patterns
65
- 3. Append at least one \`compound\` knowledge entry into \`${knowledgePath()}\`.
66
- 4. Update \`flow-state.json.retro\` with completion timestamp + compound count.
67
- 5. Print explicit completion line:
68
- - \`retro gate: complete\`
69
- - \`compound entries added: <N>\`
70
- - \`next: /cc-ops compound (optional) -> /cc-ops archive\`
98
+ 1. Confirm ship completion by reading \`${flowStatePath()}\`.
99
+ 2. If retro draft does not yet exist, synthesise \`${retroArtifactPath()}\` using:
100
+ - all \`.cclaw/artifacts/*-*.md\` from the active run (stages 01–08),
101
+ - \`.cclaw/state/delegation-log.json\` entries,
102
+ - \`${knowledgePath()}\` entries written during this run.
103
+ Draft sections:
104
+ - **Outcomes** what was actually shipped.
105
+ - **Slowed** concrete friction points (cite artifact line or delegation id).
106
+ - **Accelerated** patterns/decisions that worked and are worth keeping.
107
+ - **Repeatable rule** one candidate rule/pattern for next run.
108
+ Record \`closeout.retroDraftedAt\`.
109
+ 3. Ask the user **one** structured question via the harness question tool
110
+ (AskUserQuestion / AskQuestion / plain text fallback):
111
+
112
+ > Retro draft ready at \`${retroArtifactPath()}\`. How do you want to
113
+ > proceed? (default: accept)
114
+ >
115
+ > - **accept** — keep the draft and continue.
116
+ > - **edit** — I'll edit it, then re-run \`/cc-next\`.
117
+ > - **skip** — no retro this run (requires one-line reason).
118
+
119
+ 4. Apply the state transition for the chosen option:
120
+ - \`accept\` → append \`{ "type": "compound", "stage": "retro", ... }\` line
121
+ to \`${knowledgePath()}\`; set \`retro.completedAt\`, \`retro.compoundEntries\`,
122
+ \`closeout.retroAcceptedAt\`; set \`closeout.shipSubstate = "compound_review"\`.
123
+ - \`edit\` → leave \`shipSubstate = "retro_review"\`; announce resume path.
124
+ - \`skip\` → set \`closeout.retroSkipped\`, \`closeout.retroSkipReason\`,
125
+ \`closeout.retroAcceptedAt\`, \`retro.completedAt\`,
126
+ \`retro.compoundEntries = 0\`; set \`closeout.shipSubstate = "compound_review"\`.
127
+
128
+ 5. Print one-line completion summary:
129
+ - \`retro gate: accepted (<N> compound entries)\`
130
+ - \`retro gate: skipped (reason: <text>)\`
131
+ - \`retro gate: editing (re-run /cc-next when ready)\`
132
+
133
+ ## Resume semantics
134
+
135
+ A new session with \`closeout.shipSubstate === "retro_review"\` resumes
136
+ exactly here. If \`closeout.retroDraftedAt\` is present but
137
+ \`retroAcceptedAt\` is missing, re-ask the same structured question without
138
+ regenerating the draft.
71
139
 
72
140
  ## Validation
73
141
 
74
- - \`${retroArtifactPath()}\` exists and is non-empty.
75
- - \`${knowledgePath()}\` contains >=1 valid \`compound\` line.
76
- - \`retro.completedAt\` is set in flow-state.
142
+ - \`${retroArtifactPath()}\` exists and is non-empty, **or**
143
+ \`closeout.retroSkipped === true\` with a non-empty reason.
144
+ - When accepted: \`${knowledgePath()}\` gained a valid \`compound\` line
145
+ and \`retro.compoundEntries > 0\`.
146
+ - \`retro.completedAt\` is set.
147
+ - \`closeout.shipSubstate\` is \`"compound_review"\` (or still
148
+ \`"retro_review"\` when user picked \`edit\`).
77
149
  `;
78
150
  }