cclaw-cli 0.51.30 → 0.55.2

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 (142) hide show
  1. package/README.md +22 -16
  2. package/dist/artifact-linter/brainstorm.d.ts +2 -0
  3. package/dist/artifact-linter/brainstorm.js +245 -0
  4. package/dist/artifact-linter/design.d.ts +2 -0
  5. package/dist/artifact-linter/design.js +323 -0
  6. package/dist/artifact-linter/plan.d.ts +2 -0
  7. package/dist/artifact-linter/plan.js +162 -0
  8. package/dist/artifact-linter/review-army.d.ts +24 -0
  9. package/dist/artifact-linter/review-army.js +365 -0
  10. package/dist/artifact-linter/review.d.ts +2 -0
  11. package/dist/artifact-linter/review.js +65 -0
  12. package/dist/artifact-linter/scope.d.ts +2 -0
  13. package/dist/artifact-linter/scope.js +115 -0
  14. package/dist/artifact-linter/shared.d.ts +246 -0
  15. package/dist/artifact-linter/shared.js +1488 -0
  16. package/dist/artifact-linter/ship.d.ts +2 -0
  17. package/dist/artifact-linter/ship.js +46 -0
  18. package/dist/artifact-linter/spec.d.ts +2 -0
  19. package/dist/artifact-linter/spec.js +108 -0
  20. package/dist/artifact-linter/tdd.d.ts +2 -0
  21. package/dist/artifact-linter/tdd.js +124 -0
  22. package/dist/artifact-linter.d.ts +4 -76
  23. package/dist/artifact-linter.js +56 -2949
  24. package/dist/cli.d.ts +1 -6
  25. package/dist/cli.js +4 -159
  26. package/dist/codex-feature-flag.d.ts +1 -1
  27. package/dist/codex-feature-flag.js +1 -1
  28. package/dist/config.d.ts +3 -2
  29. package/dist/config.js +67 -3
  30. package/dist/constants.d.ts +1 -7
  31. package/dist/constants.js +9 -15
  32. package/dist/content/cancel-command.js +2 -2
  33. package/dist/content/closeout-guidance.js +10 -7
  34. package/dist/content/core-agents.d.ts +18 -0
  35. package/dist/content/core-agents.js +46 -2
  36. package/dist/content/decision-protocol.d.ts +1 -1
  37. package/dist/content/decision-protocol.js +1 -1
  38. package/dist/content/examples.js +6 -6
  39. package/dist/content/harness-doc.js +20 -2
  40. package/dist/content/hook-inline-snippets.d.ts +17 -4
  41. package/dist/content/hook-inline-snippets.js +218 -5
  42. package/dist/content/hook-manifest.d.ts +2 -2
  43. package/dist/content/hook-manifest.js +2 -2
  44. package/dist/content/hooks.d.ts +1 -0
  45. package/dist/content/hooks.js +32 -137
  46. package/dist/content/idea-command.d.ts +8 -0
  47. package/dist/content/{ideate-command.js → idea-command.js} +57 -50
  48. package/dist/content/idea-frames.d.ts +31 -0
  49. package/dist/content/{ideate-frames.js → idea-frames.js} +9 -9
  50. package/dist/content/idea-ranking.d.ts +25 -0
  51. package/dist/content/{ideate-ranking.js → idea-ranking.js} +5 -5
  52. package/dist/content/iron-laws.d.ts +0 -1
  53. package/dist/content/iron-laws.js +31 -16
  54. package/dist/content/learnings.js +1 -1
  55. package/dist/content/meta-skill.js +7 -7
  56. package/dist/content/node-hooks.d.ts +10 -0
  57. package/dist/content/node-hooks.js +43 -9
  58. package/dist/content/opencode-plugin.js +3 -3
  59. package/dist/content/skills.js +19 -7
  60. package/dist/content/stage-schema.js +44 -2
  61. package/dist/content/stages/_lint-metadata/index.js +26 -2
  62. package/dist/content/stages/brainstorm.js +13 -7
  63. package/dist/content/stages/design.js +16 -11
  64. package/dist/content/stages/plan.js +7 -4
  65. package/dist/content/stages/review.js +4 -4
  66. package/dist/content/stages/schema-types.d.ts +1 -1
  67. package/dist/content/stages/scope.js +15 -12
  68. package/dist/content/stages/ship.js +2 -2
  69. package/dist/content/stages/spec.js +9 -3
  70. package/dist/content/stages/tdd.js +14 -4
  71. package/dist/content/start-command.js +11 -10
  72. package/dist/content/status-command.js +3 -3
  73. package/dist/content/subagents.js +60 -6
  74. package/dist/content/templates.d.ts +1 -1
  75. package/dist/content/templates.js +102 -150
  76. package/dist/content/tree-command.js +2 -2
  77. package/dist/content/utility-skills.d.ts +2 -2
  78. package/dist/content/utility-skills.js +2 -2
  79. package/dist/content/view-command.js +4 -2
  80. package/dist/delegation.d.ts +2 -0
  81. package/dist/delegation.js +2 -1
  82. package/dist/early-loop.d.ts +66 -0
  83. package/dist/early-loop.js +275 -0
  84. package/dist/gate-evidence.d.ts +8 -0
  85. package/dist/gate-evidence.js +141 -5
  86. package/dist/harness-adapters.d.ts +2 -2
  87. package/dist/harness-adapters.js +47 -18
  88. package/dist/install.js +153 -29
  89. package/dist/internal/advance-stage/advance.d.ts +50 -0
  90. package/dist/internal/advance-stage/advance.js +480 -0
  91. package/dist/internal/advance-stage/cancel-run.d.ts +8 -0
  92. package/dist/internal/advance-stage/cancel-run.js +19 -0
  93. package/dist/internal/advance-stage/flow-state-coercion.d.ts +3 -0
  94. package/dist/internal/advance-stage/flow-state-coercion.js +81 -0
  95. package/dist/internal/advance-stage/helpers.d.ts +14 -0
  96. package/dist/internal/advance-stage/helpers.js +145 -0
  97. package/dist/internal/advance-stage/hook.d.ts +8 -0
  98. package/dist/internal/advance-stage/hook.js +40 -0
  99. package/dist/internal/advance-stage/parsers.d.ts +54 -0
  100. package/dist/internal/advance-stage/parsers.js +307 -0
  101. package/dist/internal/advance-stage/review-loop.d.ts +7 -0
  102. package/dist/internal/advance-stage/review-loop.js +170 -0
  103. package/dist/internal/advance-stage/rewind.d.ts +14 -0
  104. package/dist/internal/advance-stage/rewind.js +108 -0
  105. package/dist/internal/advance-stage/start-flow.d.ts +11 -0
  106. package/dist/internal/advance-stage/start-flow.js +136 -0
  107. package/dist/internal/advance-stage/verify.d.ts +29 -0
  108. package/dist/internal/advance-stage/verify.js +225 -0
  109. package/dist/internal/advance-stage.js +21 -1470
  110. package/dist/internal/compound-readiness.d.ts +1 -1
  111. package/dist/internal/compound-readiness.js +2 -2
  112. package/dist/internal/early-loop-status.d.ts +7 -0
  113. package/dist/internal/early-loop-status.js +90 -0
  114. package/dist/internal/runtime-integrity.d.ts +7 -0
  115. package/dist/internal/runtime-integrity.js +288 -0
  116. package/dist/internal/tdd-red-evidence.js +1 -1
  117. package/dist/knowledge-store.d.ts +3 -8
  118. package/dist/knowledge-store.js +16 -29
  119. package/dist/managed-resources.js +24 -2
  120. package/dist/policy.js +4 -6
  121. package/dist/run-archive.d.ts +1 -1
  122. package/dist/run-archive.js +12 -12
  123. package/dist/run-persistence.js +111 -11
  124. package/dist/tdd-cycle.d.ts +3 -3
  125. package/dist/tdd-cycle.js +1 -1
  126. package/dist/types.d.ts +18 -10
  127. package/package.json +1 -1
  128. package/dist/content/ideate-command.d.ts +0 -8
  129. package/dist/content/ideate-frames.d.ts +0 -31
  130. package/dist/content/ideate-ranking.d.ts +0 -25
  131. package/dist/content/next-command.d.ts +0 -20
  132. package/dist/content/next-command.js +0 -298
  133. package/dist/content/seed-shelf.d.ts +0 -36
  134. package/dist/content/seed-shelf.js +0 -301
  135. package/dist/content/stage-common-guidance.d.ts +0 -1
  136. package/dist/content/stage-common-guidance.js +0 -106
  137. package/dist/doctor-registry.d.ts +0 -10
  138. package/dist/doctor-registry.js +0 -186
  139. package/dist/doctor.d.ts +0 -17
  140. package/dist/doctor.js +0 -2201
  141. package/dist/internal/hook-manifest.d.ts +0 -16
  142. package/dist/internal/hook-manifest.js +0 -77
@@ -146,31 +146,37 @@ export function ironLawRuntimeDocument(options = {}) {
146
146
  laws
147
147
  };
148
148
  }
149
- export function ironLawsAgentsMdBlock() {
150
- const rows = IRON_LAWS.map((law) => {
151
- return `| \`${law.id}\` | ${law.rule} | ${law.enforcement} | ${law.severity} |`;
152
- }).join("\n");
153
- return `### Iron Laws
154
-
155
- These rules are always-on. Hook-enforced laws can block actions in strict mode.
156
-
157
- | ID | Rule | Enforced by | Level |
158
- |---|---|---|---|
159
- ${rows}
160
- `;
149
+ function appliesToLabel(law) {
150
+ return law.appliesTo === "all" ? "all stages" : law.appliesTo.join(", ");
151
+ }
152
+ function hardGateReference(law) {
153
+ if (law.appliesTo === "all") {
154
+ return "the active stage `HARD-GATE` block in `.cclaw/skills/<stage>/SKILL.md`";
155
+ }
156
+ return law.appliesTo
157
+ .map((stage) => `\`${RUNTIME_ROOT}/skills/${stage}/SKILL.md\` (${stage} HARD-GATE)`)
158
+ .join(", ");
161
159
  }
162
160
  export function ironLawsSkillMarkdown() {
163
- const list = IRON_LAWS.map((law, index) => {
164
- const applies = law.appliesTo === "all" ? "all stages" : law.appliesTo.join(", ");
161
+ const enforcedLawIds = new Set([
162
+ "stop-clean-or-handoff",
163
+ "review-coverage-complete-before-ship"
164
+ ]);
165
+ const enforced = IRON_LAWS.filter((law) => enforcedLawIds.has(law.id));
166
+ const advisory = IRON_LAWS.filter((law) => !enforcedLawIds.has(law.id));
167
+ const enforcedSections = enforced.map((law, index) => {
165
168
  return `### ${index + 1}. ${law.title}
166
169
 
167
170
  - **ID:** \`${law.id}\`
168
171
  - **Rule:** ${law.rule}
169
172
  - **Why:** ${law.rationale}
170
- - **Applies to:** ${applies}
173
+ - **Applies to:** ${appliesToLabel(law)}
171
174
  - **Enforced by:** ${law.enforcement} (${law.severity})
172
175
  `;
173
176
  }).join("\n");
177
+ const advisoryList = advisory
178
+ .map((law) => `- \`${law.id}\` — applies to ${appliesToLabel(law)}; see ${hardGateReference(law)}.`)
179
+ .join("\n");
174
180
  return `---
175
181
  name: iron-laws
176
182
  description: "Non-negotiable workflow constraints enforced by cclaw hooks and routing."
@@ -181,7 +187,16 @@ description: "Non-negotiable workflow constraints enforced by cclaw hooks and ro
181
187
  These are cclaw's non-negotiable constraints for harness sessions.
182
188
  Use them as the final arbitration layer when local instructions conflict.
183
189
 
184
- ${list}
190
+ ## Hook-Enforced Runtime Laws
191
+
192
+ ${enforcedSections}
193
+
194
+ ## Advisory Laws (Stage-Owned)
195
+
196
+ The following laws remain active guidance, but their canonical enforcement surface
197
+ is each stage's \`HARD-GATE\` contract:
198
+
199
+ ${advisoryList}
185
200
 
186
201
  ## Practical rule
187
202
 
@@ -101,7 +101,7 @@ Optional fields \`source\`, \`severity\`, \`supersedes\`, and \`superseded_by\`
101
101
  | \`first_seen_ts\` | ISO 8601 UTC string | yes | First observed timestamp (usually equals \`created\`). |
102
102
  | \`last_seen_ts\` | ISO 8601 UTC string | yes | Last re-confirmed timestamp. |
103
103
  | \`project\` | string \\| null | yes | Repo or scope name. Use \`null\` when the entry crosses projects. |
104
- | \`source\` | \`"stage" \\| "retro" \\| "compound" \\| "ideate" \\| "manual" \\| null\` | no | Origin channel for the entry when known. |
104
+ | \`source\` | \`"stage" \\| "retro" \\| "compound" \\| "idea" \\| "manual" \\| null\` | no | Origin channel for the entry when known. |
105
105
  | \`severity\` | \`"critical" \\| "important" \\| "suggestion"\` | no | Priority signal for compound lifts; \`critical\` enables single-hit override in compound readiness analysis. |
106
106
  | \`supersedes\` | string[] | no | Non-empty IDs/slugs of older entries this entry refreshes. Use only for clear replacements discovered during compound closeout or curation. |
107
107
  | \`superseded_by\` | string | no | Non-empty ID/slug of the newer entry that refreshes this one. Use only when marking stale guidance as replaced. |
@@ -13,7 +13,7 @@ function generatedHelperSkillList() {
13
13
  export function usingCclawSkillMarkdown() {
14
14
  return `---
15
15
  name: using-cclaw
16
- description: "Routing brain for cclaw. Decide whether to start/resume a stage, answer directly, or use visible commands like /cc, /cc-ideate, and /cc-cancel."
16
+ description: "Routing brain for cclaw. Decide whether to start/resume a stage, answer directly, or use visible commands like /cc, /cc-idea, and /cc-cancel."
17
17
  ---
18
18
 
19
19
  # Using Cclaw
@@ -64,7 +64,7 @@ Task arrives
64
64
  ├─ Running as spawned subagent? -> obey parent prompt only; do not run cclaw routing
65
65
  ├─ Pure question / non-software ask? -> answer directly (no stage)
66
66
  ├─ New software work? -> /cc <idea>
67
- ├─ Repo-improvement discovery? -> /cc-ideate
67
+ ├─ Repo-improvement discovery? -> /cc-idea
68
68
  ├─ Resume existing flow? -> /cc
69
69
  ├─ Knowledge operation? -> load the learnings skill
70
70
  ├─ Normal post-ship closeout? -> /cc drives ${closeoutChainInline()}
@@ -92,18 +92,18 @@ Before stage work:
92
92
  ## Platform reliability notes
93
93
 
94
94
  - Managed hook dispatch uses \`.cclaw/hooks/run-hook.cmd\` (cross-platform wrapper).
95
- - If hooks fail due missing runtime deps (for example \`node\` not on \`PATH\`), run \`npx cclaw-cli doctor\` before continuing.
95
+ - If hooks fail due missing runtime deps (for example \`node\` not on \`PATH\`), run \`npx cclaw-cli sync\` before continuing.
96
96
  - Prefer cross-platform commands in artifacts/examples (\`npm test\`, \`pnpm test\`, \`python -m pytest\`, etc.) over shell-specific aliases whenever possible.
97
97
 
98
98
  ## Stage quick map
99
99
 
100
- Use \`/cc <idea>\` for new work, \`/cc\` for progression and closeout, \`/cc-ideate\` for backlog discovery, and \`/cc-cancel\` for cancellation/abandonment.
100
+ Use \`/cc <idea>\` for new work, \`/cc\` for progression and closeout, \`/cc-idea\` for backlog discovery, and \`/cc-cancel\` for cancellation/abandonment.
101
101
 
102
102
  ## Main vs Operator Surfaces
103
103
 
104
- - **Main workflow:** \`/cc\`, \`/cc-ideate\`, and \`/cc-cancel\` inside the installed harness runtime.
105
- - **Installer/support surface:** \`npx cclaw-cli init\`, \`npx cclaw-cli sync\`, \`npx cclaw-cli upgrade\`, \`npx cclaw-cli doctor\`, and explicit support/archive actions. Do not ask users to install or run a \`cclaw\` binary during normal stage flow.
106
- - Use operator/support surfaces only for install/runtime diagnosis, explicit archival, or deeper inspection. Do not make them part of the happy path.
104
+ - **Main workflow:** \`/cc\`, \`/cc-idea\`, and \`/cc-cancel\` inside the installed harness runtime.
105
+ - **Installer/support surface:** \`npx cclaw-cli init\`, \`npx cclaw-cli sync\`, \`npx cclaw-cli upgrade\`, \`npx cclaw-cli sync\`, and \`npx cclaw-cli uninstall\`.
106
+ - Use operator/support surfaces only for install/runtime diagnosis or lifecycle maintenance. Do not make them part of the happy path.
107
107
 
108
108
  ## Whole flow map
109
109
 
@@ -15,6 +15,16 @@ export interface NodeHookRuntimeOptions {
15
15
  * `cclaw sync` after changing the config value so hook and CLI agree.
16
16
  */
17
17
  compoundRecurrenceThreshold?: number;
18
+ /**
19
+ * Enables early-stage producer/critic loop diagnostics in session-start.
20
+ * Defaults to true.
21
+ */
22
+ earlyLoopEnabled?: boolean;
23
+ /**
24
+ * Baked-in max iterations for brainstorm/scope/design early-loop status.
25
+ * Derived from `config.earlyLoop.maxIterations`.
26
+ */
27
+ earlyLoopMaxIterations?: number;
18
28
  }
19
29
  /**
20
30
  * Node-only hook runtime (single entrypoint).
@@ -1,10 +1,10 @@
1
1
  import { existsSync } from "node:fs";
2
2
  import path from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
- import { DEFAULT_COMPOUND_RECURRENCE_THRESHOLD } from "../config.js";
4
+ import { DEFAULT_COMPOUND_RECURRENCE_THRESHOLD, DEFAULT_EARLY_LOOP_MAX_ITERATIONS } from "../config.js";
5
5
  import { RUNTIME_ROOT } from "../constants.js";
6
6
  import { SMALL_PROJECT_ARCHIVE_RUNS_THRESHOLD, SMALL_PROJECT_RECURRENCE_THRESHOLD } from "../knowledge-store.js";
7
- import { HOOK_INLINE_SHARED_HELPERS, COMPOUND_READINESS_INLINE_SOURCE, RALPH_LOOP_INLINE_SOURCE } from "./hook-inline-snippets.js";
7
+ import { HOOK_INLINE_SHARED_HELPERS, COMPOUND_READINESS_INLINE_SOURCE, RALPH_LOOP_INLINE_SOURCE, EARLY_LOOP_INLINE_SOURCE } from "./hook-inline-snippets.js";
8
8
  function normalizePatterns(patterns, fallback) {
9
9
  if (!patterns || patterns.length === 0)
10
10
  return [...fallback];
@@ -51,6 +51,12 @@ export function nodeHookRuntimeScript(options = {}) {
51
51
  options.compoundRecurrenceThreshold >= 1
52
52
  ? options.compoundRecurrenceThreshold
53
53
  : DEFAULT_COMPOUND_RECURRENCE_THRESHOLD;
54
+ const earlyLoopEnabled = options.earlyLoopEnabled !== false;
55
+ const earlyLoopMaxIterations = typeof options.earlyLoopMaxIterations === "number" &&
56
+ Number.isInteger(options.earlyLoopMaxIterations) &&
57
+ options.earlyLoopMaxIterations >= 1
58
+ ? options.earlyLoopMaxIterations
59
+ : DEFAULT_EARLY_LOOP_MAX_ITERATIONS;
54
60
  const cliRuntime = resolveCliRuntimeForGeneratedHook();
55
61
  return `#!/usr/bin/env node
56
62
  import fs from "node:fs/promises";
@@ -73,6 +79,8 @@ const DEFAULT_TDD_PRODUCTION_PATH_PATTERNS = ${JSON.stringify(tddProductionPathP
73
79
  const COMPOUND_RECURRENCE_THRESHOLD = ${JSON.stringify(compoundRecurrenceThreshold)};
74
80
  const SMALL_PROJECT_ARCHIVE_RUNS_THRESHOLD = ${JSON.stringify(SMALL_PROJECT_ARCHIVE_RUNS_THRESHOLD)};
75
81
  const SMALL_PROJECT_RECURRENCE_THRESHOLD = ${JSON.stringify(SMALL_PROJECT_RECURRENCE_THRESHOLD)};
82
+ const EARLY_LOOP_ENABLED = ${JSON.stringify(earlyLoopEnabled)};
83
+ const EARLY_LOOP_MAX_ITERATIONS = ${JSON.stringify(earlyLoopMaxIterations)};
76
84
  const CCLAW_CLI_ENTRYPOINT = ${JSON.stringify(cliRuntime.entrypoint)};
77
85
  const CCLAW_CLI_ARGS_PREFIX = ${JSON.stringify(cliRuntime.argsPrefix)};
78
86
 
@@ -253,7 +261,7 @@ async function readJsonFile(filePath, fallback = {}, options = {}) {
253
261
  } catch (parseErr) {
254
262
  // Emit a diagnostic breadcrumb instead of silently returning fallback.
255
263
  // The hook must still continue (soft-fail), but the corruption is
256
- // now visible in \`state/hook-errors.jsonl\` and to \`cclaw doctor\`.
264
+ // now visible in \`state/hook-errors.jsonl\` and to \`npx cclaw-cli sync\`.
257
265
  if (options.root) {
258
266
  await recordHookError(
259
267
  options.root,
@@ -684,7 +692,6 @@ function detectTargetStage(payloadLower) {
684
692
  }
685
693
 
686
694
  function isFlowProgressionCommand(payloadLower) {
687
- if (/(\\/cc-next|cc-next)([^a-z0-9_-]|$)/u.test(payloadLower)) return true;
688
695
  return /\\/cc([^a-z0-9_-]|$)/u.test(payloadLower);
689
696
  }
690
697
 
@@ -942,6 +949,7 @@ async function handleSessionStart(runtime) {
942
949
  // both read a consistent "iter=N, acClosed=[...]" snapshot. Runs only when
943
950
  // we are in tdd — other stages skip the write to keep the file stable.
944
951
  let ralphLoopLine = "";
952
+ let earlyLoopLine = "";
945
953
  if (state.currentStage === "tdd") {
946
954
  try {
947
955
  const ralphStatus = await computeRalphLoopStatusInline(stateDir, state.activeRunId);
@@ -956,7 +964,7 @@ async function handleSessionStart(runtime) {
956
964
  } catch (err) {
957
965
  // Best-effort — a malformed cycle log should never break
958
966
  // session-start. But we DO leave a breadcrumb in
959
- // hook-errors.jsonl so \`cclaw doctor\` can surface chronic
967
+ // hook-errors.jsonl so \`npx cclaw-cli sync\` can surface chronic
960
968
  // failures (previously this was a silent swallow).
961
969
  await recordHookError(
962
970
  runtime.root,
@@ -965,6 +973,27 @@ async function handleSessionStart(runtime) {
965
973
  );
966
974
  }
967
975
  }
976
+ if (
977
+ EARLY_LOOP_ENABLED &&
978
+ (state.currentStage === "brainstorm" || state.currentStage === "scope" || state.currentStage === "design")
979
+ ) {
980
+ try {
981
+ const earlyLoopStatus = await computeEarlyLoopStatusInline(
982
+ stateDir,
983
+ state.currentStage,
984
+ state.activeRunId,
985
+ EARLY_LOOP_MAX_ITERATIONS
986
+ );
987
+ await writeJsonFile(path.join(stateDir, "early-loop.json"), earlyLoopStatus);
988
+ earlyLoopLine = formatEarlyLoopStatusLineInline(earlyLoopStatus);
989
+ } catch (err) {
990
+ await recordHookError(
991
+ runtime.root,
992
+ "session-start:early-loop",
993
+ err instanceof Error ? err.message : String(err)
994
+ );
995
+ }
996
+ }
968
997
 
969
998
  // Keep compound-readiness.json fresh on every session-start (cheap derived
970
999
  // summary). Surface a one-line nudge only from review and ship stages
@@ -1002,7 +1031,7 @@ async function handleSessionStart(runtime) {
1002
1031
  // Best-effort — a malformed knowledge.jsonl must never break
1003
1032
  // session-start. But we DO leave a breadcrumb in
1004
1033
  // hook-errors.jsonl so config/IO problems become visible in
1005
- // \`cclaw doctor\` instead of silently degrading readiness output.
1034
+ // \`npx cclaw-cli sync\` instead of silently degrading readiness output.
1006
1035
  await recordHookError(
1007
1036
  runtime.root,
1008
1037
  "session-start:compound-readiness",
@@ -1042,6 +1071,9 @@ async function handleSessionStart(runtime) {
1042
1071
  if (ralphLoopLine.length > 0) {
1043
1072
  parts.push(ralphLoopLine);
1044
1073
  }
1074
+ if (earlyLoopLine.length > 0) {
1075
+ parts.push(earlyLoopLine);
1076
+ }
1045
1077
  if (compoundReadinessLine.length > 0) {
1046
1078
  parts.push(compoundReadinessLine);
1047
1079
  }
@@ -1049,7 +1081,7 @@ async function handleSessionStart(runtime) {
1049
1081
  parts.push(
1050
1082
  "Stale stages pending acknowledgement: " +
1051
1083
  staleStageNames.join(", ") +
1052
- " (use cclaw internal rewind --ack <stage> after redo)."
1084
+ " (use npx cclaw-cli internal rewind --ack <stage> after redo)."
1053
1085
  );
1054
1086
  }
1055
1087
  if (knowledge.digestLines.length > 0) {
@@ -1215,13 +1247,15 @@ async function handlePromptGuard(runtime) {
1215
1247
  }
1216
1248
 
1217
1249
  // Inline mirrors of canonical CLI computations (compound-readiness,
1218
- // ralph-loop) are factored into src/content/hook-inline-snippets.ts so
1250
+ // ralph-loop, early-loop) are factored into
1251
+ // src/content/hook-inline-snippets.ts so
1219
1252
  // this 2000+-line file no longer owns their bodies. Each snippet carries
1220
1253
  // an explicit "mirrors X, parity enforced by Y" comment in the snippets
1221
1254
  // module. Parity is enforced by tests/unit/ralph-loop-parity.test.ts.
1222
1255
  ${HOOK_INLINE_SHARED_HELPERS}
1223
1256
  ${COMPOUND_READINESS_INLINE_SOURCE}
1224
1257
  ${RALPH_LOOP_INLINE_SOURCE}
1258
+ ${EARLY_LOOP_INLINE_SOURCE}
1225
1259
 
1226
1260
  async function hasFailingRedEvidenceForPath(stateDir, runId, rawPath) {
1227
1261
  const cycleRaw = await readTextFile(path.join(stateDir, "tdd-cycle-log.jsonl"), "");
@@ -1401,7 +1435,7 @@ async function handleWorkflowGuard(runtime) {
1401
1435
  /^(read|readfile|open|view|cat|shell|runcommand|run_command|execcommand|exec_command|terminal)$/u.test(
1402
1436
  toolLower
1403
1437
  ) &&
1404
- /(\\.cclaw\\/state\\/flow-state\\.json|cclaw doctor|cclaw sync)/u.test(payloadLower);
1438
+ /(\\.cclaw\\/state\\/flow-state\\.json|npx cclaw-cli sync|npx cclaw-cli sync|npx cclaw-cli sync|cclaw sync)/u.test(payloadLower);
1405
1439
  if (shouldRecordFlowRead) {
1406
1440
  await writeJsonFile(guardStateFile, {
1407
1441
  ...guardState,
@@ -131,7 +131,7 @@ export default function cclawPlugin(ctx) {
131
131
  if (stageSupport.length > 0) parts.push(...stageSupport);
132
132
 
133
133
  parts.push(
134
- "If you discover a non-obvious rule or pattern during stage work, add it to the current artifact ## Learnings section; stage-complete harvests it into .cclaw/knowledge.jsonl. If this plugin does not load, run \`cclaw sync\`, verify opencode.json(.c) includes the cclaw plugin registration, then run \`cclaw doctor --explain\`. Direct JSONL append is only for explicit manual learnings operations."
134
+ "If you discover a non-obvious rule or pattern during stage work, add it to the current artifact ## Learnings section; stage-complete harvests it into .cclaw/knowledge.jsonl. If this plugin does not load, run \`npx cclaw-cli sync\`, verify opencode.json(.c) includes the cclaw plugin registration, then run \`npx cclaw-cli sync\`. Direct JSONL append is only for explicit manual learnings operations."
135
135
  );
136
136
 
137
137
  const meta = (await readFileText(metaSkillPath)).trim();
@@ -510,7 +510,7 @@ export default function cclawPlugin(ctx) {
510
510
  notInitializedAdvised = true;
511
511
  logToFile(
512
512
  "guards skipped: cclaw is not initialized in this project. " +
513
- "Run \`cclaw init\` in " + root + " to activate flow enforcement."
513
+ "Run \`npx cclaw-cli init\` in " + root + " to activate flow enforcement."
514
514
  );
515
515
  }
516
516
 
@@ -697,7 +697,7 @@ export default function cclawPlugin(ctx) {
697
697
  throw new Error(
698
698
  "cclaw " + failed + " blocked tool.execute.before.\\n" +
699
699
  "Reason: " + detail + "\\n" +
700
- "Diagnose: run \`npx cclaw-cli doctor\` in project root.\\n" +
700
+ "Diagnose: run \`npx cclaw-cli sync\` in project root.\\n" +
701
701
  "Bypass (temporary): export CCLAW_DISABLE=1 before starting OpenCode,\\n" +
702
702
  "or set \`strictness: advisory\` in .cclaw/config.yaml."
703
703
  );
@@ -3,10 +3,10 @@ import { nextStage as nextStageForTrack } from "../flow-state.js";
3
3
  import { FLOW_STAGES } from "../types.js";
4
4
  import { stageExamples } from "./examples.js";
5
5
  import { reviewStackAwareRoutes, reviewStackAwareRoutingSummary, stageAutoSubagentDispatch, stageSchema, stageTrackRenderContext } from "./stage-schema.js";
6
- import { conversationLanguagePolicyMarkdown } from "./language-policy.js";
7
6
  import { referencePatternsForStage } from "./reference-patterns.js";
8
7
  import { harnessDelegationRecipes } from "../harness-adapters.js";
9
8
  const VERIFICATION_STAGES = ["tdd", "review", "ship"];
9
+ const STAGE_LANGUAGE_POLICY_POINTER = "> Language policy: see `using-cclaw` section `Conversation Language Policy`.";
10
10
  // ---------- Cross-cutting universal mechanics (Layer 2 building blocks) ----------
11
11
  //
12
12
  // These are shared, structural blocks that get injected into every stage skill.
@@ -363,7 +363,7 @@ function completionParametersBlock(schema, track) {
363
363
  const nextDescription = nextStage === "done"
364
364
  ? "flow complete"
365
365
  : stageSchema(nextStage, track).skillDescription;
366
- return `## Completion Parameters
366
+ return `### Completion Parameters
367
367
 
368
368
  - \`stage\`: \`${schema.stage}\`
369
369
  - \`next\`: \`${nextStage}\` (${nextDescription})
@@ -373,13 +373,26 @@ function completionParametersBlock(schema, track) {
373
373
  - \`completion helper\`: \`node .cclaw/hooks/stage-complete.mjs ${schema.stage}\`
374
374
  - \`completion helper with evidence\`: \`node .cclaw/hooks/stage-complete.mjs ${schema.stage} --evidence-json '{"<gate_id>":"<evidence note>"}' --passed=<gate_id>[,<gate_id>]\`
375
375
  - \`completion helper JSON diagnostics\`: append \`--json\` to receive a machine-readable validation failure summary.
376
- - \`delegation record helper\`: \`node .cclaw/hooks/delegation-record.mjs --stage=${schema.stage} --agent=<agent> --mode=<mandatory|proactive> --status=<scheduled|launched|acknowledged|completed|failed|waived|stale> --span-id=<spanId> --dispatch-id=<dispatchId> --dispatch-surface=<surface> --agent-definition-path=<path> --json\`. \`delegation helper recipe\`: call \`--status=scheduled\`, then \`--status=launched\`, then \`--status=acknowledged\`, then \`--status=completed\` with the same \`--span-id\`, \`--dispatch-id\`, \`--dispatch-surface\`, and \`--agent-definition-path\`; completed isolated/generic rows fail unless that same span already has an acknowledged event or the completed call includes \`--ack-ts=<iso>\`. For role-switch fallback, use \`--dispatch-surface=role-switch --evidence-ref=<artifact#anchor>\` instead of pretending isolated completion.
376
+ - \`delegation lifecycle proof\`: use the delegation helper recipe in this section with explicit lifecycle rows: \`--status=scheduled\` -> \`--status=launched\` -> \`--status=acknowledged\` -> \`--status=completed\` (completed isolated/generic requires prior ACK for the same span or \`--ack-ts=<iso>\`).
377
377
  - Fill \`## Learnings\` before closeout: either \`- None this stage.\` or JSON bullets with required keys \`type\`, \`trigger\`, \`action\`, \`confidence\` (knowledge-schema compatible).
378
- - Record mandatory delegation lifecycle in \`${RUNTIME_ROOT}/state/delegation-log.json\` and append proof events to \`${RUNTIME_ROOT}/state/delegation-events.jsonl\`; the ledger is current state, the event log is audit proof.${mandatoryAgents.length > 0 ? ` If a mandatory delegation cannot run in this harness, use \`--waive-delegation=${mandatoryAgents.join(",")} --waiver-reason="<why safe>"\` on the completion helper.` : ""}
378
+ - Record mandatory delegation lifecycle in \`${RUNTIME_ROOT}/state/delegation-log.json\` and append proof events to \`${RUNTIME_ROOT}/state/delegation-events.jsonl\`; the ledger is current state, the event log is audit proof.${mandatoryAgents.length > 0 ? ` If a mandatory delegation cannot run in this harness, use \`--waive-delegation=${mandatoryAgents.join(",")} --waiver-reason="<why safe>"\` on the completion helper.` : ""} If proactive delegations were intentionally skipped, rerun only with \`--accept-proactive-waiver\` (optionally \`--accept-proactive-waiver-reason="<why safe>"\`) after explicit user approval.
379
379
  - Never edit raw \`flow-state.json\` to complete a stage, even in advisory mode; that bypasses validation, gate evidence, and Learnings harvest. If the helper fails, stop and report the exact command/output instead of applying a manual state workaround.
380
380
  - Completion protocol: verify required gates, update the artifact, then use the completion helper with \`--evidence-json\` and \`--passed\` for every satisfied gate.
381
381
  `;
382
382
  }
383
+ function delegationAndCompletionBlock(schema, track) {
384
+ const dispatchBlock = autoSubagentDispatchBlock(schema.stage, track).trim();
385
+ const completionBlock = completionParametersBlock(schema, track).trim();
386
+ const normalizedDispatch = dispatchBlock.length > 0
387
+ ? dispatchBlock.replace(/^## Automatic Subagent Dispatch/mu, "### Automatic Subagent Dispatch")
388
+ : "### Automatic Subagent Dispatch\nNo automatic subagent dispatch rules for this stage.";
389
+ return `## Delegation & Completion
390
+
391
+ ${normalizedDispatch}
392
+
393
+ ${completionBlock}
394
+ `;
395
+ }
383
396
  function quickStartBlock(stage, track) {
384
397
  const schema = stageSchema(stage, track);
385
398
  const gatePreview = schema.executionModel.requiredGates.slice(0, 3).map((g) => `\`${g.id}\``).join(", ");
@@ -516,7 +529,7 @@ If you are about to violate the Iron Law, STOP. No amount of urgency, partial pr
516
529
 
517
530
  ${quickStartBlock(stage, track)}
518
531
 
519
- ${conversationLanguagePolicyMarkdown()}
532
+ ${STAGE_LANGUAGE_POLICY_POINTER}
520
533
  ## Philosophy
521
534
  ${philosophy.purpose}
522
535
 
@@ -541,7 +554,7 @@ Stage state machine (map only; Checklist is authoritative):
541
554
  ${processFlowMermaid.length > 0 ? processFlowMermaid : "```mermaid\nflowchart TD\n S1[\"Execute Checklist\"] --> S2[\"Satisfy required gates\"] --> S3[\"Verify before closeout\"]\n```"}
542
555
 
543
556
  ${platformNotesBlock}${contextLoadingBlock(stage, artifactRules.crossStageTrace, executionModel)}
544
- ${autoSubagentDispatchBlock(stage, track)}
557
+ ${delegationAndCompletionBlock(schema, track)}
545
558
  ${stackAwareReviewRoutingBlock(stage)}
546
559
  ${researchPlaybooksBlock(executionModel.researchPlaybooks ?? [])}
547
560
  ${referencePatternsBlock(stage)}
@@ -575,7 +588,6 @@ ${verificationBlock(stage)}
575
588
  ## Exit Criteria
576
589
  ${executionModel.exitCriteria.map((item) => `- [ ] ${item}`).join("\n")}
577
590
 
578
- ${completionParametersBlock(schema, track)}
579
591
  ## Artifact Rules
580
592
  - Artifact target: \`${RUNTIME_ROOT}/artifacts/${artifactRules.artifactFile}\`
581
593
 
@@ -89,6 +89,8 @@ function defaultReturnSchemaForAgent(agent) {
89
89
  return "architecture-return";
90
90
  case "spec-validator":
91
91
  return "spec-validation-return";
92
+ case "spec-document-reviewer":
93
+ return "review-return";
92
94
  case "slice-implementer":
93
95
  return "worker-return";
94
96
  case "performance-reviewer":
@@ -102,6 +104,7 @@ function defaultReturnSchemaForAgent(agent) {
102
104
  case "planner":
103
105
  return "planning-return";
104
106
  case "product-manager":
107
+ case "product-strategist":
105
108
  return "product-return";
106
109
  case "critic":
107
110
  return "critic-return";
@@ -258,6 +261,7 @@ const REQUIRED_GATE_IDS = {
258
261
  design: [
259
262
  "design_research_complete",
260
263
  "design_architecture_locked",
264
+ "design_diagram_freshness",
261
265
  "design_data_flow_mapped",
262
266
  "design_failure_modes_mapped",
263
267
  "design_test_and_perf_defined"
@@ -266,6 +270,7 @@ const REQUIRED_GATE_IDS = {
266
270
  "spec_acceptance_measurable",
267
271
  "spec_testability_confirmed",
268
272
  "spec_assumptions_surfaced",
273
+ "spec_self_review_complete",
269
274
  "spec_user_approved"
270
275
  ],
271
276
  plan: [
@@ -282,6 +287,9 @@ const REQUIRED_GATE_IDS = {
282
287
  "tdd_green_full_suite",
283
288
  "tdd_refactor_completed",
284
289
  "tdd_verified_before_complete",
290
+ "tdd_iron_law_acknowledged",
291
+ "tdd_watched_red_observed",
292
+ "tdd_slice_cycle_complete",
285
293
  "tdd_docs_drift_check",
286
294
  ...(track === "quick" ? [] : ["tdd_traceable_to_plan"])
287
295
  ],
@@ -322,9 +330,27 @@ const REQUIRED_ARTIFACT_SECTIONS = {
322
330
  "Spec Handoff",
323
331
  "Completion Dashboard"
324
332
  ],
325
- spec: ["Acceptance Criteria", "Edge Cases", "Assumptions Before Finalization", "Acceptance Mapping", "Approval"],
333
+ spec: [
334
+ "Acceptance Criteria",
335
+ "Edge Cases",
336
+ "Assumptions Before Finalization",
337
+ "Acceptance Mapping",
338
+ "Spec Self-Review",
339
+ "Approval"
340
+ ],
326
341
  plan: ["Task List", "Dependency Batches", "Acceptance Mapping", "Execution Posture", "WAIT_FOR_CONFIRM"],
327
- tdd: ["Test Discovery", "System-Wide Impact Check", "RED Evidence", "GREEN Evidence", "REFACTOR Notes", "Traceability", "Verification Ladder"],
342
+ tdd: [
343
+ "Test Discovery",
344
+ "System-Wide Impact Check",
345
+ "RED Evidence",
346
+ "GREEN Evidence",
347
+ "REFACTOR Notes",
348
+ "Traceability",
349
+ "Iron Law Acknowledgement",
350
+ "Watched-RED Proof",
351
+ "Vertical Slice Cycle",
352
+ "Verification Ladder"
353
+ ],
328
354
  review: ["Review Evidence Scope", "Changed-File Coverage", "Layer 1 Verdict", "Review Findings Contract", "Severity Summary", "Final Verdict"],
329
355
  ship: ["Preflight Results", "Release Notes", "Rollback Plan", "Finalization"]
330
356
  };
@@ -474,6 +500,14 @@ const STAGE_AUTO_SUBAGENT_DISPATCH = {
474
500
  when: "When scope choices change user value, success metrics, or product positioning.",
475
501
  purpose: "Keep accepted/deferred reference ideas tied to user value and measurable success.",
476
502
  requiresUserGate: false
503
+ },
504
+ {
505
+ agent: "product-strategist",
506
+ mode: "proactive",
507
+ requiredAtTier: "standard",
508
+ when: "When scope mode resolves to SCOPE EXPANSION or SELECTIVE EXPANSION.",
509
+ purpose: "Drive 10x vision and concrete expansion proposals before locking the scope contract.",
510
+ requiresUserGate: false
477
511
  }
478
512
  ],
479
513
  design: [
@@ -546,6 +580,14 @@ const STAGE_AUTO_SUBAGENT_DISPATCH = {
546
580
  when: "When acceptance criteria need testability review or RED expressibility is uncertain.",
547
581
  purpose: "Confirm likely test levels, commands/manual evidence, and assertion surfaces are concrete.",
548
582
  requiresUserGate: false
583
+ },
584
+ {
585
+ agent: "spec-document-reviewer",
586
+ mode: "proactive",
587
+ requiredAtTier: "standard",
588
+ when: "When Spec Self-Review reports gaps (Status: Issues Found) or subsystem boundaries drift beyond one coherent plan slice.",
589
+ purpose: "Run a final document-level quality pass for completeness, consistency, clarity, and scope fit before handoff to plan.",
590
+ requiresUserGate: false
549
591
  }
550
592
  ],
551
593
  plan: [
@@ -6,6 +6,9 @@ const STAGE_POLICY_NEEDLES = {
6
6
  "Explore project context",
7
7
  "One question at a time",
8
8
  "2-3 architecturally distinct approaches",
9
+ "Embedded Grill",
10
+ "Victory Detector",
11
+ "Critic Pass",
9
12
  "State what is being approved",
10
13
  "Self-review before handoff",
11
14
  "Do NOT implement, scaffold, or modify behavior"
@@ -17,7 +20,9 @@ const STAGE_POLICY_NEEDLES = {
17
20
  "Discretion Areas",
18
21
  "NOT in scope",
19
22
  "Premise Challenge",
20
- "Locked Decisions"
23
+ "Locked Decisions",
24
+ "Victory Detector",
25
+ "Critic Pass"
21
26
  ],
22
27
  design: [
23
28
  "Parallel Research Fleet",
@@ -25,9 +30,21 @@ const STAGE_POLICY_NEEDLES = {
25
30
  "Data Flow",
26
31
  "Failure Modes and Mitigation",
27
32
  "Performance Budget",
33
+ "Long-Term Trajectory",
34
+ "Victory Detector",
35
+ "Critic Pass",
28
36
  "One issue at a time"
29
37
  ],
30
- spec: ["Acceptance Criteria", "Constraints", "Assumptions Before Finalization", "Testability", "approved spec", "Edge Cases"],
38
+ spec: [
39
+ "Acceptance Criteria",
40
+ "Constraints",
41
+ "Assumptions Before Finalization",
42
+ "Testability",
43
+ "Spec Self-Review",
44
+ "single subsystem",
45
+ "approved spec",
46
+ "Edge Cases"
47
+ ],
31
48
  plan: [
32
49
  "WAIT_FOR_CONFIRM",
33
50
  "Task Graph",
@@ -35,6 +52,8 @@ const STAGE_POLICY_NEEDLES = {
35
52
  "Acceptance Mapping",
36
53
  "verification steps",
37
54
  "Execution Posture",
55
+ "Calibrated Findings",
56
+ "Regression Iron Rule",
38
57
  "Locked Decision Coverage"
39
58
  ],
40
59
  tdd: [
@@ -42,8 +61,13 @@ const STAGE_POLICY_NEEDLES = {
42
61
  "GREEN",
43
62
  "REFACTOR",
44
63
  "failing test",
64
+ "Iron Law Acknowledgement",
65
+ "Watched-RED Proof",
66
+ "Vertical Slice Cycle",
45
67
  "Test Discovery",
46
68
  "System-Wide Impact Check",
69
+ "TDD Blocker Taxonomy",
70
+ "Per-Slice Review",
47
71
  "full test suite",
48
72
  "acceptance criteria",
49
73
  "traceable to plan slice"
@@ -5,8 +5,8 @@ export const BRAINSTORM = {
5
5
  schemaShape: "v2",
6
6
  stage: "brainstorm",
7
7
  complexityTier: "standard",
8
- skillFolder: "brainstorming",
9
- skillName: "brainstorming",
8
+ skillFolder: "brainstorm",
9
+ skillName: "brainstorm",
10
10
  skillDescription: "Problem-discovery stage. Build a concise Problem Decision Record, choose lite/standard/deep depth, compare distinct directions, and hand approved decisions to scope.",
11
11
  philosophy: {
12
12
  hardGate: "Do NOT invoke implementation skills, write code, scaffold projects, or mutate product behavior until a concrete direction is approved by the user.",
@@ -43,15 +43,17 @@ export const BRAINSTORM = {
43
43
  "**Reframe with How Might We** — write a single `How Might We …?` line that names the user/operator, the desired outcome, and the constraint. This is the altitude check before approaches.",
44
44
  "**Run Clarity Gate** — record ambiguity score (0.00-1.00), decision boundaries, reaffirmed non-goals, and residual-risk handoff before locking recommendations. If ambiguity remains high (>0.40), ask one decision-changing question before recommending.",
45
45
  "**Sharpening question discipline** — ask one decision-changing question at a time. Do not default to 3-5 batched questions; record only questions that changed the direction or a critical stop decision.",
46
- "**Use compact discovery for simple apps** — for concrete low-risk asks (todo app, landing page, local widget), do one context pass, compare one baseline and one challenger, then ask for one explicit approval; do not drag the user through a full workshop.",
46
+ "**Use compact discovery for low-risk asks** — for concrete bounded requests, do one context pass, compare one baseline and one challenger, then ask for one explicit approval; do not drag the user through a full workshop.",
47
47
  "**Early-exit concrete asks** — for unambiguous implementation-only requests, write a compact Problem Decision Record plus short-circuit handoff (context, approved intent, constraints, assumptions, next-stage risks) and ask for one explicit approval.",
48
48
  "**Ask only decision-changing questions** — one at a time; if answers would not change approach and are non-critical preference/default assumptions, state the assumption and continue; STOP on scope, architecture, security, data loss, public API, migration, auth/pricing, or user approval uncertainty.",
49
49
  "**Compare 2-3 distinct approaches with stable Role/Upside columns** — Role values are `baseline` | `challenger` | `wild-card`; Upside is `low` | `modest` | `high` | `higher`; include real trade-offs, reuse notes, and reference-pattern source/disposition when a known pattern influenced the option; include exactly one challenger with explicit `high` or `higher` upside.",
50
50
  "**Collect reaction before recommending** — ask which option feels closest and what concern remains, then recommend based on that reaction.",
51
51
  "**Write the `Not Doing` list** — name 3-5 things this brainstorm explicitly is not committing to (vs. deferred). This protects scope from silent enlargement and the next stage from rework.",
52
+ "**Run early Ralph loop discipline** — after each producer iteration, append a `Critic Pass` JSONL row to `.cclaw/state/early-loop-log.jsonl`, refresh `.cclaw/state/early-loop.json`, and iterate until open concerns clear or convergence guard escalates.",
53
+ "**Embedded Grill (post-pick)** — after `Selected Direction` is named, run 3-5 sharp checks on hidden constraints, reversibility/rollback, scope boundaries, existing-pattern conformance, and domain-language fit; record each question with recommended answer and disposition (accept/refine/reject).",
52
54
  "**Self-review before user approval** — re-read the artifact and patch contradictions, weak trade-offs, placeholders, ambiguity, and weak handoff language. Record the result in `Self-Review Notes` using the calibrated review format: `- Status: Approved` (or `Issues Found`), `- Patches applied:` with inline note or sub-bullets, `- Remaining concerns:` with inline note or sub-bullets. Use `Patches applied: None` and `Remaining concerns: None` when there is nothing to record.",
53
55
  "**Request explicit approval** — state exactly what direction is being approved; do not advance without approval and artifact review.",
54
- "**Handoff** — only after approval, hand scope: upstream decisions used, explicit drift, confidence level, unresolved questions, next-stage risk hints, and non-goals."
56
+ "**Handoff packet** — only after approval, produce a scope handoff packet with selected direction, why rejected options were rejected, explicit non-goals, unresolved questions, risk hints, and explicit drift from the initial ask so scope starts from locked upstream decisions instead of rediscovering intent."
55
57
  ],
56
58
  interactionProtocol: [
57
59
  "Start from observed project context; if the idea is vague, first narrow the project type with **one** structured question, then keep going.",
@@ -59,7 +61,7 @@ export const BRAINSTORM = {
59
61
  "Lead with the premise check (right problem / direct path / what if nothing) and the `How Might We` reframing before approaches; both go in the artifact, not just the chat.",
60
62
  "Ask at most one question per turn, only when decision-changing; if using a structured question tool, send exactly one question object, not a multi-question form.",
61
63
  "Only non-critical preference/default assumptions may continue inline. STOP and ask when uncertainty affects scope, architecture, security, data loss, public API, migration, auth/pricing, or user approval.",
62
- "For simple greenfield web apps, present a compact A/B choice with one recommended path and one higher-upside challenger; keep the artifact concise but structurally complete (Context, Premise, How Might We, Sharpening Questions, Approaches, Reaction, Selected Direction, Not Doing).",
64
+ "For simple low-risk greenfield work, present a compact A/B choice with one recommended path and one higher-upside challenger; keep the artifact concise but structurally complete (Context, Premise, How Might We, Sharpening Questions, Approaches, Reaction, Selected Direction, Not Doing).",
63
65
  "Show approaches before the recommendation; include a higher-upside challenger and gather reaction first.",
64
66
  "Self-review before approval: re-read the artifact, fix contradictions/placeholders/weak trade-offs, then ask for approval. Do not ask for approval on a draft you have not re-read.",
65
67
  "State exactly what is being approved, then **STOP** until the user explicitly approves the artifact."
@@ -87,11 +89,12 @@ export const BRAINSTORM = {
87
89
  "2-3 approaches with trade-offs are recorded, including one higher-upside challenger option and reference-pattern source/disposition when applicable.",
88
90
  "User reaction to approaches is captured before final recommendation.",
89
91
  "Final recommendation explicitly reflects user reaction.",
92
+ "Early-loop status is reflected via `Victory Detector` / `Critic Pass` sections and `.cclaw/state/early-loop.json` when concerns remain.",
90
93
  "Selected Direction includes the handoff to the track-aware next stage: scope on standard, spec on medium when scope/design are skipped.",
91
94
  "When a promising option is parked, a seed file is created under `.cclaw/seeds/` and referenced in the artifact.",
92
95
  "Approved direction and approval marker are present.",
93
96
  "Assumptions and open questions are captured (or explicitly marked as none).",
94
- "Scope handoff includes upstream decisions used, explicit drift, confidence, unresolved questions, next-stage risk hints, and non-goals."
97
+ "Scope handoff packet includes selected direction, upstream decisions used, explicit drift, confidence, unresolved questions, next-stage risk hints, and non-goals."
95
98
  ],
96
99
  inputs: ["problem statement", "constraints", "success criteria"],
97
100
  requiredContext: [
@@ -141,10 +144,13 @@ export const BRAINSTORM = {
141
144
  { section: "Reference Pattern Candidates", required: false, validationRule: "Recommended when examples influence direction: list pattern/source, reusable invariant, accept/reject/defer disposition, and reason before approaches are finalized." },
142
145
  { section: "Approaches", required: true, validationRule: "Must compare 2-3 distinct options with real trade-offs. Use the canonical `Role` column with `baseline` | `challenger` | `wild-card` and the `Upside` column with `low` | `modest` | `high` | `higher`; include exactly one challenger row with `high` or `higher` upside, and cite reference-pattern source/disposition when applicable." },
143
146
  { section: "Approach Reaction", required: true, validationRule: "Must appear before Selected Direction and summarize user reaction before recommendation, including `Closest option`, `Concerns`, and what changed after reaction." },
144
- { section: "Selected Direction", required: true, validationRule: "Must include the selected approach, explicit approval marker, rationale traceable to Approach Reaction, and scope handoff with decisions, drift, confidence, unresolved questions, risk hints, and non-goals." },
147
+ { section: "Selected Direction", required: true, validationRule: "Must include the selected approach, explicit approval marker, rationale traceable to Approach Reaction, and a scope handoff packet with selected direction, decisions, drift, confidence, unresolved questions, risk hints, and non-goals." },
148
+ { section: "Embedded Grill", required: false, validationRule: "Recommended after Selected Direction: 3-5 rows covering hidden constraints, reversibility/rollback, scope boundaries, existing-pattern fit, and domain-language alignment. Each row records question, recommended answer, and disposition (accept/refine/reject)." },
145
149
  { section: "Not Doing", required: false, validationRule: "Recommended: 3-5 explicitly non-committed items (distinct from deferred). Protects scope from silent enlargement and the next stage from rework." },
146
150
  { section: "Design", required: false, validationRule: "Must cover architecture, key components, and data flow scaled to complexity." },
147
151
  { section: "Visual Companion", required: false, validationRule: "If architecture/data-flow complexity is medium+, include compact ASCII/Mermaid diagram or explicitly justify omission." },
152
+ { section: "Victory Detector", required: false, validationRule: "Recommended early-loop checkpoint: cite `.cclaw/state/early-loop.json`, current iteration/maxIterations, open concern count, convergence status, and iterate/ready/escalate decision." },
153
+ { section: "Critic Pass", required: false, validationRule: "Recommended producer/critic log contract: each iteration appends one JSONL row to `.cclaw/state/early-loop-log.jsonl` with runId, stage, iteration, and open concerns." },
148
154
  { section: "Self-Review Notes", required: false, validationRule: "Recommended: use the calibrated review format — `- Status: Approved` (or `Issues Found`), `- Patches applied:` (inline note or sub-bullets, use `None` if nothing changed), `- Remaining concerns:` (inline note or sub-bullets, use `None` if nothing remains). Done before requesting user approval." },
149
155
  { section: "Assumptions and Open Questions", required: false, validationRule: "Must capture unresolved assumptions/open questions, or explicitly state none." }
150
156
  ],