cclaw-cli 0.51.21 → 0.51.23

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 (48) hide show
  1. package/README.md +14 -13
  2. package/dist/config.d.ts +8 -1
  3. package/dist/config.js +9 -6
  4. package/dist/content/examples.js +2 -2
  5. package/dist/content/hook-manifest.d.ts +2 -4
  6. package/dist/content/hook-manifest.js +5 -7
  7. package/dist/content/learnings.js +5 -2
  8. package/dist/content/meta-skill.d.ts +1 -0
  9. package/dist/content/meta-skill.js +16 -9
  10. package/dist/content/next-command.js +2 -2
  11. package/dist/content/node-hooks.js +14 -4
  12. package/dist/content/review-loop.js +15 -5
  13. package/dist/content/review-prompts.js +1 -1
  14. package/dist/content/skills.js +16 -11
  15. package/dist/content/stage-command.d.ts +2 -0
  16. package/dist/content/stage-command.js +17 -0
  17. package/dist/content/stage-schema.js +1 -0
  18. package/dist/content/stages/brainstorm.js +3 -3
  19. package/dist/content/stages/design.js +18 -17
  20. package/dist/content/stages/plan.js +2 -1
  21. package/dist/content/stages/review.js +15 -15
  22. package/dist/content/stages/scope.js +14 -14
  23. package/dist/content/stages/spec.js +7 -5
  24. package/dist/content/stages/tdd.js +11 -4
  25. package/dist/content/start-command.d.ts +4 -3
  26. package/dist/content/start-command.js +21 -17
  27. package/dist/content/subagents.js +14 -4
  28. package/dist/content/templates.d.ts +1 -1
  29. package/dist/content/templates.js +49 -29
  30. package/dist/content/track-render-context.js +7 -0
  31. package/dist/content/view-command.js +3 -1
  32. package/dist/delegation.d.ts +2 -2
  33. package/dist/delegation.js +40 -13
  34. package/dist/doctor-registry.js +1 -1
  35. package/dist/doctor.js +222 -34
  36. package/dist/gate-evidence.js +19 -7
  37. package/dist/harness-adapters.d.ts +14 -11
  38. package/dist/harness-adapters.js +154 -22
  39. package/dist/install.js +116 -28
  40. package/dist/internal/advance-stage.js +90 -11
  41. package/dist/knowledge-store.d.ts +4 -1
  42. package/dist/knowledge-store.js +24 -14
  43. package/dist/retro-gate.d.ts +1 -0
  44. package/dist/retro-gate.js +9 -9
  45. package/dist/run-archive.js +19 -1
  46. package/dist/run-persistence.js +6 -2
  47. package/dist/tdd-cycle.js +6 -3
  48. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
1
  export declare const ARTIFACT_TEMPLATES: Record<string, string>;
2
2
  export declare const RULEBOOK_MARKDOWN = "# Cclaw Rulebook\n\n## MUST_ALWAYS\n- Follow flow order: brainstorm -> scope -> design -> spec -> plan -> tdd -> review -> ship\n- Require explicit user confirmation after plan before TDD\n- Keep evidence artifacts in `.cclaw/artifacts/`\n- Enforce RED before GREEN in TDD\n- Run two-layer review (spec_compliance and code_quality) before ship\n- Validate all inputs before processing \u2014 never trust external data without sanitization\n- Prefer immutable data patterns and pure functions where the language supports them\n- Follow existing repo conventions, patterns, and directory structure \u2014 match the codebase\n- Verify claims with fresh evidence: \"tests pass\" requires running tests in this message\n- Use conventional commits: `type(scope): description` (feat, fix, refactor, test, docs, chore)\n\n## MUST_NEVER\n- Skip RED phase and jump directly to GREEN in TDD\n- Ship with critical review findings\n- Start implementation during /brainstorm\n- Modify generated cclaw files manually when CLI can regenerate them\n- Commit `.cclaw/` or generated shim files\n- Expose secrets, tokens, API keys, or absolute system paths in agent output\n- Duplicate existing functionality without explicit justification \u2014 search before building\n- Bypass security checks, linting hooks, or type checking to \"move faster\"\n- Claim success (\"Done,\" \"All good,\" \"Tests pass\") without running verification in this message\n- Make changes outside the blast radius of the current task without user consent\n\n## DELEGATION\nWhen a task requires specialist knowledge (security audit, performance profiling, database review),\ndelegate to a specialized agent or skill if the harness supports it. The primary agent should:\n1. Identify the specialist domain\n2. Provide focused context (relevant files, the specific concern)\n3. Evaluate the specialist output before acting on it \u2014 do not blindly apply recommendations\n";
3
- 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-next`.\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 or medium 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-next` = 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- Do not mark gates passed from memory.\n- Keep evidence in `.cclaw/artifacts/`; archive via `npx cclaw-cli archive`.\n\n## Delegation And Approvals\n\n- Machine-only checks in design/plan/tdd/review/ship should auto-dispatch when tooling supports it.\n- Ask for user input only at explicit approval gates (scope mode, plan approval, challenge resolution, ship finalization).\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";
3
+ 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-next`.\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-next` = 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- Do not mark gates passed from memory.\n- Keep evidence in `.cclaw/artifacts/`; archive via `npx cclaw-cli archive`.\n\n## Delegation And Approvals\n\n- Machine-only checks in design/plan/tdd/review/ship should auto-dispatch when tooling supports it.\n- Ask for user input only at explicit approval gates (scope mode, plan approval, challenge resolution, ship finalization).\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";
4
4
  export declare function buildRulesJson(): Record<string, unknown>;
@@ -143,6 +143,7 @@ ${SEED_SHELF_SECTION}
143
143
  | Reversibility cost? | | |
144
144
 
145
145
  ## Dream State Mapping
146
+ - Deep/optional only; omit for compact scope.
146
147
  - CURRENT STATE:
147
148
  - THIS PLAN:
148
149
  - 12-MONTH IDEAL:
@@ -156,6 +157,7 @@ ${SEED_SHELF_SECTION}
156
157
  | C (optional) | | | | | | |
157
158
 
158
159
  ## Temporal Interrogation
160
+ - Deep/optional only; omit for compact scope.
159
161
  | Time slice | Likely decision pressure | Lock now or defer? | Reason |
160
162
  |---|---|---|---|
161
163
  | HOUR 1 (foundations) | | | |
@@ -170,12 +172,11 @@ ${SEED_SHELF_SECTION}
170
172
  - [ ] SCOPE REDUCTION — strip to the smallest useful wedge when risk/blast radius is too high.
171
173
 
172
174
  ## Mode-Specific Analysis
173
- - **Selected mode:**
174
- - **Analysis:**
175
- - (SCOPE EXPANSION: 10-star opportunities, delight features)
176
- - (SELECTIVE EXPANSION: hold-scope baseline, cherry-picked expansions)
177
- - (HOLD SCOPE: approved slice with maximum rigor)
178
- - (SCOPE REDUCTION: ruthless cuts, follow-up split)
175
+ | Selected mode | Rationale | Depth |
176
+ |---|---|---|
177
+ | | | default / deep |
178
+
179
+ > Default path: one selected-mode row plus rationale. Deep/high-risk scope may expand below with mode-specific analysis.
179
180
 
180
181
  ## Requirements (stable IDs)
181
182
  | ID | Requirement (observable outcome) | Priority | Source (origin doc / prompt line) |
@@ -224,7 +225,7 @@ ${SEED_SHELF_SECTION}
224
225
  |---|---|---|---|---|
225
226
  | F-1 | premise_fit | | accept/reject/defer | |
226
227
 
227
- ## Spec Review Loop
228
+ ## Scope Outside Voice Loop
228
229
  | Iteration | Quality Score | Findings | Stop decision |
229
230
  |---|---|---|---|
230
231
  | 1 | 0.00 | 0 | continue/stop |
@@ -288,8 +289,13 @@ ${SEED_SHELF_SECTION}
288
289
 
289
290
  # Design Artifact
290
291
 
292
+ ## Compact-First Scaffold
293
+ - Default to the compact design spine unless risk requires Standard/Deep add-ons.
294
+ - Compact required spine: Codebase Investigation, Architecture Boundaries, Architecture Diagram, Data Flow, Failure Mode Table, Test Strategy, and Completion Dashboard.
295
+ - Mark optional Standard/Deep sections as \`Omitted - compact design\` when they do not apply; do not expand the scaffold just to fill empty tables.
296
+
291
297
  ## Upstream Handoff
292
- - Source artifacts: \`02-scope-<slug>.md\`, \`02a-research.md\` when present
298
+ - Source artifacts: \`02-scope-<slug>.md\`, \`02a-research.md\` only when present for deep/high-risk research
293
299
  - Decisions carried forward:
294
300
  - Constraints carried forward:
295
301
  - Open questions:
@@ -308,12 +314,11 @@ ${SEED_SHELF_SECTION}
308
314
  | Layer 3 | | |
309
315
 
310
316
  ## Research Fleet Synthesis
311
- | Lens | Key findings | Design impact | Evidence |
317
+ | Lens actually run | Key findings | Design impact | Evidence |
312
318
  |---|---|---|---|
313
- | stack-researcher | | | |
314
- | features-researcher | | | |
315
- | architecture-researcher | | | |
316
- | pitfalls-researcher | | | |
319
+ | compact inline synthesis | | | |
320
+
321
+ > Default path: compact inline synthesis here. Deep/high-risk work may also write \`.cclaw/artifacts/02a-research.md\`.
317
322
 
318
323
  ## Architecture Boundaries
319
324
  | Component | Responsibility | Requirement Refs (R#) | Decision Refs (LD#hash) | Owner |
@@ -329,12 +334,14 @@ ${MARKDOWN_CODE_FENCE}
329
334
  ${MARKDOWN_CODE_FENCE}
330
335
 
331
336
  ## Data-Flow Shadow Paths
337
+ - Standard/Deep add-on; omit when compact design does not need a shadow path.
332
338
  <!-- diagram: data-flow-shadow-paths -->
333
339
  | Path | Trigger | Fallback/Degrade behavior |
334
340
  |---|---|---|
335
341
  | | | |
336
342
 
337
343
  ## Error Flow Diagram
344
+ - Standard/Deep add-on; omit when the Failure Mode Table is sufficient.
338
345
 
339
346
  <!-- diagram: error-flow -->
340
347
 
@@ -343,6 +350,7 @@ ${MARKDOWN_CODE_FENCE}
343
350
  ${MARKDOWN_CODE_FENCE}
344
351
 
345
352
  ## State Machine Diagram
353
+ - Deep add-on; omit for compact design.
346
354
 
347
355
  <!-- diagram: state-machine -->
348
356
 
@@ -351,6 +359,7 @@ ${MARKDOWN_CODE_FENCE}
351
359
  ${MARKDOWN_CODE_FENCE}
352
360
 
353
361
  ## Rollback Flowchart
362
+ - Deep add-on; omit for compact design.
354
363
 
355
364
  <!-- diagram: rollback-flowchart -->
356
365
 
@@ -359,6 +368,7 @@ ${MARKDOWN_CODE_FENCE}
359
368
  ${MARKDOWN_CODE_FENCE}
360
369
 
361
370
  ## Deployment Sequence Diagram
371
+ - Deep add-on; omit for compact design.
362
372
 
363
373
  <!-- diagram: deployment-sequence -->
364
374
 
@@ -426,7 +436,7 @@ ${MARKDOWN_CODE_FENCE}
426
436
  |---|---|---|---|---|
427
437
  | F-1 | architecture_fit | | accept/reject/defer | |
428
438
 
429
- ## Spec Review Loop
439
+ ## Design Outside Voice Loop
430
440
  | Iteration | Quality Score | Findings | Stop decision |
431
441
  |---|---|---|---|
432
442
  | 1 | 0.00 | 0 | continue/stop |
@@ -439,6 +449,7 @@ ${MARKDOWN_CODE_FENCE}
439
449
  -
440
450
 
441
451
  ## Parallelization Strategy
452
+ - Standard/Deep add-on when multi-module; omit for compact sequential work.
442
453
  - Parallel lanes:
443
454
  - Conflict risks:
444
455
 
@@ -448,11 +459,13 @@ ${MARKDOWN_CODE_FENCE}
448
459
  | | | |
449
460
 
450
461
  ## Interface Contracts
462
+ - Standard/Deep add-on when module boundaries or APIs change; omit for compact local changes.
451
463
  | Module | Produces | Consumes |
452
464
  |---|---|---|
453
465
  | | | |
454
466
 
455
467
  ## Unresolved Decisions
468
+ - Standard/Deep add-on; use \`None\` for compact design with no unresolved decisions.
456
469
  | Decision | Missing info | Owner | Default |
457
470
  |---|---|---|---|
458
471
  | | | | |
@@ -481,7 +494,7 @@ ${SEED_SHELF_SECTION}
481
494
  # Specification Artifact
482
495
 
483
496
  ## Upstream Handoff
484
- - Source artifacts: \`02-scope-<slug>.md\`, \`03-design-<slug>.md\`
497
+ - Source artifacts: standard uses \`02-scope-<slug>.md\` + \`03-design-<slug>.md\`; medium uses \`01-brainstorm-<slug>.md\` when present; quick uses \`00-idea.md\` plus reproduction context.
485
498
  - Decisions carried forward:
486
499
  - Constraints carried forward:
487
500
  - Open questions:
@@ -492,9 +505,14 @@ ${SEED_SHELF_SECTION}
492
505
  |---|---|---|---|
493
506
  | AC-1 | R1 | | |
494
507
 
495
- > Every AC must reference at least one \`R#\` from \`02-scope.md\`. ACs are
496
- > stable (never renumber): dropped ACs stay with Priority \`DROPPED\`; new
497
- > ones append with the next free \`AC-#\`.
508
+ > Standard ACs reference at least one \`R#\` from \`02-scope.md\`. Quick-track ACs may instead put \`Quick Reproduction Contract\` / bug-slice refs in the Requirement Ref column and \`N/A\` for Design Decision Ref. ACs are stable (never renumber): dropped ACs stay with Priority \`DROPPED\`; new ones append with the next free \`AC-#\`.
509
+
510
+ ## Quick Reproduction Contract
511
+ > Required for quick bug-fix specs; use \`N/A\` for non-bugfix or standard/medium tracks. TDD turns this contract into the RED reproduction test.
512
+
513
+ | Bug slice | Symptom | Repro steps | Expected RED test behavior | Linked acceptance criterion |
514
+ |---|---|---|---|---|
515
+ | QS-1 | | | | AC-1 |
498
516
 
499
517
  ## Edge Cases
500
518
  | Criterion ID | Boundary case | Error case |
@@ -627,7 +645,7 @@ Execution rule: complete and verify each batch before starting the next batch.
627
645
  # TDD Artifact
628
646
 
629
647
  ## Upstream Handoff
630
- - Source artifacts: \`04-spec.md\`, \`05-plan.md\`
648
+ - Source artifacts: \`04-spec.md\` plus the active track's upstream source item (plan slice on standard/medium, spec acceptance item or bug reproduction slice on quick).
631
649
  - Decisions carried forward:
632
650
  - Constraints carried forward:
633
651
  - Open questions:
@@ -654,9 +672,11 @@ Execution rule: complete and verify each batch before starting the next batch.
654
672
  | S-1 | | | |
655
673
 
656
674
  ## Acceptance Mapping
657
- | Slice | Plan task ID | Spec criterion ID |
675
+ | Slice | Source item ID | Spec criterion ID |
658
676
  |---|---|---|
659
- | S-1 | T-1 | AC-1 |
677
+ | S-1 | SRC-1 | AC-1 |
678
+
679
+ > Map each slice to the active track's source item: plan slice on standard/medium, or the \`Quick Reproduction Contract\` bug slice / spec acceptance item on quick.
660
680
 
661
681
  ## Failure Analysis
662
682
  | Slice | Expected missing behavior | Actual failure reason |
@@ -673,7 +693,7 @@ Execution rule: complete and verify each batch before starting the next batch.
673
693
  - Behavior preserved:
674
694
 
675
695
  ## Traceability
676
- - Plan task IDs:
696
+ - Source item IDs:
677
697
  - Spec criterion IDs:
678
698
 
679
699
 
@@ -709,7 +729,7 @@ Execution rule: complete and verify each batch before starting the next batch.
709
729
  # Review Artifact
710
730
 
711
731
  ## Upstream Handoff
712
- - Source artifacts: \`04-spec.md\`, \`05-plan.md\`, \`06-tdd.md\`
732
+ - Source artifacts: \`04-spec.md\`, \`06-tdd.md\`, plus the active track's upstream source item when available.
713
733
  - Decisions carried forward:
714
734
  - Constraints carried forward:
715
735
  - Open questions:
@@ -723,7 +743,7 @@ Execution rule: complete and verify each batch before starting the next batch.
723
743
  ## Layer 2 Findings
724
744
  | ID | Severity | Category | Description | Status |
725
745
  |---|---|---|---|---|
726
- | R-1 | Critical/Important/Suggestion | correctness/security/performance/architecture | | open/resolved |
746
+ | R-1 | Critical/Important/Suggestion | correctness/security/performance/architecture/external-safety | | open/resolved |
727
747
  - NO_CHANGE_ATTESTATION: <required when Category=security has no entries; explain why no security-relevant changes were detected>
728
748
 
729
749
  ## Incoming Feedback Queue
@@ -746,15 +766,15 @@ Execution rule: complete and verify each batch before starting the next batch.
746
766
 
747
767
  ## Completeness Snapshot
748
768
  - AC coverage: <N>/<M> (<percent>%)
749
- - Task coverage (tasks backed by ≥1 test slice): <N>/<M>
750
- - Slice coverage (slices linked to ≥1 AC): <N>/<M>
769
+ - Source item coverage (source items backed by ≥1 test slice): <N>/<M> or \`N/A - direct spec/reproduction coverage\`
770
+ - Slice coverage (slices linked to ≥1 AC or bug reproduction slice): <N>/<M>
751
771
  - Adversarial review: not triggered | pass | fail
752
772
  - Overall: complete | concerns | blocked
753
773
 
754
774
  ## Trace Matrix Check
755
- - Command: \`cclaw internal trace-matrix\`
775
+ - Command: \`cclaw internal trace-matrix\` when the active track enforces it; otherwise record direct AC/reproduction-slice coverage.
756
776
  - Orphaned criteria: 0
757
- - Orphaned tasks: 0
777
+ - Orphaned source items: 0 or \`N/A - direct spec/reproduction coverage\`
758
778
  - Orphaned tests: 0
759
779
  - Evidence ref:
760
780
 
@@ -955,7 +975,7 @@ Track-specific skips are allowed only when \`flow-state.track\` + \`skippedStage
955
975
  | Class | Route |
956
976
  |---|---|
957
977
  | non-trivial software work | \`/cc <idea>\` |
958
- | trivial software fix | \`/cc <idea>\` (quick or medium track) |
978
+ | trivial software fix | \`/cc <idea>\` (quick track) |
959
979
  | bugfix with repro | \`/cc <idea>\` and enforce RED-first in tdd |
960
980
  | pure question / non-software | direct answer (no stage flow) |
961
981
 
@@ -34,8 +34,15 @@ export function renderTrackTerminology(value, context) {
34
34
  }
35
35
  return value
36
36
  .replace(/\btask from the plan\b/giu, `${context.traceabilitySourceNoun} from the spec`)
37
+ .replace(/\bplan confirmation\b/giu, "spec approval")
38
+ .replace(/\bplan approval\b/giu, "spec approval")
39
+ .replace(/\bapproved plan slice\b/giu, `approved ${context.traceabilitySliceNoun}`)
40
+ .replace(/\bplanned slice\b/giu, context.traceabilitySliceNoun)
37
41
  .replace(/\bplan task ID\b/giu, context.traceabilityIdNoun)
38
42
  .replace(/\bplan task\b/giu, context.traceabilitySourceNoun)
43
+ .replace(/\bplan-task\b/giu, "acceptance-criterion")
44
+ .replace(/\btask coverage\b/giu, "source item coverage")
45
+ .replace(/\borphaned tasks\b/giu, "orphaned source items")
39
46
  .replace(/\bplan row\b/giu, "acceptance row")
40
47
  .replace(/\btraceable to plan slice\b/giu, `traceable to ${context.traceabilitySliceNoun}`)
41
48
  .replace(/\bplan slice\b/giu, context.traceabilitySliceNoun)
@@ -37,9 +37,11 @@ ${conversationLanguagePolicyMarkdown()}
37
37
  For machine orchestration, emit one JSON envelope:
38
38
 
39
39
  \`\`\`json
40
- {"version":"1","kind":"stage-output","stage":"non-flow","payload":{"command":"/cc-view","subcommand":"status","summary":"<short>"},"emittedAt":"<ISO-8601>"}
40
+ {"version":"1","kind":"stage-output","stage":"non-flow","payload":{"command":"/cc-view <status|tree|diff>","subcommand":"<status|tree|diff>","summary":"<short>"},"emittedAt":"<ISO-8601>"}
41
41
  \`\`\`
42
42
 
43
+ Use the parsed/defaulted subcommand in both \`payload.command\` and \`payload.subcommand\`; do not collapse \`tree\` or \`diff\` responses to \`status\`.
44
+
43
45
  Validate envelopes with:
44
46
  \`cclaw internal envelope-validate --stdin\`
45
47
 
@@ -6,8 +6,8 @@ export type DelegationStatus = "scheduled" | "completed" | "failed" | "waived";
6
6
  * How a delegation was actually fulfilled. Advisory — mirrors the harness
7
7
  * `subagentFallback` that was in effect when the entry was recorded.
8
8
  *
9
- * - `isolated` — Claude-style isolated subagent worker.
10
- * - `generic-dispatch` — Cursor-style Task dispatch mapped to a named role.
9
+ * - `isolated` — native isolated subagent worker (Claude/OpenCode/Codex).
10
+ * - `generic-dispatch` — generic Task/Subagent dispatch mapped to a named role.
11
11
  * - `role-switch` — performed in-session with explicit role announce.
12
12
  * - `harness-waiver` — auto-waived due to missing dispatch capability.
13
13
  */
@@ -18,6 +18,13 @@ function delegationLockPath(projectRoot) {
18
18
  function createSpanId() {
19
19
  return `dspan-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
20
20
  }
21
+ function activeHarnessSubagentFallback() {
22
+ const activeHarness = process.env.CCLAW_ACTIVE_HARNESS;
23
+ if (!activeHarness)
24
+ return undefined;
25
+ return HARNESS_ADAPTERS[activeHarness]
26
+ ?.capabilities.subagentFallback;
27
+ }
21
28
  async function resolveReviewDiffBase(projectRoot) {
22
29
  let head = "";
23
30
  try {
@@ -103,6 +110,9 @@ async function detectReviewTriggers(projectRoot) {
103
110
  return empty;
104
111
  }
105
112
  }
113
+ function hasValidWaiverReason(value) {
114
+ return typeof value === "string" && value.trim().length > 0;
115
+ }
106
116
  function isDelegationTokenUsage(value) {
107
117
  if (!value || typeof value !== "object" || Array.isArray(value))
108
118
  return false;
@@ -130,6 +140,7 @@ function isDelegationEntry(value) {
130
140
  Number.isFinite(o.retryCount) &&
131
141
  Number.isInteger(o.retryCount) &&
132
142
  o.retryCount >= 0);
143
+ const waiverOk = o.status !== "waived" || hasValidWaiverReason(o.waiverReason);
133
144
  return (typeof o.stage === "string" &&
134
145
  typeof o.agent === "string" &&
135
146
  modeOk &&
@@ -141,6 +152,7 @@ function isDelegationEntry(value) {
141
152
  (o.endTs === undefined || typeof o.endTs === "string") &&
142
153
  (o.taskId === undefined || typeof o.taskId === "string") &&
143
154
  (o.waiverReason === undefined || typeof o.waiverReason === "string") &&
155
+ waiverOk &&
144
156
  (o.runId === undefined || typeof o.runId === "string") &&
145
157
  (o.fulfillmentMode === undefined ||
146
158
  o.fulfillmentMode === "isolated" ||
@@ -165,8 +177,10 @@ function parseLedger(raw, runId) {
165
177
  for (const item of entriesRaw) {
166
178
  if (isDelegationEntry(item)) {
167
179
  const ts = item.startTs ?? item.ts ?? new Date().toISOString();
168
- const inferredFulfillmentMode = item.fulfillmentMode
169
- ?? (item.status === "completed" ? "isolated" : undefined);
180
+ const isLegacyCompletion = item.fulfillmentMode === undefined &&
181
+ item.schemaVersion === undefined &&
182
+ item.status === "completed";
183
+ const inferredFulfillmentMode = item.fulfillmentMode ?? (isLegacyCompletion ? "isolated" : undefined);
170
184
  entries.push({
171
185
  ...item,
172
186
  spanId: item.spanId ?? createSpanId(),
@@ -205,6 +219,9 @@ export async function appendDelegation(projectRoot, entry) {
205
219
  const filePath = delegationLogPath(projectRoot);
206
220
  const prior = await readDelegationLedger(projectRoot);
207
221
  const startTs = entry.startTs ?? entry.ts ?? new Date().toISOString();
222
+ if (entry.status === "waived" && !hasValidWaiverReason(entry.waiverReason)) {
223
+ throw new Error("waived delegation entries require a non-empty waiverReason");
224
+ }
208
225
  const stamped = { ...entry, runId: entry.runId ?? activeRunId };
209
226
  stamped.spanId = entry.spanId ?? createSpanId();
210
227
  stamped.startTs = startTs;
@@ -219,10 +236,16 @@ export async function appendDelegation(projectRoot, entry) {
219
236
  stamped.evidenceRefs = [];
220
237
  }
221
238
  if (stamped.status === "completed" && stamped.fulfillmentMode === undefined) {
222
- const config = await readConfig(projectRoot).catch(() => null);
223
- const harnesses = config?.harnesses ?? [];
224
- const fallbacks = harnesses.map((h) => HARNESS_ADAPTERS[h].capabilities.subagentFallback);
225
- stamped.fulfillmentMode = expectedFulfillmentMode(fallbacks);
239
+ const activeFallback = activeHarnessSubagentFallback();
240
+ if (activeFallback) {
241
+ stamped.fulfillmentMode = expectedFulfillmentMode([activeFallback]);
242
+ }
243
+ else {
244
+ const config = await readConfig(projectRoot).catch(() => null);
245
+ const harnesses = config?.harnesses ?? [];
246
+ const fallbacks = harnesses.map((h) => HARNESS_ADAPTERS[h].capabilities.subagentFallback);
247
+ stamped.fulfillmentMode = expectedFulfillmentMode(fallbacks);
248
+ }
226
249
  }
227
250
  // Idempotency: if a caller (or a retried hook) tries to append a row
228
251
  // with a spanId that already exists in the ledger, treat it as a no-op
@@ -256,10 +279,11 @@ export function expectedFulfillmentMode(fallbacks) {
256
279
  return "harness-waiver";
257
280
  }
258
281
  export async function checkMandatoryDelegations(projectRoot, stage, options = {}) {
259
- const mandatory = stageSchema(stage).mandatoryDelegations;
260
- const { activeRunId } = await readFlowState(projectRoot, {
282
+ const flowState = await readFlowState(projectRoot, {
261
283
  repairFeatureSystem: options.repairFeatureSystem
262
284
  });
285
+ const mandatory = stageSchema(stage, flowState.track).mandatoryDelegations;
286
+ const { activeRunId } = flowState;
263
287
  const ledger = await readDelegationLedger(projectRoot);
264
288
  const forStage = ledger.entries.filter((e) => e.stage === stage);
265
289
  const forRun = forStage.filter((e) => e.runId === activeRunId);
@@ -271,8 +295,9 @@ export async function checkMandatoryDelegations(projectRoot, stage, options = {}
271
295
  const missingEvidence = [];
272
296
  const config = await readConfig(projectRoot).catch(() => null);
273
297
  const harnesses = config?.harnesses ?? [];
274
- const fallbacks = harnesses.map((h) => HARNESS_ADAPTERS[h].capabilities.subagentFallback);
275
- const expectedMode = expectedFulfillmentMode(fallbacks);
298
+ const configuredFallbacks = harnesses.map((h) => HARNESS_ADAPTERS[h].capabilities.subagentFallback);
299
+ const activeFallback = activeHarnessSubagentFallback();
300
+ const expectedMode = expectedFulfillmentMode(activeFallback ? [activeFallback] : configuredFallbacks);
276
301
  for (const agent of mandatory) {
277
302
  const rows = forRun.filter((e) => e.agent === agent);
278
303
  const completedRows = rows.filter((e) => e.status === "completed");
@@ -287,9 +312,11 @@ export async function checkMandatoryDelegations(projectRoot, stage, options = {}
287
312
  if (hasWaived) {
288
313
  waived.push(agent);
289
314
  }
290
- // Evidence is required for any non-isolated completion mode. Legacy rows
291
- // without fulfillmentMode are inferred to `isolated` during parse.
292
- const evidenceRequired = completedRows.some((e) => (e.fulfillmentMode ?? "isolated") !== "isolated");
315
+ // Evidence is required for non-isolated completions and for explicit
316
+ // degraded role-switch rows. Native OpenCode/Codex/Claude isolated
317
+ // dispatch is accepted as true subagent work; role-switch remains a
318
+ // fallback that must point at artifact evidence.
319
+ const evidenceRequired = expectedMode !== "isolated" || completedRows.some((e) => (e.fulfillmentMode ?? "isolated") !== "isolated");
293
320
  if (hasCompleted &&
294
321
  evidenceRequired &&
295
322
  !completedRows.some((e) => Array.isArray(e.evidenceRefs) && e.evidenceRefs.length > 0)) {
@@ -39,7 +39,7 @@ const RULES = [
39
39
  }
40
40
  },
41
41
  {
42
- test: /^(dir:|command:|utility_command:|skill:|utility_skill:|agent:|harness_tool_ref:|harness_ref:|stage_examples_ref:|doctor_ref:)/,
42
+ test: /^(dir:|command:|utility_command:|stage_command:|skill:|utility_skill:|agent:|harness_tool_ref:|harness_ref:|stage_examples_ref:|doctor_ref:)/,
43
43
  metadata: {
44
44
  severity: "error",
45
45
  summary: "Generated runtime surface presence check.",