cclaw-cli 0.49.0 → 0.51.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/README.md +54 -82
  2. package/dist/artifact-linter.d.ts +4 -0
  3. package/dist/artifact-linter.js +24 -3
  4. package/dist/cli.d.ts +1 -19
  5. package/dist/cli.js +49 -491
  6. package/dist/constants.d.ts +2 -13
  7. package/dist/constants.js +1 -43
  8. package/dist/content/closeout-guidance.d.ts +14 -0
  9. package/dist/content/closeout-guidance.js +42 -0
  10. package/dist/content/core-agents.js +51 -9
  11. package/dist/content/decision-protocol.d.ts +12 -0
  12. package/dist/content/decision-protocol.js +20 -0
  13. package/dist/content/diff-command.d.ts +1 -2
  14. package/dist/content/diff-command.js +8 -94
  15. package/dist/content/examples.d.ts +4 -10
  16. package/dist/content/examples.js +10 -20
  17. package/dist/content/hook-events.js +2 -2
  18. package/dist/content/hook-inline-snippets.d.ts +5 -2
  19. package/dist/content/hook-inline-snippets.js +33 -1
  20. package/dist/content/hook-manifest.d.ts +3 -4
  21. package/dist/content/hook-manifest.js +11 -12
  22. package/dist/content/hooks.js +2 -0
  23. package/dist/content/ideate-command.d.ts +2 -0
  24. package/dist/content/ideate-command.js +31 -25
  25. package/dist/content/iron-laws.d.ts +5 -5
  26. package/dist/content/iron-laws.js +5 -5
  27. package/dist/content/learnings.d.ts +3 -4
  28. package/dist/content/learnings.js +24 -50
  29. package/dist/content/meta-skill.js +31 -21
  30. package/dist/content/next-command.js +38 -38
  31. package/dist/content/node-hooks.js +17 -343
  32. package/dist/content/opencode-plugin.js +2 -100
  33. package/dist/content/research-playbooks.js +14 -14
  34. package/dist/content/review-loop.d.ts +2 -0
  35. package/dist/content/review-loop.js +8 -0
  36. package/dist/content/session-hooks.js +14 -46
  37. package/dist/content/skills.d.ts +0 -5
  38. package/dist/content/skills.js +53 -128
  39. package/dist/content/stage-common-guidance.d.ts +0 -1
  40. package/dist/content/stage-common-guidance.js +15 -14
  41. package/dist/content/stage-schema.d.ts +26 -1
  42. package/dist/content/stage-schema.js +121 -40
  43. package/dist/content/stages/_lint-metadata/index.js +9 -15
  44. package/dist/content/stages/brainstorm.js +22 -43
  45. package/dist/content/stages/design.js +37 -57
  46. package/dist/content/stages/plan.js +22 -13
  47. package/dist/content/stages/review.js +24 -27
  48. package/dist/content/stages/scope.js +34 -46
  49. package/dist/content/stages/ship.js +7 -4
  50. package/dist/content/stages/spec.js +20 -9
  51. package/dist/content/stages/tdd.js +64 -44
  52. package/dist/content/start-command.js +10 -12
  53. package/dist/content/status-command.d.ts +2 -7
  54. package/dist/content/status-command.js +19 -146
  55. package/dist/content/subagents.d.ts +0 -5
  56. package/dist/content/subagents.js +47 -28
  57. package/dist/content/templates.d.ts +1 -1
  58. package/dist/content/templates.js +126 -135
  59. package/dist/content/track-render-context.d.ts +17 -0
  60. package/dist/content/track-render-context.js +44 -0
  61. package/dist/content/tree-command.d.ts +1 -2
  62. package/dist/content/tree-command.js +4 -87
  63. package/dist/content/utility-skills.d.ts +2 -29
  64. package/dist/content/utility-skills.js +2 -1534
  65. package/dist/content/view-command.js +29 -11
  66. package/dist/delegation.d.ts +1 -1
  67. package/dist/delegation.js +5 -15
  68. package/dist/doctor-registry.js +20 -21
  69. package/dist/doctor.js +88 -344
  70. package/dist/flow-state.d.ts +3 -0
  71. package/dist/flow-state.js +2 -0
  72. package/dist/harness-adapters.d.ts +1 -1
  73. package/dist/harness-adapters.js +48 -57
  74. package/dist/install.js +128 -358
  75. package/dist/internal/advance-stage.js +3 -9
  76. package/dist/internal/compound-readiness.d.ts +1 -1
  77. package/dist/internal/compound-readiness.js +1 -1
  78. package/dist/internal/tdd-loop-status.d.ts +1 -1
  79. package/dist/internal/tdd-loop-status.js +1 -1
  80. package/dist/knowledge-store.d.ts +16 -10
  81. package/dist/knowledge-store.js +51 -15
  82. package/dist/policy.js +16 -105
  83. package/dist/run-archive.d.ts +4 -6
  84. package/dist/run-archive.js +15 -20
  85. package/dist/run-persistence.d.ts +2 -2
  86. package/dist/run-persistence.js +3 -9
  87. package/package.json +1 -2
  88. package/dist/content/archive-command.d.ts +0 -2
  89. package/dist/content/archive-command.js +0 -124
  90. package/dist/content/compound-command.d.ts +0 -5
  91. package/dist/content/compound-command.js +0 -193
  92. package/dist/content/contexts.d.ts +0 -18
  93. package/dist/content/contexts.js +0 -24
  94. package/dist/content/contracts.d.ts +0 -2
  95. package/dist/content/contracts.js +0 -51
  96. package/dist/content/doctor-references.d.ts +0 -2
  97. package/dist/content/doctor-references.js +0 -150
  98. package/dist/content/eval-scaffold.d.ts +0 -15
  99. package/dist/content/eval-scaffold.js +0 -370
  100. package/dist/content/feature-command.d.ts +0 -2
  101. package/dist/content/feature-command.js +0 -123
  102. package/dist/content/flow-map.d.ts +0 -23
  103. package/dist/content/flow-map.js +0 -134
  104. package/dist/content/harness-doc.d.ts +0 -2
  105. package/dist/content/harness-doc.js +0 -202
  106. package/dist/content/harness-playbooks.d.ts +0 -24
  107. package/dist/content/harness-playbooks.js +0 -393
  108. package/dist/content/harness-tool-refs.d.ts +0 -20
  109. package/dist/content/harness-tool-refs.js +0 -268
  110. package/dist/content/ops-command.d.ts +0 -2
  111. package/dist/content/ops-command.js +0 -71
  112. package/dist/content/protocols.d.ts +0 -7
  113. package/dist/content/protocols.js +0 -215
  114. package/dist/content/retro-command.d.ts +0 -2
  115. package/dist/content/retro-command.js +0 -165
  116. package/dist/content/rewind-command.d.ts +0 -2
  117. package/dist/content/rewind-command.js +0 -106
  118. package/dist/content/tdd-log-command.d.ts +0 -2
  119. package/dist/content/tdd-log-command.js +0 -85
  120. package/dist/eval/agents/single-shot.d.ts +0 -27
  121. package/dist/eval/agents/single-shot.js +0 -79
  122. package/dist/eval/agents/with-tools.d.ts +0 -44
  123. package/dist/eval/agents/with-tools.js +0 -261
  124. package/dist/eval/agents/workflow.d.ts +0 -31
  125. package/dist/eval/agents/workflow.js +0 -155
  126. package/dist/eval/baseline.d.ts +0 -38
  127. package/dist/eval/baseline.js +0 -282
  128. package/dist/eval/config-loader.d.ts +0 -14
  129. package/dist/eval/config-loader.js +0 -395
  130. package/dist/eval/corpus.d.ts +0 -30
  131. package/dist/eval/corpus.js +0 -330
  132. package/dist/eval/cost-guard.d.ts +0 -102
  133. package/dist/eval/cost-guard.js +0 -190
  134. package/dist/eval/diff.d.ts +0 -64
  135. package/dist/eval/diff.js +0 -323
  136. package/dist/eval/llm-client.d.ts +0 -176
  137. package/dist/eval/llm-client.js +0 -267
  138. package/dist/eval/mode.d.ts +0 -28
  139. package/dist/eval/mode.js +0 -61
  140. package/dist/eval/progress.d.ts +0 -83
  141. package/dist/eval/progress.js +0 -59
  142. package/dist/eval/report.d.ts +0 -11
  143. package/dist/eval/report.js +0 -181
  144. package/dist/eval/rubric-loader.d.ts +0 -20
  145. package/dist/eval/rubric-loader.js +0 -143
  146. package/dist/eval/runner.d.ts +0 -81
  147. package/dist/eval/runner.js +0 -746
  148. package/dist/eval/runs.d.ts +0 -41
  149. package/dist/eval/runs.js +0 -114
  150. package/dist/eval/sandbox.d.ts +0 -38
  151. package/dist/eval/sandbox.js +0 -137
  152. package/dist/eval/tools/glob.d.ts +0 -2
  153. package/dist/eval/tools/glob.js +0 -163
  154. package/dist/eval/tools/grep.d.ts +0 -2
  155. package/dist/eval/tools/grep.js +0 -152
  156. package/dist/eval/tools/index.d.ts +0 -7
  157. package/dist/eval/tools/index.js +0 -35
  158. package/dist/eval/tools/read.d.ts +0 -2
  159. package/dist/eval/tools/read.js +0 -122
  160. package/dist/eval/tools/types.d.ts +0 -49
  161. package/dist/eval/tools/types.js +0 -41
  162. package/dist/eval/tools/write.d.ts +0 -2
  163. package/dist/eval/tools/write.js +0 -92
  164. package/dist/eval/types.d.ts +0 -561
  165. package/dist/eval/types.js +0 -47
  166. package/dist/eval/verifiers/judge.d.ts +0 -40
  167. package/dist/eval/verifiers/judge.js +0 -256
  168. package/dist/eval/verifiers/rules.d.ts +0 -24
  169. package/dist/eval/verifiers/rules.js +0 -218
  170. package/dist/eval/verifiers/structural.d.ts +0 -14
  171. package/dist/eval/verifiers/structural.js +0 -171
  172. package/dist/eval/verifiers/traceability.d.ts +0 -23
  173. package/dist/eval/verifiers/traceability.js +0 -84
  174. package/dist/eval/verifiers/workflow-consistency.d.ts +0 -21
  175. package/dist/eval/verifiers/workflow-consistency.js +0 -225
  176. package/dist/eval/workflow-corpus.d.ts +0 -7
  177. package/dist/eval/workflow-corpus.js +0 -207
  178. package/dist/feature-system.d.ts +0 -42
  179. package/dist/feature-system.js +0 -432
  180. package/dist/internal/knowledge-digest.d.ts +0 -7
  181. package/dist/internal/knowledge-digest.js +0 -93
@@ -45,6 +45,9 @@
45
45
  * - `countArchivedRunsInline` counts immediate subdirectories of
46
46
  * `<root>/.cclaw/runs/` so both the hook and the CLI see the same
47
47
  * `archivedRunsCount` for the small-project relaxation.
48
+ * - `formatCompoundReadinessLineInline` mirrors the one-line summary shape
49
+ * used by `src/internal/compound-readiness.ts::formatCompoundReadinessLine`
50
+ * so session-start and internal CLI command stay wording-compatible.
48
51
  */
49
52
  export const HOOK_INLINE_SHARED_HELPERS = `
50
53
  function normalizeCompoundLastUpdatedAt(date) {
@@ -65,6 +68,35 @@ async function countArchivedRunsInline(root) {
65
68
  return undefined;
66
69
  }
67
70
  }
71
+
72
+ function formatCompoundReadinessLineInline(readiness) {
73
+ if (!readiness || typeof readiness !== "object") {
74
+ return "";
75
+ }
76
+ const ready = Array.isArray(readiness.ready) ? readiness.ready : [];
77
+ const readyCount =
78
+ typeof readiness.readyCount === "number" && Number.isFinite(readiness.readyCount)
79
+ ? Math.trunc(readiness.readyCount)
80
+ : ready.length;
81
+ const clusterCount =
82
+ typeof readiness.clusterCount === "number" && Number.isFinite(readiness.clusterCount)
83
+ ? Math.trunc(readiness.clusterCount)
84
+ : 0;
85
+ const threshold =
86
+ typeof readiness.threshold === "number" && Number.isFinite(readiness.threshold)
87
+ ? Math.trunc(readiness.threshold)
88
+ : COMPOUND_RECURRENCE_THRESHOLD;
89
+ if (readyCount === 0) {
90
+ return "Compound readiness: no candidates (clusters=" +
91
+ String(clusterCount) + ", threshold=" + String(threshold) + ")";
92
+ }
93
+ const critical = ready.filter(
94
+ (entry) => entry && typeof entry === "object" && entry.severity === "critical"
95
+ ).length;
96
+ const criticalSuffix = critical > 0 ? " (critical=" + String(critical) + ")" : "";
97
+ return "Compound readiness: clusters=" + String(clusterCount) +
98
+ ", ready=" + String(readyCount) + criticalSuffix;
99
+ }
68
100
  `;
69
101
  /**
70
102
  * Inline mirror of `src/knowledge-store.ts::computeCompoundReadiness`.
@@ -127,7 +159,7 @@ async function computeCompoundReadinessInline(root, options) {
127
159
  let row;
128
160
  try { row = JSON.parse(line); } catch { continue; }
129
161
  if (!row || typeof row !== "object" || Array.isArray(row)) continue;
130
- if (row.maturity === "lifted-to-enforcement") continue;
162
+ if (row.maturity === "lifted-to-enforcement" || typeof row.superseded_by === "string") continue;
131
163
  const type = typeof row.type === "string" ? row.type : "";
132
164
  const trigger = typeof row.trigger === "string" ? row.trigger : "";
133
165
  const action = typeof row.action === "string" ? row.action : "";
@@ -21,7 +21,7 @@
21
21
  */
22
22
  export declare const HOOK_MANIFEST_HARNESSES: readonly ["claude", "cursor", "codex"];
23
23
  export type HookManifestHarness = (typeof HOOK_MANIFEST_HARNESSES)[number];
24
- export declare const HOOK_HANDLERS: readonly ["session-start", "prompt-guard", "workflow-guard", "context-monitor", "stop-checkpoint", "pre-compact", "verify-current-state"];
24
+ export declare const HOOK_HANDLERS: readonly ["session-start", "prompt-guard", "workflow-guard", "context-monitor", "stop-handoff", "pre-compact", "verify-current-state"];
25
25
  export type HookHandlerId = (typeof HOOK_HANDLERS)[number];
26
26
  export interface HookBinding {
27
27
  /**
@@ -52,7 +52,7 @@ export interface HookHandlerSpec {
52
52
  semantic: HookSemanticEvent | null;
53
53
  bindings: Partial<Record<HookManifestHarness, HookBinding[]>>;
54
54
  }
55
- export declare const HOOK_SEMANTIC_EVENTS: readonly ["session_rehydrate", "pre_tool_prompt_guard", "pre_tool_workflow_guard", "post_tool_context_monitor", "stop_checkpoint", "precompact_digest"];
55
+ export declare const HOOK_SEMANTIC_EVENTS: readonly ["session_rehydrate", "pre_tool_prompt_guard", "pre_tool_workflow_guard", "post_tool_context_monitor", "stop_handoff", "precompact_compat"];
56
56
  export type HookSemanticEvent = (typeof HOOK_SEMANTIC_EVENTS)[number];
57
57
  export declare const HOOK_MANIFEST: readonly HookHandlerSpec[];
58
58
  export interface EventGroup {
@@ -76,7 +76,6 @@ export declare function groupBindingsByEvent(harness: HookManifestHarness): Even
76
76
  /** Distinct harness-native event names covered by the manifest. */
77
77
  export declare function requiredEventsFor(harness: HookManifestHarness): string[];
78
78
  /**
79
- * Human-readable per-harness semantic coverage used by docs and by
80
- * the doctor's `harness-gaps.json` synthesis.
79
+ * Human-readable per-harness semantic coverage used by docs and doctor output.
81
80
  */
82
81
  export declare function semanticEventCoverage(harness: HookManifestHarness): Partial<Record<HookSemanticEvent, string>>;
@@ -25,7 +25,7 @@ export const HOOK_HANDLERS = [
25
25
  "prompt-guard",
26
26
  "workflow-guard",
27
27
  "context-monitor",
28
- "stop-checkpoint",
28
+ "stop-handoff",
29
29
  "pre-compact",
30
30
  "verify-current-state"
31
31
  ];
@@ -34,8 +34,8 @@ export const HOOK_SEMANTIC_EVENTS = [
34
34
  "pre_tool_prompt_guard",
35
35
  "pre_tool_workflow_guard",
36
36
  "post_tool_context_monitor",
37
- "stop_checkpoint",
38
- "precompact_digest"
37
+ "stop_handoff",
38
+ "precompact_compat"
39
39
  ];
40
40
  export const HOOK_MANIFEST = [
41
41
  {
@@ -90,9 +90,9 @@ export const HOOK_MANIFEST = [
90
90
  }
91
91
  },
92
92
  {
93
- handler: "stop-checkpoint",
94
- description: "Persist checkpoint with stage + run context on session stop.",
95
- semantic: "stop_checkpoint",
93
+ handler: "stop-handoff",
94
+ description: "Remind about clean handoff with stage + run context on session stop.",
95
+ semantic: "stop_handoff",
96
96
  bindings: {
97
97
  claude: [{ event: "Stop", timeout: 10 }],
98
98
  cursor: [{ event: "stop", timeout: 10 }],
@@ -101,12 +101,12 @@ export const HOOK_MANIFEST = [
101
101
  },
102
102
  {
103
103
  handler: "pre-compact",
104
- description: "Write pre-compact digest (Claude+Cursor have a native event; Codex has no PreCompact covered by `/cc-ops retro`).",
105
- semantic: "precompact_digest",
104
+ description: "No-op compatibility hook for harness pre-compact events; session-start rehydrates from flow-state, artifacts, and knowledge.",
105
+ semantic: "precompact_compat",
106
106
  bindings: {
107
107
  claude: [{ event: "PreCompact", matcher: "manual|auto", timeout: 10 }],
108
- // pre-compact must capture the digest BEFORE session-start
109
- // rehydrates on cursor `sessionCompact`.
108
+ // Keep this before session-start on cursor `sessionCompact` so the
109
+ // compatibility handler runs before rehydration.
110
110
  cursor: [{ event: "sessionCompact", priority: -10 }]
111
111
  }
112
112
  },
@@ -179,8 +179,7 @@ export function requiredEventsFor(harness) {
179
179
  return ordered;
180
180
  }
181
181
  /**
182
- * Human-readable per-harness semantic coverage used by docs and by
183
- * the doctor's `harness-gaps.json` synthesis.
182
+ * Human-readable per-harness semantic coverage used by docs and doctor output.
184
183
  */
185
184
  export function semanticEventCoverage(harness) {
186
185
  const out = {};
@@ -134,6 +134,7 @@ set "RUNTIME=%HOOK_DIR%run-hook.mjs"
134
134
  where node >nul 2>nul
135
135
  if %ERRORLEVEL% neq 0 (
136
136
  REM Best-effort: missing node should not block harness execution loops.
137
+ echo [cclaw] run-hook.cmd: node not found; cclaw hook skipped. Run cclaw doctor. >&2
137
138
  exit /b 0
138
139
  )
139
140
  node "%RUNTIME%" %*
@@ -145,6 +146,7 @@ if [ "$#" -lt 1 ]; then
145
146
  exit 1
146
147
  fi
147
148
  if ! command -v node >/dev/null 2>&1; then
149
+ echo "[cclaw] run-hook.cmd: node not found; cclaw hook skipped. Run cclaw doctor." >&2
148
150
  exit 0
149
151
  fi
150
152
  exec node "\${SCRIPT_DIR}/run-hook.mjs" "$@"
@@ -1,6 +1,8 @@
1
1
  import { type IdeateFrameId } from "./ideate-frames.js";
2
2
  export interface IdeateCommandOptions {
3
3
  frameIds?: readonly IdeateFrameId[];
4
+ mode?: "repo-grounded" | "elsewhere-software" | "elsewhere-non-software" | "narrow";
4
5
  }
6
+ export declare function minimumDistinctIdeateFrames(frameCount: number, mode?: IdeateCommandOptions["mode"]): number;
5
7
  export declare function ideateCommandContract(options?: IdeateCommandOptions): string;
6
8
  export declare function ideateCommandSkillMarkdown(options?: IdeateCommandOptions): string;
@@ -1,5 +1,6 @@
1
1
  import { RUNTIME_ROOT } from "../constants.js";
2
2
  import { resolveIdeateFrames } from "./ideate-frames.js";
3
+ import { ideateStructuredAskToolsWithFallback } from "./decision-protocol.js";
3
4
  const IDEATE_SKILL_FOLDER = "flow-ideate";
4
5
  const IDEATE_SKILL_NAME = "flow-ideate";
5
6
  /**
@@ -10,15 +11,13 @@ const IDEATE_SKILL_NAME = "flow-ideate";
10
11
  const IDEATE_ARTIFACT_GLOB = ".cclaw/artifacts/ideate-*.md";
11
12
  const IDEATE_ARTIFACT_PATTERN = ".cclaw/artifacts/ideate-<YYYY-MM-DD-slug>.md";
12
13
  const IDEATE_RESUME_WINDOW_DAYS = 30;
13
- /**
14
- * Structured-ask tool list reused across cclaw skills. Kept inline here (small
15
- * enough) to avoid cross-module coupling; larger stage skills cite the shared
16
- * protocol file instead.
17
- */
18
- const STRUCTURED_ASK_TOOLS = "`AskUserQuestion` on Claude, `AskQuestion` on Cursor, " +
19
- "`question` on OpenCode when `permission.question: \"allow\"` is set, " +
20
- "`request_user_input` on Codex in Plan / Collaboration mode; " +
21
- "fall back to a plain-text lettered list when the tool is hidden or errors";
14
+ const STRUCTURED_ASK_TOOLS = ideateStructuredAskToolsWithFallback();
15
+ export function minimumDistinctIdeateFrames(frameCount, mode = "repo-grounded") {
16
+ if (frameCount <= 0)
17
+ return 0;
18
+ const cap = mode === "repo-grounded" ? 4 : 2;
19
+ return Math.min(cap, frameCount);
20
+ }
22
21
  function renderFrameBullets(frameIds) {
23
22
  return resolveIdeateFrames(frameIds)
24
23
  .map((frame) => ` - ${frame.label} (\`${frame.id}\`)`)
@@ -32,7 +31,7 @@ function renderFrameNames(frameIds) {
32
31
  export function ideateCommandContract(options = {}) {
33
32
  const frames = resolveIdeateFrames(options.frameIds);
34
33
  const frameBullets = renderFrameBullets(options.frameIds);
35
- const minimumDistinctFrames = Math.min(4, frames.length);
34
+ const minimumDistinctFrames = minimumDistinctIdeateFrames(frames.length, options.mode);
36
35
  return `# /cc-ideate
37
36
 
38
37
  ## Purpose
@@ -58,8 +57,10 @@ same session, or save/discard the backlog.
58
57
  has been modified within the last ${IDEATE_RESUME_WINDOW_DAYS} days,
59
58
  offer the user: continue that backlog, start fresh, or cancel.
60
59
  2. **Mode classification.** Explicitly classify subject:
61
- \`repo-grounded\` / \`elsewhere-software\` / \`elsewhere-non-software\`.
62
- Do not assume repo-grounded by default.
60
+ \`repo-grounded\` / \`elsewhere-software\` / \`elsewhere-non-software\` / \`narrow\`.
61
+ Do not assume repo-grounded by default. Repo-grounded scans keep the
62
+ broadest frame minimum; narrow and non-repo modes use the smaller minimum
63
+ shown below.
63
64
  3. **Mode-aware grounding (parallel).**
64
65
  - Repo-grounded: repo signal scan + \`${RUNTIME_ROOT}/knowledge.jsonl\`
65
66
  repetition scan.
@@ -68,7 +69,9 @@ same session, or save/discard the backlog.
68
69
  4. **Divergent ideation frames (parallel).** Generate candidates with
69
70
  configured frames (${frames.length} total):
70
71
  ${frameBullets}
71
- Keep at least ${minimumDistinctFrames} distinct frame outputs in every run.
72
+ Keep at least ${minimumDistinctFrames} distinct frame outputs in this rendered mode.
73
+ Deterministic minimum: repo-grounded = 4, narrow/non-repo = 2, always capped
74
+ by configured frame count.
72
75
  5. **Adversarial critique pass.** For each candidate, write the strongest
73
76
  counter-argument, kill weak ideas, and keep survivors only.
74
77
  6. **Produce 5-10 survivors** with impact (High/Medium/Low),
@@ -91,7 +94,7 @@ ${frameBullets}
91
94
  For skill-to-skill invocation, emit exactly one JSON envelope:
92
95
 
93
96
  \`\`\`json
94
- {"version":"1","kind":"stage-output","stage":"brainstorm","payload":{"command":"/cc-ideate","artifact":".cclaw/artifacts/ideate-<date>-<slug>.md","recommendation":"I-1"},"emittedAt":"<ISO-8601>"}
97
+ {"version":"1","kind":"stage-output","stage":"non-flow","payload":{"command":"/cc-ideate","artifact":".cclaw/artifacts/ideate-<date>-<slug>.md","recommendation":"I-1"},"emittedAt":"<ISO-8601>"}
95
98
  \`\`\`
96
99
 
97
100
  Validate envelopes with:
@@ -105,7 +108,7 @@ Validate envelopes with:
105
108
  export function ideateCommandSkillMarkdown(options = {}) {
106
109
  const frames = resolveIdeateFrames(options.frameIds);
107
110
  const frameBullets = renderFrameBullets(options.frameIds);
108
- const minimumDistinctFrames = Math.min(4, frames.length);
111
+ const minimumDistinctFrames = minimumDistinctIdeateFrames(frames.length, options.mode);
109
112
  const frameNames = renderFrameNames(options.frameIds);
110
113
  return `---
111
114
  name: ${IDEATE_SKILL_NAME}
@@ -148,6 +151,7 @@ repository. Will persist a ranked backlog to
148
151
  - \`repo-grounded\` — explicitly tied to this repository.
149
152
  - \`elsewhere-software\` — software problem not tied to this repository.
150
153
  - \`elsewhere-non-software\` — process/business/non-software problem.
154
+ - \`narrow\` — a focused prompt where broad frame coverage would be performative.
151
155
  6. Record the chosen mode in the artifact.
152
156
 
153
157
  ### Phase 1 — Mode-aware grounding
@@ -161,8 +165,7 @@ Run grounding in parallel where available:
161
165
  - Module size outliers (\`wc -l\` or \`du\`) with weak direct test coverage.
162
166
  - Docs drift: check that \`README.md\` / \`docs/\` reference files that still
163
167
  exist and flags/APIs that still match \`src/\`.
164
- - \`${RUNTIME_ROOT}/knowledge.jsonl\` entries with \`type: "heuristic"\`
165
- or repeated \`subject:\` values.
168
+ - \`${RUNTIME_ROOT}/knowledge.jsonl\` entries with recurring \`type\` in \`rule | pattern | lesson | compound\` and repeated \`trigger/action\` pairs; prefer clusters that already show stable \`origin_run\` history.
166
169
  - For \`elsewhere-software\`:
167
170
  - Gather current framework/library docs first.
168
171
  - Add one comparison scan for established solutions.
@@ -177,8 +180,11 @@ Generate candidate ideas by frame, in parallel when possible:
177
180
 
178
181
  ${frameBullets}
179
182
 
180
- Require at least ${minimumDistinctFrames} distinct frames in every run. Avoid frame-collapse
181
- (same idea rewritten 6 times). Keep raw outputs for auditability.
183
+ Require at least ${minimumDistinctFrames} distinct frames in this rendered mode. The
184
+ runtime rule is deterministic: repo-grounded scans require 4 distinct frames;
185
+ narrow, elsewhere-software, and elsewhere-non-software runs require 2; all modes
186
+ are capped by the configured frame count. Avoid frame-collapse (same idea
187
+ rewritten many times). Keep raw outputs for auditability.
182
188
 
183
189
  ### Phase 3 — Critique all, keep survivors
184
190
 
@@ -217,7 +223,7 @@ Only survivors advance to ranking.
217
223
  # Ideation — <date>
218
224
 
219
225
  **Focus:** <user-supplied focus or "open-ended scan">
220
- **Mode:** <repo-grounded | elsewhere-software | elsewhere-non-software>
226
+ **Mode:** <repo-grounded | elsewhere-software | elsewhere-non-software | narrow>
221
227
  **Generated:** <ISO-8601 timestamp>
222
228
  **Frames used:** <comma-separated list>
223
229
  **Raw candidates:** <N>
@@ -239,15 +245,15 @@ Only survivors advance to ranking.
239
245
 
240
246
  | ID | Improvement | Impact | Effort | Confidence | Evidence |
241
247
  |---|---|---|---|---|---|
242
- | I-1 | Fix feature-worktree test timeouts | High | S | High | tests/unit/feature-system.test.ts:31 |
248
+ | I-1 | Simplify a confusing generated prompt surface | High | S | High | <path-to-generated-surface> |
243
249
  | … | … | … | … | … | … |
244
250
 
245
251
  ## Candidate detail
246
252
 
247
- ### I-1 — Fix feature-worktree test timeouts
248
- - **Evidence:** \`npm test\` hangs 40s on tests/unit/feature-system.test.ts:31.
249
- - **Counter-argument:** Fix may hide deeper orchestration race.
250
- - **Handoff:** \`/cc Fix feature-worktree test timeouts on macOS\`
253
+ ### I-1 — Simplify a confusing generated prompt surface
254
+ - **Evidence:** \`<path>\` contains repeated or stale guidance that a user would see.
255
+ - **Counter-argument:** Trimming too hard can remove useful orientation for new users.
256
+ - **Handoff:** \`/cc Simplify the confusing generated prompt surface while preserving behavior\`
251
257
 
252
258
  ### I-2 — …
253
259
  \`\`\`
@@ -79,8 +79,8 @@ export declare const IRON_LAWS: readonly [{
79
79
  readonly title: "Review layers are sequential";
80
80
  readonly rule: "Review stage must complete Layer 1 spec compliance before Layer 2 quality/security passes.";
81
81
  readonly rationale: "Stops premature quality discussion when acceptance criteria are not yet satisfied.";
82
- readonly enforcement: "advisory";
83
- readonly severity: "soft-gate";
82
+ readonly enforcement: "PreToolUse";
83
+ readonly severity: "hard-gate";
84
84
  readonly appliesTo: ["review"];
85
85
  }, {
86
86
  readonly id: "review-criticals-close-before-ship";
@@ -123,9 +123,9 @@ export declare const IRON_LAWS: readonly [{
123
123
  readonly severity: "hard-gate";
124
124
  readonly appliesTo: "all";
125
125
  }, {
126
- readonly id: "stop-clean-or-checkpointed";
127
- readonly title: "Stop only from clean checkpoint";
128
- readonly rule: "Do not end a session with dirty state unless checkpoint explicitly records unresolved work and blockers.";
126
+ readonly id: "stop-clean-or-handoff";
127
+ readonly title: "Stop only from clean handoff";
128
+ readonly rule: "Do not end a session with dirty state unless the current artifact records unresolved work and blockers.";
129
129
  readonly rationale: "Protects continuity and prevents silent half-finished sessions.";
130
130
  readonly enforcement: "Stop";
131
131
  readonly severity: "hard-gate";
@@ -49,8 +49,8 @@ export const IRON_LAWS = [
49
49
  title: "Review layers are sequential",
50
50
  rule: "Review stage must complete Layer 1 spec compliance before Layer 2 quality/security passes.",
51
51
  rationale: "Stops premature quality discussion when acceptance criteria are not yet satisfied.",
52
- enforcement: "advisory",
53
- severity: "soft-gate",
52
+ enforcement: "PreToolUse",
53
+ severity: "hard-gate",
54
54
  appliesTo: ["review"]
55
55
  },
56
56
  {
@@ -99,9 +99,9 @@ export const IRON_LAWS = [
99
99
  appliesTo: "all"
100
100
  },
101
101
  {
102
- id: "stop-clean-or-checkpointed",
103
- title: "Stop only from clean checkpoint",
104
- rule: "Do not end a session with dirty state unless checkpoint explicitly records unresolved work and blockers.",
102
+ id: "stop-clean-or-handoff",
103
+ title: "Stop only from clean handoff",
104
+ rule: "Do not end a session with dirty state unless the current artifact records unresolved work and blockers.",
105
105
  rationale: "Protects continuity and prevents silent half-finished sessions.",
106
106
  enforcement: "Stop",
107
107
  severity: "hard-gate",
@@ -1,9 +1,8 @@
1
1
  /**
2
2
  * Canonical required JSONL field order (matches strict validator keys).
3
- * Optional keys (for now: `source`, `severity`) may be appended after these
4
- * required fields.
3
+ * Optional keys (`source`, `severity`, `supersedes`, `superseded_by`) may
4
+ * be appended after these required fields.
5
5
  * Exported for tests and any programmatic writer that wants a stable base shape.
6
6
  */
7
- export declare const KNOWLEDGE_JSONL_FIELDS: readonly ["type", "trigger", "action", "confidence", "domain", "stage", "origin_stage", "origin_feature", "frequency", "universality", "maturity", "created", "first_seen_ts", "last_seen_ts", "project"];
7
+ export declare const KNOWLEDGE_JSONL_FIELDS: readonly ["type", "trigger", "action", "confidence", "domain", "stage", "origin_stage", "origin_run", "frequency", "universality", "maturity", "created", "first_seen_ts", "last_seen_ts", "project"];
8
8
  export declare function learnSkillMarkdown(): string;
9
- export declare function learnCommandContract(): string;
@@ -1,5 +1,5 @@
1
1
  // ---------------------------------------------------------------------------
2
- // Knowledge store content for /cc-learn and stage self-improvement prompts.
2
+ // Knowledge store content for the learnings skill and stage self-improvement prompts.
3
3
  //
4
4
  // The knowledge store is a single canonical JSONL file. Each line is one
5
5
  // self-contained JSON object matching the strict schema in this module.
@@ -11,8 +11,8 @@ const LEARN_SKILL_NAME = "learnings";
11
11
  const LEARN_SKILL_DESCRIPTION = "Project-scoped knowledge store: append and query rule/pattern/lesson/compound entries in the canonical JSONL file at .cclaw/knowledge.jsonl. Strict schema, append-only, machine-queryable.";
12
12
  /**
13
13
  * Canonical required JSONL field order (matches strict validator keys).
14
- * Optional keys (for now: `source`, `severity`) may be appended after these
15
- * required fields.
14
+ * Optional keys (`source`, `severity`, `supersedes`, `superseded_by`) may
15
+ * be appended after these required fields.
16
16
  * Exported for tests and any programmatic writer that wants a stable base shape.
17
17
  */
18
18
  export const KNOWLEDGE_JSONL_FIELDS = [
@@ -23,7 +23,7 @@ export const KNOWLEDGE_JSONL_FIELDS = [
23
23
  "domain",
24
24
  "stage",
25
25
  "origin_stage",
26
- "origin_feature",
26
+ "origin_run",
27
27
  "frequency",
28
28
  "universality",
29
29
  "maturity",
@@ -49,7 +49,7 @@ Use the store to keep durable knowledge that should survive sessions:
49
49
  - **rule**: hard constraint to follow every time.
50
50
  - **pattern**: repeatable way that works well in this project.
51
51
  - **lesson**: non-obvious outcome from a failure or trade-off.
52
- - **compound**: post-ship insight about how to make the *next* feature faster (process accelerator, not domain rule).
52
+ - **compound**: post-ship insight about how to make the *next* run faster (process accelerator, not domain rule).
53
53
 
54
54
  ## Continuous capture (stage closeout path)
55
55
 
@@ -63,22 +63,23 @@ Knowledge capture is now stage-native:
63
63
  2. appends deduped entries to \`${KNOWLEDGE_PATH}\`,
64
64
  3. writes a harvest marker into the artifact.
65
65
 
66
- \`/cc-learn\` remains the manual/query surface (search, backfill, curation).
66
+ Manual/query operations (search, backfill, curation) use this skill when the
67
+ user asks for knowledge work.
67
68
 
68
69
  ## HARD-GATE
69
70
 
70
- Under \`/cc-learn\`, only modify \`${KNOWLEDGE_PATH}\`, \`${KNOWLEDGE_ARCHIVE_PATH}\`,
71
+ During manual knowledge operations, only modify \`${KNOWLEDGE_PATH}\`, \`${KNOWLEDGE_ARCHIVE_PATH}\`,
71
72
  or an explicitly user-approved summary file. Do not modify application code here.
72
73
  Do not invent alternate stores (no markdown mirror, no SQLite, no per-stage files).
73
74
 
74
75
  ## Entry format — strict JSONL schema
75
76
 
76
77
  Exactly one JSON object per line. Required fields must appear in the order:
77
- \`type, trigger, action, confidence, domain, stage, origin_stage, origin_feature, frequency, universality, maturity, created, first_seen_ts, last_seen_ts, project\`.
78
+ \`type, trigger, action, confidence, domain, stage, origin_stage, origin_run, frequency, universality, maturity, created, first_seen_ts, last_seen_ts, project\`.
78
79
  Optional fields \`source\` and \`severity\` may be appended after \`project\`.
79
80
 
80
81
  \`\`\`json
81
- {"type":"pattern","trigger":"when reviewing external payloads","action":"parse through zod before touching service layer","confidence":"high","domain":"api","stage":"review","origin_stage":"review","origin_feature":"payload-hardening","frequency":1,"universality":"project","maturity":"raw","created":"2026-04-14T12:00:00Z","first_seen_ts":"2026-04-14T12:00:00Z","last_seen_ts":"2026-04-14T12:00:00Z","project":"cclaw"}
82
+ {"type":"pattern","trigger":"when reviewing external payloads","action":"parse through zod before touching service layer","confidence":"high","domain":"api","stage":"review","origin_stage":"review","origin_run":"payload-hardening","frequency":1,"universality":"project","maturity":"raw","created":"2026-04-14T12:00:00Z","first_seen_ts":"2026-04-14T12:00:00Z","last_seen_ts":"2026-04-14T12:00:00Z","project":"cclaw"}
82
83
  \`\`\`
83
84
 
84
85
  | field | type | required | notes |
@@ -90,7 +91,7 @@ Optional fields \`source\` and \`severity\` may be appended after \`project\`.
90
91
  | \`domain\` | string \\| null | yes | Free-form taxonomy (\`api\`, \`infra\`, \`ui\`, \`security\`, \`testing\`, …). Use \`null\` when cross-cutting. |
91
92
  | \`stage\` | \`FlowStage\` \\| null | yes | One of brainstorm / scope / design / spec / plan / tdd / review / ship, or \`null\` when cross-stage. |
92
93
  | \`origin_stage\` | \`FlowStage\` \\| null | yes | Stage where this learning was first observed. |
93
- | \`origin_feature\` | string \\| null | yes | Feature/worktree label where it was observed first. |
94
+ | \`origin_run\` | string \\| null | yes | Optional run, branch, or topic label where it was observed first. |
94
95
  | \`frequency\` | integer >= 1 | yes | Number of times this same trigger/action pair has been observed. |
95
96
  | \`universality\` | \`"project" \\| "personal" \\| "universal"\` | yes | Scope of applicability. |
96
97
  | \`maturity\` | \`"raw" \\| "lifted-to-rule" \\| "lifted-to-enforcement"\` | yes | Lifecycle state of the learning. |
@@ -99,7 +100,7 @@ Optional fields \`source\` and \`severity\` may be appended after \`project\`.
99
100
  | \`last_seen_ts\` | ISO 8601 UTC string | yes | Last re-confirmed timestamp. |
100
101
  | \`project\` | string \\| null | yes | Repo or scope name. Use \`null\` when the entry crosses projects. |
101
102
  | \`source\` | \`"stage" \\| "retro" \\| "compound" \\| "ideate" \\| "manual" \\| null\` | no | Origin channel for the entry when known. |
102
- | \`severity\` | \`"critical" \\| "important" \\| "suggestion"\` | no | Priority signal for compound lifts; \`critical\` enables single-hit override in \`/cc-ops compound\`. |
103
+ | \`severity\` | \`"critical" \\| "important" \\| "suggestion"\` | no | Priority signal for compound lifts; \`critical\` enables single-hit override in compound readiness analysis. |
103
104
 
104
105
  Rules:
105
106
  - No other fields beyond the table above. Extra keys are forbidden and MUST be rejected by any writer.
@@ -111,68 +112,41 @@ Rules:
111
112
  ## Curation policy (target: ≤ 50 active entries)
112
113
 
113
114
  - The file is append-only — entries are never physically deleted.
114
- - When the canonical file exceeds 50 lines, \`/cc-learn curate\` proposes
115
+ - When the canonical file exceeds 50 lines, a curation pass proposes
115
116
  soft-archiving: the approved lines are **moved** to \`${KNOWLEDGE_ARCHIVE_PATH}\`
116
117
  verbatim (same JSONL shape). The working file stays lean.
117
- - See the **knowledge-curation** utility skill for the full curation protocol.
118
+ - Use the **Curate** action below for the full read-only audit and
119
+ user-approved soft-archive plan.
118
120
 
119
- ## Subcommands
121
+ ## Manual Actions
120
122
 
121
- ### \`/cc-learn\` (default)
123
+ ### Show recent entries
122
124
  - Read \`${KNOWLEDGE_PATH}\`. Stream the last 30 lines; pretty-print each
123
125
  line's \`type\` / \`trigger\` / \`action\` for human review.
124
- - If file is missing or empty, report that clearly and suggest \`/cc-learn add\`.
126
+ - If file is missing or empty, report that clearly and suggest adding a
127
+ manual entry through this skill.
125
128
 
126
- ### \`/cc-learn search <query>\`
129
+ ### Search \`<query>\`
127
130
  - Stream \`${KNOWLEDGE_PATH}\`, JSON.parse each line, filter where any of
128
131
  \`trigger\`, \`action\`, \`domain\`, \`project\` contains \`<query>\` (case-insensitive).
129
132
  - Return the matched lines pretty-printed (do not mutate the file).
130
133
 
131
- ### \`/cc-learn add\`
134
+ ### Add
132
135
  - Ask for required user-facing fields in order: \`type\`, \`trigger\`, \`action\`, \`confidence\`, \`domain\`, \`stage\`, \`universality\`, \`project\`.
133
136
  - \`confidence\` must be one of \`high\`, \`medium\`, \`low\`. Default to \`medium\` if the user declines to set it.
134
137
  - \`domain\`, \`stage\`, and \`project\` may be explicitly \`null\`.
135
138
  - Prefer stage-native \`## Learnings\` capture for new flow work; use \`add\` mainly for backfilling historical lessons or ad-hoc entries outside a stage closeout.
136
- - \`origin_stage\` defaults to \`stage\`; \`origin_feature\` defaults to active feature (or \`null\` if unknown).
139
+ - \`origin_stage\` defaults to \`stage\`; \`origin_run\` defaults to the current run, branch, or topic label (or \`null\` if unknown).
137
140
  - \`frequency\` starts at \`1\`.
138
141
  - \`maturity\` starts at \`raw\`.
139
142
  - \`created\`, \`first_seen_ts\`, and \`last_seen_ts\` are set automatically to current UTC ISO timestamp.
140
143
  - Append exactly one JSON line to \`${KNOWLEDGE_PATH}\` with the field order from the schema table above.
141
144
  - Re-read the file tail to confirm the new line is valid JSON and parses back to the same object.
142
145
 
143
- ### \`/cc-learn curate\`
144
- - Hand off to the **knowledge-curation** skill (read-only audit + soft-archive plan).
146
+ ### Curate
147
+ - Produce a read-only audit + soft-archive plan.
145
148
  - Never deletes. Soft-archive means **moving** full JSON lines from
146
149
  \`${KNOWLEDGE_PATH}\` to \`${KNOWLEDGE_ARCHIVE_PATH}\` as part of a
147
150
  user-approved curation pass.
148
151
  `;
149
152
  }
150
- export function learnCommandContract() {
151
- return `# /cc-learn
152
-
153
- ## Purpose
154
-
155
- Manage the project knowledge store. One canonical file, strict JSONL:
156
- - \`${KNOWLEDGE_PATH}\` — append-only JSONL, one entry per line.
157
- - \`${KNOWLEDGE_ARCHIVE_PATH}\` — soft-archive target written only by curate.
158
-
159
- Stage-native pipeline:
160
- - During \`stage-complete.mjs\`, cclaw harvests \`## Learnings\` from the current
161
- stage artifact into \`${KNOWLEDGE_PATH}\` automatically.
162
- - Use \`/cc-learn\` for query, backfill, and curation workflows.
163
-
164
- ## HARD-GATE
165
-
166
- Do not edit source code from this command. Only operate on \`${KNOWLEDGE_PATH}\`,
167
- \`${KNOWLEDGE_ARCHIVE_PATH}\`, or user-approved summary output.
168
-
169
- ## Subcommands
170
-
171
- | subcommand | args | description |
172
- |---|---|---|
173
- | (default) | — | Show recent knowledge entries (tail of JSONL, pretty-printed). |
174
- | \`search\` | \`<query>\` | Stream-filter the JSONL for matching \`trigger\`, \`action\`, \`domain\`, \`project\`. |
175
- | \`add\` | — | Append one JSON line (\`rule\` / \`pattern\` / \`lesson\` / \`compound\`) with the strict JSONL schema (15 required fields + optional \`source\` / \`severity\`). |
176
- | \`curate\` | — | Hand off to the **knowledge-curation** skill: read-only audit + soft-archive plan when the file exceeds the curation threshold. |
177
- `;
178
- }
@@ -1,10 +1,9 @@
1
- import { FLOW_MAP_REL_PATH } from "./flow-map.js";
2
- import { COMPLETION_PROTOCOL_REL_PATH, DECISION_PROTOCOL_REL_PATH, ETHOS_PROTOCOL_REL_PATH } from "./protocols.js";
1
+ import { CLOSEOUT_CHAIN, closeoutChainInline, closeoutFlowMapSentence, closeoutProtocolBehaviorSentence } from "./closeout-guidance.js";
3
2
  export const META_SKILL_NAME = "using-cclaw";
4
3
  export function usingCclawSkillMarkdown() {
5
4
  return `---
6
5
  name: using-cclaw
7
- description: "Routing brain for cclaw. Decide whether to start/resume a stage, answer directly, or use utility commands like /cc-learn, /cc-ideate, /cc-view, and /cc-ops."
6
+ description: "Routing brain for cclaw. Decide whether to start/resume a stage, answer directly, or use visible commands like /cc, /cc-next, /cc-ideate, and /cc-view."
8
7
  ---
9
8
 
10
9
  # Using Cclaw
@@ -58,9 +57,10 @@ Task arrives
58
57
  ├─ New software work? -> /cc <idea>
59
58
  ├─ Repo-improvement discovery? -> /cc-ideate
60
59
  ├─ Resume existing flow? -> /cc or /cc-next
61
- ├─ Knowledge operation? -> /cc-learn
60
+ ├─ Knowledge operation? -> load the learnings skill
62
61
  ├─ Read-only workspace view? -> /cc-view [status|tree|diff]
63
- └─ Workspace operation? -> /cc-ops [feature|tdd-log|retro|compound|archive|rewind]
62
+ ├─ Normal post-ship closeout? -> /cc-next drives ${closeoutChainInline()}
63
+ └─ Explicit early archival/reset? -> cclaw archive [--name=<slug>]
64
64
  \`\`\`
65
65
 
66
66
  ## Task classification
@@ -89,30 +89,40 @@ Before stage work:
89
89
 
90
90
  ## Stage quick map
91
91
 
92
- brainstorm -> scope -> design -> spec -> plan -> tdd -> review -> ship
92
+ Use \`/cc <idea>\` for new work, \`/cc-next\` for progression and closeout, \`/cc-view\` for read-only state, and \`/cc-ideate\` for backlog discovery.
93
93
 
94
- Tracks may skip stages via \`flow-state.track\` + \`skippedStages\`.
95
- For the full surface (stages, routers, Ralph Loop, state files) load
96
- \`${FLOW_MAP_REL_PATH}\` — it is the single-page overview of cclaw.
94
+ ## Main vs Operator Surfaces
97
95
 
98
- ## Contextual skill activation
96
+ - **Main workflow:** \`/cc\`, \`/cc-next\`, \`/cc-ideate\`, \`/cc-view status\`.
97
+ - **Operator/support:** \`cclaw doctor\`, \`cclaw sync\`, \`cclaw archive\`,
98
+ \`/cc-view tree\`, and \`/cc-view diff\`.
99
+ - Use operator/support surfaces only for install/runtime diagnosis, explicit
100
+ archival, or deeper inspection. Do not make them part of the happy path.
99
101
 
100
- Load utility skills only when triggered by the current task:
102
+ ## Whole flow map
101
103
 
102
- - security, performance, debugging, docs, ci-cd
103
- - verification-before-completion before completion claims
104
- - finishing-a-development-branch during ship/finalization
105
- - document-review, receiving-code-review, and execution context skills
104
+ standard: brainstorm -> scope -> design -> spec -> plan -> tdd -> review -> ship -> ${CLOSEOUT_CHAIN}
105
+ medium: brainstorm -> spec -> plan -> tdd -> review -> ship -> ${CLOSEOUT_CHAIN}
106
+ quick: spec -> tdd -> review -> ship -> ${CLOSEOUT_CHAIN}
107
+
108
+ ${closeoutFlowMapSentence()}
109
+
110
+ Tracks may skip critical-path stages via \`flow-state.track\` + \`skippedStages\`.
111
+ Use the current stage skill plus \`.cclaw/state/flow-state.json\` for orientation.
112
+
113
+ ## Contextual Skill Activation
114
+
115
+ Use built-in judgment only when triggered by the current task:
116
+
117
+ - security, performance, debugging, docs, and CI/CD review lenses
118
+ - verification discipline before completion claims
119
+ - branch-finishing discipline during ship/finalization
106
120
  - iron-laws as policy arbitration when instructions conflict
107
121
  - language rule packs from \`.cclaw/config.yaml\` when enabled
108
122
 
109
- ## Protocol references
110
-
111
- Do not inline these protocols in stage skills; cite by path:
123
+ ## Protocol Behavior
112
124
 
113
- - Decision protocol: \`${DECISION_PROTOCOL_REL_PATH}\`
114
- - Completion/resume protocol: \`${COMPLETION_PROTOCOL_REL_PATH}\`
115
- - Engineering ethos + announce discipline: \`${ETHOS_PROTOCOL_REL_PATH}\`
125
+ ${closeoutProtocolBehaviorSentence()}
116
126
 
117
127
  ## Knowledge guidance
118
128