cclaw-cli 6.4.0 → 6.5.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.
@@ -43,11 +43,11 @@ export async function lintScopeStage(ctx) {
43
43
  const skipByTrack = shouldDemoteArtifactValidationByTrack(track, taskClass);
44
44
  if (skipByTrack) {
45
45
  findings.push({
46
- section: "Expansion Strategist Delegation",
46
+ section: "Product Discovery Delegation (Strategist Mode)",
47
47
  required: false,
48
48
  rule: "When Scope Summary selects SCOPE EXPANSION or SELECTIVE EXPANSION, a completed `product-discovery` delegation for the active run with non-empty evidenceRefs is required.",
49
49
  found: true,
50
- details: `Expansion Strategist delegation requirement skipped for track="${track}"` +
50
+ details: `Product-discovery delegation requirement skipped for track="${track}"` +
51
51
  (taskClass ? `, taskClass="${taskClass}"` : "") +
52
52
  ` (Wave 25: lite-tier escape; selectedMode=${selectedScopeMode}).`
53
53
  });
@@ -78,12 +78,12 @@ export async function lintScopeStage(ctx) {
78
78
  const hasCompleted = discoveryRows.length > 0;
79
79
  const hasEvidence = discoveryRows.some((entry) => Array.isArray(entry.evidenceRefs) && entry.evidenceRefs.length > 0);
80
80
  findings.push({
81
- section: "Expansion Strategist Delegation",
81
+ section: "Product Discovery Delegation (Strategist Mode)",
82
82
  required: true,
83
83
  rule: "When Scope Summary selects SCOPE EXPANSION or SELECTIVE EXPANSION, a completed `product-discovery` delegation for the active run with non-empty evidenceRefs is required.",
84
84
  found: hasCompleted && hasEvidence,
85
85
  details: !hasCompleted
86
- ? `Scope mode ${selectedScopeMode} requires a completed product-discovery delegation row for active run ${delegationLedger.runId}.`
86
+ ? `Scope mode ${selectedScopeMode} requires a completed product-discovery delegation row for active run ${delegationLedger.runId}. In SELECTIVE EXPANSION / SCOPE EXPANSION, run product-discovery (mode=proactive) BEFORE stage-complete.`
87
87
  : hasEvidence
88
88
  ? `product-discovery delegation satisfied for mode ${selectedScopeMode}.`
89
89
  : "product-discovery delegation exists but evidenceRefs is empty; add at least one artifact/code evidence reference."
@@ -367,7 +367,7 @@ export async function lintArtifact(projectRoot, stage, track = "standard", optio
367
367
  * - `Architecture Diagram` — sync/async + failure-edge enforcement
368
368
  * - `Data Flow` — Interaction Edge Case mandatory rows
369
369
  * - `Stale Diagram Drift Check` — blast-radius file mtime audit
370
- * - `Expansion Strategist Delegation` — product-discovery delegation
370
+ * - `Product Discovery Delegation (Strategist Mode)` — product-discovery delegation
371
371
  *
372
372
  * Findings remain in the result so the caller can surface them as
373
373
  * advisory hints; only `required` flips to `false`.
@@ -376,5 +376,5 @@ const ARTIFACT_VALIDATION_LITE_DEMOTE_SECTIONS = new Set([
376
376
  "Architecture Diagram",
377
377
  "Data Flow",
378
378
  "Stale Diagram Drift Check",
379
- "Expansion Strategist Delegation"
379
+ "Product Discovery Delegation (Strategist Mode)"
380
380
  ]);
@@ -380,6 +380,47 @@ function buildRow(args, status, runId, now) {
380
380
  };
381
381
  }
382
382
 
383
+ async function acquireDelegationLogLock(stateDir) {
384
+ const lockDir = path.join(stateDir, "delegation-log.json.lock");
385
+ const maxWaitMs = 3000;
386
+ const startMs = Date.now();
387
+ let delayMs = 25;
388
+ while (true) {
389
+ try {
390
+ await fs.mkdir(lockDir, { recursive: false });
391
+ return lockDir;
392
+ } catch (err) {
393
+ const code = err && typeof err === "object" && "code" in err ? err.code : "";
394
+ if (code !== "EEXIST") throw err;
395
+ if (Date.now() - startMs >= maxWaitMs) {
396
+ process.stderr.write(
397
+ "[cclaw] delegation-record: timeout waiting for delegation-log.json.lock (max " + maxWaitMs + "ms)\\n"
398
+ );
399
+ process.exit(2);
400
+ }
401
+ const jitter = Math.floor(Math.random() * 25);
402
+ await new Promise((resolve) => setTimeout(resolve, delayMs + jitter));
403
+ delayMs = Math.min(delayMs * 2, 200);
404
+ }
405
+ }
406
+ }
407
+
408
+ async function releaseDelegationLogLock(lockDir) {
409
+ try {
410
+ await fs.rm(lockDir, { recursive: true, force: true });
411
+ } catch {
412
+ // best-effort release
413
+ }
414
+ }
415
+
416
+ async function writeDelegationLedgerAtomic(ledgerPath, ledger) {
417
+ const dir = path.dirname(ledgerPath);
418
+ const tmp =
419
+ path.join(dir, ".delegation-log.json." + process.pid + "." + Date.now() + "." + Math.random().toString(16).slice(2) + ".tmp");
420
+ await fs.writeFile(tmp, JSON.stringify(ledger, null, 2) + "\\n", { encoding: "utf8", mode: 0o600 });
421
+ await fs.rename(tmp, ledgerPath);
422
+ }
423
+
383
424
  async function persistEntry(root, runId, clean, event, options = {}) {
384
425
  const stateDir = path.join(root, RUNTIME_ROOT, "state");
385
426
  await fs.mkdir(stateDir, { recursive: true });
@@ -387,29 +428,34 @@ async function persistEntry(root, runId, clean, event, options = {}) {
387
428
 
388
429
  const ledgerPath = path.join(stateDir, "delegation-log.json");
389
430
  let ledger = { runId, entries: [], schemaVersion: LEDGER_SCHEMA_VERSION };
431
+ const lockDir = await acquireDelegationLogLock(stateDir);
390
432
  try {
391
- ledger = JSON.parse(await fs.readFile(ledgerPath, "utf8"));
392
- if (!Array.isArray(ledger.entries)) ledger.entries = [];
393
- } catch {
394
- ledger = { runId, entries: [], schemaVersion: LEDGER_SCHEMA_VERSION };
395
- }
396
-
397
- // Rerecord semantics: replace any pre-existing row with the same spanId
398
- // (regardless of its status) so the legacy v1/v2 row is upgraded to v3
399
- // shape on disk. The append path keeps the historical dedup semantics:
400
- // an exact (spanId, status) duplicate is dropped to keep retried hooks
401
- // idempotent.
402
- if (options.replaceBySpanId) {
403
- ledger.entries = ledger.entries.filter((entry) => entry.spanId !== clean.spanId);
404
- ledger.entries.push(clean);
405
- ledger.runId = runId;
406
- ledger.schemaVersion = LEDGER_SCHEMA_VERSION;
407
- await fs.writeFile(ledgerPath, JSON.stringify(ledger, null, 2) + "\\n", { encoding: "utf8", mode: 0o600 });
408
- } else if (!ledger.entries.some((entry) => entry.spanId === clean.spanId && entry.status === clean.status)) {
409
- ledger.entries.push(clean);
410
- ledger.runId = runId;
411
- ledger.schemaVersion = LEDGER_SCHEMA_VERSION;
412
- await fs.writeFile(ledgerPath, JSON.stringify(ledger, null, 2) + "\\n", { encoding: "utf8", mode: 0o600 });
433
+ try {
434
+ ledger = JSON.parse(await fs.readFile(ledgerPath, "utf8"));
435
+ if (!Array.isArray(ledger.entries)) ledger.entries = [];
436
+ } catch {
437
+ ledger = { runId, entries: [], schemaVersion: LEDGER_SCHEMA_VERSION };
438
+ }
439
+
440
+ // Rerecord semantics: replace any pre-existing row with the same spanId
441
+ // (regardless of its status) so the legacy v1/v2 row is upgraded to v3
442
+ // shape on disk. The append path keeps the historical dedup semantics:
443
+ // an exact (spanId, status) duplicate is dropped to keep retried hooks
444
+ // idempotent.
445
+ if (options.replaceBySpanId) {
446
+ ledger.entries = ledger.entries.filter((entry) => entry.spanId !== clean.spanId);
447
+ ledger.entries.push(clean);
448
+ ledger.runId = runId;
449
+ ledger.schemaVersion = LEDGER_SCHEMA_VERSION;
450
+ await writeDelegationLedgerAtomic(ledgerPath, ledger);
451
+ } else if (!ledger.entries.some((entry) => entry.spanId === clean.spanId && entry.status === clean.status)) {
452
+ ledger.entries.push(clean);
453
+ ledger.runId = runId;
454
+ ledger.schemaVersion = LEDGER_SCHEMA_VERSION;
455
+ await writeDelegationLedgerAtomic(ledgerPath, ledger);
456
+ }
457
+ } finally {
458
+ await releaseDelegationLogLock(lockDir);
413
459
  }
414
460
 
415
461
  const active = ledger.entries.filter((entry) => ["scheduled", "launched", "acknowledged"].includes(entry.status));
@@ -192,7 +192,7 @@ function autoSubagentDispatchBlock(stage, track) {
192
192
  |---|---|---|---|---|---|---|---|
193
193
  ${rows}
194
194
  Mandatory: ${mandatoryList}. Record lifecycle rows in \`${delegationLogRel}\` and append-only \`${delegationEventsRel}\` before completion.${runPhaseLegend}
195
- ### Harness Dispatch Contract — use true harness dispatch: Claude Task, Cursor generic dispatch, OpenCode \`.opencode/agents/<agent>.md\` via Task/@agent, Codex \`.codex/agents/<agent>.toml\`. Do not collapse OpenCode or Codex to role-switch by default. Worker ACK Contract: ACK must include \`spanId\`, \`dispatchId\`, \`dispatchSurface\`, \`agentDefinitionPath\`, and \`ackTs\`; never claim \`fulfillmentMode: "isolated"\` without matching lifecycle proof. Helper: \`.cclaw/hooks/delegation-record.mjs --status=<status> --span-id=<spanId> --dispatch-id=<dispatchId> --dispatch-surface=<surface> --agent-definition-path=<path> --json\`. Exact recipe: scheduled -> launched -> acknowledged -> completed with the same span; completed isolated/generic rows require a prior ACK event for that span or \`--ack-ts=<iso>\`.
195
+ ### Harness Dispatch Contract — use true harness dispatch: Claude Task, Cursor generic dispatch, OpenCode \`.opencode/agents/<agent>.md\` via Task/@agent, Codex \`.codex/agents/<agent>.toml\`. Do not collapse OpenCode or Codex to role-switch by default. Worker ACK Contract: ACK must include \`spanId\`, \`dispatchId\`, \`dispatchSurface\`, \`agentDefinitionPath\`, and \`ackTs\`; never claim \`fulfillmentMode: "isolated"\` without matching lifecycle proof. Canonical helper (same flags as \`delegation-record.mjs --help\`): \`node .cclaw/hooks/delegation-record.mjs --stage=<stage> --agent=<agent> --mode=<mandatory|proactive> --status=<scheduled|launched|acknowledged|completed|...> --span-id=<id> --dispatch-id=<id> --dispatch-surface=<surface> --agent-definition-path=<path> [--ack-ts=<iso>] [--evidence-ref=<ref>] --json\`. Lifecycle order: \`scheduled launched acknowledged completed\` on one span (reuse the same span id); completed isolated/generic rows require a prior ACK event for that span or \`--ack-ts=<iso>\`. For a partial audit trail, \`--repair --span-id=<id> --repair-reason="<why>"\` appends missing phases (see \`--help\`) instead of inventing shortcuts.
196
196
 
197
197
  ${perHarnessLifecycleRecipeBlock()}`;
198
198
  }
@@ -390,7 +390,7 @@ function completionParametersBlock(schema, track) {
390
390
  - If you edit any completed-stage artifact after it shipped (\`completedStageMeta\` timestamps exist), append a short \`## Amendments\` section with dated bullets (timestamp + reason) instead of overwriting the archived narrative silently — advisory linter rule \`stage_artifact_post_closure_mutation\` enforces visibility when this trail is missing.
391
391
  - 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.
392
392
  - Never edit raw \`flow-state.json\` to complete a stage, even in advisory mode; that bypasses validation, gate evidence, and Learnings harvest. If a helper fails, report a one-line human-readable failure plus fenced JSON diagnostics; never echo the invoking command line or apply a manual state workaround.
393
- - Stage completion claim requires \`stage-complete\` exit 0 in the current turn. Quote the success line; do not paraphrase, do not infer success from skipped retries.
393
+ - Stage completion claim requires \`stage-complete\` exit 0 in the current turn. Quote the single-line success JSON exactly as printed to stdout (for example \`{"ok":true,"command":"stage-complete",...}\` including \`completedStages\` / \`currentStage\` / \`runId\`); do not paraphrase. Do not infer success from empty stdout or from skipped retries (quiet mode always emits one JSON line on success).
394
394
  - Completion protocol: verify required gates, update the artifact, then use the completion helper with \`--evidence-json\` and \`--passed\` for every satisfied gate.
395
395
  `;
396
396
  }
@@ -412,7 +412,7 @@ ${completionBlock}
412
412
  - **NEVER paste the \`--evidence-json\` payload into chat.** It is structured data for the helper, not for the user. The same evidence already lives in the artifact section.
413
413
  - On failure, report a compact human-readable summary based on the helper's JSON \`findings\` array — list failing section names only (one line each), include the full helper JSON in a single fenced \`json\` block. Do not echo the invoking command.
414
414
  - **NEVER run shell hash commands** (\`shasum\`, \`sha256sum\`, \`md5sum\`, \`Get-FileHash\`, \`certutil\`, etc.) for hash compute. If the linter ever asks for a hash, that is a linter bug — report failure and stop, do not auto-fix in bash.
415
- - The helper defaults to quiet success (\`CCLAW_STAGE_COMPLETE_QUIET=1\`); rely on the resulting JSON, not stdout chatter.
415
+ - The helper defaults to quiet (\`CCLAW_STAGE_COMPLETE_QUIET=1\`): no pretty-printed chatter, but **stdout still prints exactly one line** of machine-readable success JSON (same contract as \`start-flow\` in quiet mode).
416
416
  `;
417
417
  }
418
418
  function quickStartBlock(stage, track) {
@@ -52,6 +52,7 @@ export const SCOPE = {
52
52
  "**Premise carry-forward (do NOT re-author)** — brainstorm OWNS the premise check (right problem / direct path / what if nothing). Cite brainstorm's `## Premise Check` section in `## Upstream Handoff > Decisions carried forward`. Add a row to `## Premise Drift` only when the scope-stage Q&A surfaced NEW evidence that materially changes the brainstorm answer (e.g. new constraint, new user signal). Otherwise mark `Premise Drift: None` — do not duplicate the brainstorm premise table.",
53
53
  "**Conditional 10-star boundary** — for deep/high-risk/product-strategy work, show what would make the product meaningfully better, then explicitly choose what ships now, what is deferred, and what is excluded without vague `later/for now` placeholders. Skip this for straightforward repair work and record `not needed: compact scope`.",
54
54
  "**Pick one operational mode with the user** — HOLD SCOPE preserves focus; SELECTIVE EXPANSION cherry-picks high-leverage reference ideas; SCOPE EXPANSION explores ambitious alternatives; SCOPE REDUCTION cuts to the essential wedge. Recommend one, state why and what signal would change it, then keep elicitation focused until the user either approves or asks to proceed with draft boundaries.",
55
+ "**Product-discovery is REQUIRED for SELECTIVE / SCOPE EXPANSION (hard gate)** — If the resolved scope mode is SELECTIVE EXPANSION or SCOPE EXPANSION, run \`product-discovery\` in proactive mode **after** adaptive elicitation converges and **before** \`stage-complete\`. Do not complete this stage until the delegation ledger shows \`product-discovery\` as \`completed\` with non-empty \`evidenceRefs\` pointing at this scope artifact. HOLD SCOPE and SCOPE REDUCTION do not require this row.",
55
56
  "**Run mode-specific analysis only to needed depth** — lean discovery keeps the selected-mode row compact; guided adds the standard contract rows; deep may add Landscape Check, Taste Calibration, Reference Pattern Registry, Reference Pull, Ambitious Alternatives, and Ruthless Minimum Slice evidence when mode/risk warrants it.",
56
57
  "**Decision-driver contract** — list weighted decision drivers (value, risk, reversibility, effort, timeline) and score candidate scope moves so the selected mode and boundaries are evidence-backed, not preference-led.",
57
58
  "**Architecture handoff (do NOT pick architecture tier here)** — design OWNS architecture choice (minimum-viable / product-grade / ideal). Scope only picks the SCOPE MODE (HOLD/SELECTIVE/EXPAND/REDUCE) and boundary; record in `## Scope Contract > Design handoff` what design must decide (e.g. `architecture-tier`, `framework`, `data-model`). Do NOT enumerate Implementation Alternatives in scope.",
@@ -7,5 +7,5 @@ export declare const RULEBOOK_MARKDOWN = "# Cclaw Rulebook\n\n## MUST_ALWAYS\n-
7
7
  * (premature draft, premature subagent dispatch, command-line echo to chat).
8
8
  */
9
9
  export declare const CURSOR_GUIDELINES_RULE_MDC = "---\ndescription: cclaw zero-install behavior baseline (always-on)\nglobs:\n - \"**/*\"\nalwaysApply: true\n---\n\n<!-- cclaw-managed-cursor-guidelines-rule -->\n\n# Cclaw Baseline Guidelines\n\nThese three rules apply to every Cursor agent session in this project,\nregardless of whether stage skills loaded.\n\n## 1. Q&A floor before drafting (brainstorm/scope/design)\n\nBefore drafting any `.cclaw/artifacts/01-brainstorm-*.md`,\n`02-scope-*.md`, or `03-design-*.md`, verify that the artifact's\n`## Q&A Log` table demonstrates Ralph-Loop convergence: every\nforcing-question topic id is tagged `[topic:<id>]` on at least one row\n(see the stage's forcing-questions checklist for the id list), the last\n2 turns produce no new decision-changing impact, OR an explicit user\nstop-signal row is recorded. Walk the stage forcing questions one at a\ntime via the `AskQuestion` tool. If you find yourself proposing a\ndraft after 1-2 questions while forcing topic ids remain untagged, STOP\nand continue the loop.\n\nThe `qa_log_unconverged` linter rule will block `stage-complete` when\nconvergence has not been reached. Wave 24 (v6.0.0) made `[topic:<id>]`\ntagging mandatory; the English keyword fallback was removed because it\nmis-reported convergence on RU/UA Q&A logs.\n\n## 2. Mandatory subagents run after Q&A approval\n\nFor brainstorm / scope / design, mandatory subagents (\n`product-discovery`, `critic`, `planner`, `architect`,\n`test-author`) run **only AFTER the user approves the elicitation\noutcome**, never before the Q&A loop converges. Dispatching them early\npreempts the user dialogue and violates the elicitation contract \u2014 the\nlinter will block stage-complete.\n\nSee each stage's \"Run Phase: post-elicitation\" rows in the materialized\nAutomatic Subagent Dispatch table.\n\n## 3. Never echo cclaw command lines to chat\n\nThe user does not run cclaw helpers (`node .cclaw/hooks/...`) manually.\nNEVER paste full command lines, `--evidence-json '{...}'` payloads,\n`--waive-delegation=...`, or shell hash commands (`shasum`,\n`sha256sum`, `Get-FileHash`, `certutil`, etc.) into chat. Run the\nhelper via the tool layer and report only the resulting summary. On\nfailure, report a compact human-readable summary plus the helper JSON in\na single fenced `json` block.\n";
10
- export declare const CURSOR_WORKFLOW_RULE_MDC = "---\ndescription: cclaw workflow guardrails for Cursor agent sessions\nglobs:\n - \"**/*\"\nalwaysApply: true\n---\n\n<!-- cclaw-managed-cursor-workflow-rule -->\n\n# Cclaw Workflow Guardrails\n\n## Activation Rule\n\nBefore responding to coding work:\n1. Read `.cclaw/state/flow-state.json`.\n2. Start with `/cc` or continue with `/cc`.\n3. If no software-stage flow applies, respond normally.\n\n## Stage Order\n\n`brainstorm -> scope -> design -> spec -> plan -> tdd -> review -> ship`\n\nTrack-specific skips are allowed only when `flow-state.track` + `skippedStages` explicitly say so.\n\n## Task Classification\n\n| Class | Route |\n|---|---|\n| non-trivial software work | `/cc <idea>` |\n| trivial software fix | `/cc <idea>` (quick track) |\n| bugfix with repro | `/cc <idea>` and enforce RED-first in tdd |\n| pure question / non-software | direct answer (no stage flow) |\n\n## Command Surface\n\n- `/cc` = entry and resume.\n- `/cc` = only progression path.\n- Knowledge capture and recall use the `learnings` skill when requested.\n\n## Verification Discipline\n\n- No completion claim without fresh command evidence in this turn.\n- Stage completion claim requires `stage-complete` exit 0 in the current turn. Quote the success line; do not paraphrase, do not infer success from skipped retries.\n\n## Protocol label hygiene\n\n`skip` wording means different things depending on phase: brainstorm/scope/design Q&A stop-signals may still literal **skip**/enough/move-on wording; structured ship closeout retros and compound clustering prompts should expose **no changes** (or accept-as-is language) rather than labeling the passive path as skip. Keep the verbs aligned with the harness question copy you present to the human.\n- Do not mark gates passed from memory.\n- Keep evidence in `.cclaw/artifacts/`; archive through closeout via `/cc` or cancel early via `node .cclaw/hooks/cancel-run.mjs`.\n\n## Delegation And Approvals\n\n- Machine-only checks in design/plan/tdd/review/ship should auto-dispatch when tooling supports it.\n- **For brainstorm / scope / design stages**: ask user input continuously via adaptive elicitation (one question per turn through the harness-native question tool \u2014 `AskQuestion` in Cursor). Walk the stage forcing-questions list one-by-one. **Tag each Q&A Log row's `Decision impact` cell with `[topic:<id>]`** (the id is given in the stage's forcing-questions checklist) so the linter can verify coverage in any natural language. Do NOT batch and do NOT defer to a single approval gate at the end. The `qa_log_unconverged` linter rule will block `stage-complete` when convergence is not reached (forcing topic ids untagged AND last 2 turns still produce decision-changing rows AND no stop-signal).\n- **For other stages** (spec/plan/tdd/build/review/ship): ask user input only at explicit approval gates (scope mode, plan approval, challenge resolution, ship finalization), not for routine progress updates.\n- If you find yourself proposing a draft after 1-2 questions in brainstorm/scope/design, STOP \u2014 go back to the forcing-questions list and continue.\n- Mandatory subagents in brainstorm/scope/design run only AFTER the user approves the elicitation outcome (see each stage's \"Run Phase: post-elicitation\" rows). Dispatching them before the Q&A loop converges violates the contract.\n- Never echo cclaw command lines (`node .cclaw/hooks/...`, `--evidence-json '{...}'`) to chat \u2014 the user does not run cclaw manually. Run helpers via the tool layer; report only the resulting summary.\n- If harness capabilities are partial, record waiver reasons in delegation logs.\n\n## Routing Source Of Truth\n\n- Primary router: `.cclaw/skills/using-cclaw/SKILL.md`.\n- Stage behavior: current stage skill plus `.cclaw/state/flow-state.json`.\n- Preamble budget: keep role/status announcements brief and avoid repeating\n them unless the stage or role changes.\n";
10
+ export declare const CURSOR_WORKFLOW_RULE_MDC = "---\ndescription: cclaw workflow guardrails for Cursor agent sessions\nglobs:\n - \"**/*\"\nalwaysApply: true\n---\n\n<!-- cclaw-managed-cursor-workflow-rule -->\n\n# Cclaw Workflow Guardrails\n\n## Activation Rule\n\nBefore responding to coding work:\n1. Read `.cclaw/state/flow-state.json`.\n2. Start with `/cc` or continue with `/cc`.\n3. If no software-stage flow applies, respond normally.\n\n## Stage Order\n\n`brainstorm -> scope -> design -> spec -> plan -> tdd -> review -> ship`\n\nTrack-specific skips are allowed only when `flow-state.track` + `skippedStages` explicitly say so.\n\n## Task Classification\n\n| Class | Route |\n|---|---|\n| non-trivial software work | `/cc <idea>` |\n| trivial software fix | `/cc <idea>` (quick track) |\n| bugfix with repro | `/cc <idea>` and enforce RED-first in tdd |\n| pure question / non-software | direct answer (no stage flow) |\n\n## Command Surface\n\n- `/cc` = entry and resume.\n- `/cc` = only progression path.\n- Knowledge capture and recall use the `learnings` skill when requested.\n\n## Verification Discipline\n\n- No completion claim without fresh command evidence in this turn.\n- Stage completion claim requires `stage-complete` exit 0 in the current turn. Quote the single-line success JSON printed to stdout (e.g. `{\"ok\":true,\"command\":\"stage-complete\",...}`); do not paraphrase, do not infer success from empty stdout or from skipped retries.\n\n## Protocol label hygiene\n\n`skip` wording means different things depending on phase: brainstorm/scope/design Q&A stop-signals may still literal **skip**/enough/move-on wording; structured ship closeout retros and compound clustering prompts should expose **no changes** (or accept-as-is language) rather than labeling the passive path as skip. Keep the verbs aligned with the harness question copy you present to the human.\n- Do not mark gates passed from memory.\n- Keep evidence in `.cclaw/artifacts/`; archive through closeout via `/cc` or cancel early via `node .cclaw/hooks/cancel-run.mjs`.\n\n## Delegation And Approvals\n\n- Machine-only checks in design/plan/tdd/review/ship should auto-dispatch when tooling supports it.\n- **For brainstorm / scope / design stages**: ask user input continuously via adaptive elicitation (one question per turn through the harness-native question tool \u2014 `AskQuestion` in Cursor). Walk the stage forcing-questions list one-by-one. **Tag each Q&A Log row's `Decision impact` cell with `[topic:<id>]`** (the id is given in the stage's forcing-questions checklist) so the linter can verify coverage in any natural language. Do NOT batch and do NOT defer to a single approval gate at the end. The `qa_log_unconverged` linter rule will block `stage-complete` when convergence is not reached (forcing topic ids untagged AND last 2 turns still produce decision-changing rows AND no stop-signal).\n- **For other stages** (spec/plan/tdd/build/review/ship): ask user input only at explicit approval gates (scope mode, plan approval, challenge resolution, ship finalization), not for routine progress updates.\n- If you find yourself proposing a draft after 1-2 questions in brainstorm/scope/design, STOP \u2014 go back to the forcing-questions list and continue.\n- Mandatory subagents in brainstorm/scope/design run only AFTER the user approves the elicitation outcome (see each stage's \"Run Phase: post-elicitation\" rows). Dispatching them before the Q&A loop converges violates the contract.\n- Never echo cclaw command lines (`node .cclaw/hooks/...`, `--evidence-json '{...}'`) to chat \u2014 the user does not run cclaw manually. Run helpers via the tool layer; report only the resulting summary.\n- If harness capabilities are partial, record waiver reasons in delegation logs.\n\n## Routing Source Of Truth\n\n- Primary router: `.cclaw/skills/using-cclaw/SKILL.md`.\n- Stage behavior: current stage skill plus `.cclaw/state/flow-state.json`.\n- Preamble budget: keep role/status announcements brief and avoid repeating\n them unless the stage or role changes.\n";
11
11
  export declare function buildRulesJson(): Record<string, unknown>;
@@ -1565,7 +1565,7 @@ Track-specific skips are allowed only when \`flow-state.track\` + \`skippedStage
1565
1565
  ## Verification Discipline
1566
1566
 
1567
1567
  - No completion claim without fresh command evidence in this turn.
1568
- - Stage completion claim requires \`stage-complete\` exit 0 in the current turn. Quote the success line; do not paraphrase, do not infer success from skipped retries.
1568
+ - Stage completion claim requires \`stage-complete\` exit 0 in the current turn. Quote the single-line success JSON printed to stdout (e.g. \`{"ok":true,"command":"stage-complete",...}\`); do not paraphrase, do not infer success from empty stdout or from skipped retries.
1569
1569
 
1570
1570
  ## Protocol label hygiene
1571
1571
 
@@ -601,7 +601,17 @@ export async function runAdvanceStage(projectRoot, args, io) {
601
601
  interactionHints
602
602
  };
603
603
  await writeFlowState(projectRoot, finalState);
604
- if (!args.quiet) {
604
+ if (args.quiet) {
605
+ io.stdout.write(`${JSON.stringify({
606
+ ok: true,
607
+ command: "stage-complete",
608
+ stage: args.stage,
609
+ completedStages: finalState.completedStages,
610
+ currentStage: finalState.currentStage,
611
+ runId: finalState.activeRunId
612
+ })}\n`);
613
+ }
614
+ else {
605
615
  io.stdout.write(`${JSON.stringify({
606
616
  ok: true,
607
617
  command: "advance-stage",
@@ -211,19 +211,31 @@ export async function runStartFlow(projectRoot, args, io) {
211
211
  nextState = { ...nextState, repoSignals };
212
212
  await writeFlowState(projectRoot, nextState, { allowReset: true });
213
213
  await appendIdeaArtifact(projectRoot, args, current);
214
- if (!args.quiet) {
214
+ const successPayload = {
215
+ ok: true,
216
+ command: "start-flow",
217
+ reclassify: args.reclassify,
218
+ track: nextState.track,
219
+ discoveryMode: nextState.discoveryMode,
220
+ taskClass: nextState.taskClass ?? null,
221
+ currentStage: nextState.currentStage,
222
+ skippedStages: nextState.skippedStages,
223
+ activeRunId: nextState.activeRunId,
224
+ repoSignals
225
+ };
226
+ if (args.quiet) {
215
227
  io.stdout.write(`${JSON.stringify({
216
228
  ok: true,
217
229
  command: "start-flow",
218
- reclassify: args.reclassify,
219
- track: nextState.track,
220
- discoveryMode: nextState.discoveryMode,
221
- taskClass: nextState.taskClass ?? null,
222
- currentStage: nextState.currentStage,
223
- skippedStages: nextState.skippedStages,
224
- activeRunId: nextState.activeRunId,
225
- repoSignals
226
- }, null, 2)}\n`);
230
+ track: successPayload.track,
231
+ discoveryMode: successPayload.discoveryMode,
232
+ currentStage: successPayload.currentStage,
233
+ activeRunId: successPayload.activeRunId,
234
+ repoSignals: successPayload.repoSignals
235
+ })}\n`);
236
+ }
237
+ else {
238
+ io.stdout.write(`${JSON.stringify(successPayload, null, 2)}\n`);
227
239
  }
228
240
  return 0;
229
241
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cclaw-cli",
3
- "version": "6.4.0",
3
+ "version": "6.5.0",
4
4
  "description": "Installer-first flow toolkit for coding agents",
5
5
  "type": "module",
6
6
  "bin": {