cclaw-cli 6.14.4 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/README.md +0 -2
  2. package/dist/artifact-linter/brainstorm.js +1 -1
  3. package/dist/artifact-linter/design.js +2 -2
  4. package/dist/artifact-linter/findings-dedup.js +1 -1
  5. package/dist/artifact-linter/plan.js +6 -6
  6. package/dist/artifact-linter/review-army.d.ts +1 -1
  7. package/dist/artifact-linter/review-army.js +1 -1
  8. package/dist/artifact-linter/scope.js +6 -6
  9. package/dist/artifact-linter/shared.d.ts +37 -73
  10. package/dist/artifact-linter/shared.js +30 -37
  11. package/dist/artifact-linter/spec.js +1 -1
  12. package/dist/artifact-linter/tdd.d.ts +20 -33
  13. package/dist/artifact-linter/tdd.js +89 -639
  14. package/dist/artifact-linter.js +11 -32
  15. package/dist/cli.js +1 -1
  16. package/dist/config.js +1 -1
  17. package/dist/constants.js +1 -1
  18. package/dist/content/core-agents.d.ts +8 -26
  19. package/dist/content/core-agents.js +48 -94
  20. package/dist/content/examples.d.ts +1 -1
  21. package/dist/content/examples.js +4 -4
  22. package/dist/content/hooks.js +62 -149
  23. package/dist/content/idea.js +2 -2
  24. package/dist/content/iron-laws.js +1 -1
  25. package/dist/content/node-hooks.js +2 -2
  26. package/dist/content/skills-elicitation.js +2 -2
  27. package/dist/content/skills.d.ts +4 -6
  28. package/dist/content/skills.js +14 -53
  29. package/dist/content/stage-schema.d.ts +3 -3
  30. package/dist/content/stage-schema.js +8 -46
  31. package/dist/content/stages/brainstorm.js +5 -5
  32. package/dist/content/stages/plan.js +2 -2
  33. package/dist/content/stages/review.js +1 -1
  34. package/dist/content/stages/schema-types.d.ts +1 -1
  35. package/dist/content/stages/scope.js +1 -1
  36. package/dist/content/stages/spec.js +2 -2
  37. package/dist/content/stages/tdd.js +43 -108
  38. package/dist/content/start-command.js +3 -3
  39. package/dist/content/subagent-context-skills.js +5 -3
  40. package/dist/content/subagents.js +13 -74
  41. package/dist/content/templates.d.ts +6 -6
  42. package/dist/content/templates.js +23 -24
  43. package/dist/content/utility-skills.d.ts +1 -1
  44. package/dist/content/utility-skills.js +1 -1
  45. package/dist/delegation.d.ts +79 -139
  46. package/dist/delegation.js +83 -215
  47. package/dist/early-loop.js +1 -1
  48. package/dist/flow-state.d.ts +24 -129
  49. package/dist/flow-state.js +5 -30
  50. package/dist/gate-evidence.d.ts +2 -7
  51. package/dist/gate-evidence.js +2 -59
  52. package/dist/harness-adapters.d.ts +1 -1
  53. package/dist/harness-adapters.js +11 -10
  54. package/dist/install.js +24 -459
  55. package/dist/internal/advance-stage/advance.d.ts +5 -5
  56. package/dist/internal/advance-stage/advance.js +9 -24
  57. package/dist/internal/advance-stage/parsers.d.ts +1 -1
  58. package/dist/internal/advance-stage/review-loop.d.ts +1 -1
  59. package/dist/internal/advance-stage/review-loop.js +3 -3
  60. package/dist/internal/advance-stage/start-flow.js +1 -3
  61. package/dist/internal/advance-stage.js +4 -23
  62. package/dist/internal/cohesion-contract-stub.d.ts +8 -13
  63. package/dist/internal/cohesion-contract-stub.js +18 -24
  64. package/dist/internal/flow-state-repair.d.ts +1 -1
  65. package/dist/internal/plan-split-waves.d.ts +18 -21
  66. package/dist/internal/plan-split-waves.js +16 -19
  67. package/dist/internal/wave-status.d.ts +3 -6
  68. package/dist/internal/wave-status.js +5 -27
  69. package/dist/policy.js +1 -1
  70. package/dist/run-persistence.js +10 -44
  71. package/dist/runtime/run-hook.mjs +3 -3
  72. package/dist/track-heuristics.js +1 -1
  73. package/dist/types.d.ts +2 -2
  74. package/package.json +1 -1
  75. package/dist/integration-fanin.d.ts +0 -44
  76. package/dist/integration-fanin.js +0 -180
  77. package/dist/internal/set-checkpoint-mode.d.ts +0 -16
  78. package/dist/internal/set-checkpoint-mode.js +0 -72
  79. package/dist/internal/set-integration-overseer-mode.d.ts +0 -14
  80. package/dist/internal/set-integration-overseer-mode.js +0 -69
  81. package/dist/internal/set-worktree-mode.d.ts +0 -10
  82. package/dist/internal/set-worktree-mode.js +0 -28
  83. package/dist/worktree-manager.d.ts +0 -50
  84. package/dist/worktree-manager.js +0 -136
  85. package/dist/worktree-types.d.ts +0 -36
  86. package/dist/worktree-types.js +0 -6
@@ -294,22 +294,9 @@ async function readRunId(root) {
294
294
  }
295
295
  }
296
296
 
297
- async function readWorktreeExecutionModeInline(root) {
298
- try {
299
- const raw = await fs.readFile(path.join(root, RUNTIME_ROOT, "state", "flow-state.json"), "utf8");
300
- const parsed = JSON.parse(raw);
301
- if (parsed && parsed.worktreeExecutionMode === "worktree-first") {
302
- return "worktree-first";
303
- }
304
- return "single-tree";
305
- } catch {
306
- return "single-tree";
307
- }
308
- }
309
-
310
- // v6.14.2 — read \`tddGreenMinElapsedMs\` from flow-state.json. Defaults to
311
- // 4000ms when missing or invalid. Operators set 0 to disable the freshness
312
- // floor while keeping RED-test-name and passing-assertion checks active.
297
+ // Read \`tddGreenMinElapsedMs\` from flow-state.json. Defaults to 4000ms
298
+ // when missing or invalid. Operators set 0 to disable the freshness floor
299
+ // while keeping RED-test-name and passing-assertion checks active.
313
300
  async function readTddGreenMinElapsedMsInline(root) {
314
301
  try {
315
302
  const raw = await fs.readFile(path.join(root, RUNTIME_ROOT, "state", "flow-state.json"), "utf8");
@@ -323,11 +310,11 @@ async function readTddGreenMinElapsedMsInline(root) {
323
310
  }
324
311
  }
325
312
 
326
- // v6.14.2 Fix 4 — match the RED test name into the GREEN evidenceRef.
327
- // Returns the basename or stem (without extension) of the most-specific
328
- // path token in the RED row's first evidenceRef. We deliberately use a
329
- // substring match, not equality, so callers can include richer text
330
- // like "REGRESSION: cargo test --test foo => 8 passed; 0 failed".
313
+ // Match the RED test name into the GREEN evidenceRef. Returns the
314
+ // basename or stem (without extension) of the most-specific path token
315
+ // in the RED row's first evidenceRef. We deliberately use a substring
316
+ // match, not equality, so callers can include richer text like
317
+ // "REGRESSION: cargo test --test foo => 8 passed; 0 failed".
331
318
  function extractRedTestNameInline(redEvidenceRef) {
332
319
  if (typeof redEvidenceRef !== "string") return null;
333
320
  const trimmed = redEvidenceRef.trim();
@@ -351,8 +338,8 @@ function extractRedTestNameInline(redEvidenceRef) {
351
338
  // pytest: "===== N passed in 0.42s ====="
352
339
  // go test: "ok pkg 0.123s"
353
340
  // npm/jest/vitest: "Tests: N passed"
354
- // We accept a generic shape: "=> N passed; 0 failed" (the example in
355
- // the v6.14.2 worker contract) plus four runner-specific patterns.
341
+ // We accept a generic shape: "=> N passed; 0 failed" plus four
342
+ // runner-specific patterns.
356
343
  const GREEN_PASS_PATTERNS = [
357
344
  /=>\\s*\\d+\\s+passed/iu,
358
345
  /\\b\\d+\\s+passed[;,]\\s*0\\s+failed\\b/iu,
@@ -403,7 +390,7 @@ function usage() {
403
390
  " node .cclaw/hooks/delegation-record.mjs --stage=<stage> --agent=<agent> --mode=<mandatory|proactive> --status=<scheduled|launched|acknowledged|completed|failed|waived|stale> --span-id=<id> [--dispatch-id=<id>] [--worker-run-id=<id>] [--dispatch-surface=<surface>] [--agent-definition-path=<path>] [--ack-ts=<iso>] [--launched-ts=<iso>] [--completed-ts=<iso>] [--evidence-ref=<ref>] [--waiver-reason=<text>] [--supersede=<prevSpanId>] [--allow-parallel] [--paths=<comma-separated>] [--override-cap=<int>] [--json]",
404
391
  " node .cclaw/hooks/delegation-record.mjs --rerecord --span-id=<id> --dispatch-id=<id> --dispatch-surface=<surface> --agent-definition-path=<path> [--ack-ts=<iso>] [--completed-ts=<iso>] [--evidence-ref=<ref>] [--json]",
405
392
  " node .cclaw/hooks/delegation-record.mjs --repair --span-id=<id> --repair-reason=\\\"<why>\\\" [--json]",
406
- " node .cclaw/hooks/delegation-record.mjs --audit-kind=cclaw_integration_overseer_skipped [--audit-reason=\\\"<comma-separated reasons>\\\"] [--slice-ids=\\\"S-1,S-2\\\"] [--json] # v6.14.1: emit non-delegation audit row only",
393
+ " node .cclaw/hooks/delegation-record.mjs --audit-kind=cclaw_integration_overseer_skipped [--audit-reason=\\\"<comma-separated reasons>\\\"] [--slice-ids=\\\"S-1,S-2\\\"] [--json] # non-delegation audit row",
407
394
  "",
408
395
  "Allowed --dispatch-surface values:",
409
396
  " " + VALID_DISPATCH_SURFACES.join(", "),
@@ -411,25 +398,20 @@ function usage() {
411
398
  "Per-surface allowed --agent-definition-path prefixes:",
412
399
  ...VALID_DISPATCH_SURFACES.map((surface) => " " + surface + ": " + (SURFACE_PATH_PREFIXES[surface].length === 0 ? "(any)" : SURFACE_PATH_PREFIXES[surface].join(", "))),
413
400
  "",
414
- "Dispatch dedup (v6.8.0):",
401
+ "Dispatch dedup:",
415
402
  " --supersede=<prevSpanId> close the previous active span on this (stage, agent) as 'stale' before recording the new scheduled row",
416
403
  " --allow-parallel record both spans as concurrent; new row is tagged allowParallel: true",
417
404
  "",
418
- "TDD parallel scheduler (v6.10.0):",
419
- " --paths=<a,b,c> repo-relative paths the slice-implementer will edit; disjoint sets auto-promote to allowParallel, overlap throws DispatchOverlapError",
420
- " --override-cap=<int> raise the slice-implementer fan-out cap once for this dispatch (default cap " + String(5) + ", env CCLAW_MAX_PARALLEL_SLICE_IMPLEMENTERS overrides globally)",
405
+ "TDD parallel scheduler:",
406
+ " --paths=<a,b,c> repo-relative paths the slice-builder will edit; disjoint sets auto-promote to allowParallel, overlap throws DispatchOverlapError",
407
+ " --override-cap=<int> raise the slice worker fan-out cap once for this dispatch (default cap " + String(5) + ", env CCLAW_MAX_PARALLEL_SLICE_BUILDERS overrides globally)",
421
408
  "",
422
- "TDD slice phase tagging (v6.11.0):",
409
+ "TDD slice phase tagging:",
423
410
  " --slice=<id> TDD slice identifier (e.g. S-1) used by the linter to auto-derive the Watched-RED + Vertical Slice Cycle tables.",
424
411
  " --phase=<phase> one of " + VALID_DELEGATION_PHASES.join(", ") + ". Pair with --slice to record a TDD slice phase event.",
425
- " --refactor-rationale=<t> required when --phase=refactor-deferred unless --evidence-ref carries the rationale text. v6.14.0: also paired with --refactor-outcome on phase=green.",
426
- " --claim-token=<opaque> v6.13 required for worktree-first slice-implementer schedules with --slice (echo on all terminal rows for the span).",
427
- " --lane-id=<id> v6.13 worktree lane id (ownerLaneId metadata).",
428
- " --lease-until=<iso> v6.13 — ISO8601 lease expiry for reclaim tooling.",
429
- " --depends-on=<a,b> v6.13 — comma-separated plan unit ids for scheduler diagnostics.",
430
- " --integration-state=<s> v6.13 — one of pending|applied|conflict|resolved|abandoned.",
431
- " --refactor-outcome=<m> v6.14.0 — one of inline|deferred. Folds REFACTOR into the phase=green event so a single row can close RED→GREEN→REFACTOR. Pair --refactor-outcome=deferred with --refactor-rationale.",
432
- " --risk-tier=<t> v6.14.0 — one of low|medium|high. high triggers integration-overseer in conditional mode.",
412
+ " --refactor-rationale=<t> required when --phase=refactor-deferred unless --evidence-ref carries the rationale text; also paired with --refactor-outcome on phase=green.",
413
+ " --refactor-outcome=<m> one of inline|deferred. Folds REFACTOR into the phase=green event so a single row can close RED→GREEN→REFACTOR. Pair --refactor-outcome=deferred with --refactor-rationale.",
414
+ " --risk-tier=<t> one of low|medium|high. high triggers integration-overseer in conditional mode.",
433
415
  ""
434
416
  ].join("\\n") + "\\n");
435
417
  }
@@ -531,16 +513,15 @@ function buildRow(args, status, runId, now, options) {
531
513
  // Inherit the span's startTs from prior rows so monotonic validation
532
514
  // can compare against the original schedule, not the row write time.
533
515
  const startTs = (options && options.spanStartTs) || now;
534
- // v6.10.0 (P1): claimedPaths from --paths=<comma-separated>. Empty
535
- // arrays are dropped so the row stays compatible with v6.9 readers.
516
+ // claimedPaths from --paths=<comma-separated>. Empty arrays are dropped.
536
517
  const claimedPathsRaw = typeof args.paths === "string" ? args.paths : "";
537
518
  const claimedPaths = claimedPathsRaw
538
519
  .split(",")
539
520
  .map((value) => value.trim())
540
521
  .filter((value) => value.length > 0);
541
- // v6.11.0 (D1+D2): TDD slice tagging via --slice / --phase. Phase
542
- // must be one of the canonical enum values; the inline validator
543
- // rejects unknown phases before the row hits the ledger.
522
+ // TDD slice tagging via --slice / --phase. Phase must be one of the
523
+ // canonical enum values; the inline validator rejects unknown phases
524
+ // before the row hits the ledger.
544
525
  const sliceId =
545
526
  typeof args.slice === "string" && args.slice.trim().length > 0
546
527
  ? args.slice.trim()
@@ -549,10 +530,10 @@ function buildRow(args, status, runId, now, options) {
549
530
  typeof args.phase === "string" && args.phase.trim().length > 0
550
531
  ? args.phase.trim()
551
532
  : undefined;
552
- // v6.11.0 (D2): when --refactor-rationale is supplied it is folded
553
- // into evidenceRefs[0] so the linter (which reads evidenceRefs only)
554
- // can surface the rationale without touching new fields. The user
555
- // may also pass --evidence-ref containing the rationale text.
533
+ // When --refactor-rationale is supplied it is folded into
534
+ // evidenceRefs[0] so the linter (which reads evidenceRefs only) can
535
+ // surface the rationale without touching new fields. The user may
536
+ // also pass --evidence-ref containing the rationale text.
556
537
  let resolvedEvidenceRefs = normalizeEvidenceRefs(args);
557
538
  if (
558
539
  phase === "refactor-deferred" &&
@@ -564,48 +545,12 @@ function buildRow(args, status, runId, now, options) {
564
545
  resolvedEvidenceRefs = [rationale, ...resolvedEvidenceRefs];
565
546
  }
566
547
  }
567
- const integrationStateRaw =
568
- typeof args["integration-state"] === "string" ? args["integration-state"].trim() : "";
569
- const integrationStateAllowed = new Set([
570
- "pending",
571
- "applied",
572
- "conflict",
573
- "resolved",
574
- "abandoned"
575
- ]);
576
- const integrationState =
577
- integrationStateRaw.length > 0 && integrationStateAllowed.has(integrationStateRaw)
578
- ? integrationStateRaw
579
- : undefined;
580
- const claimToken =
581
- typeof args["claim-token"] === "string" && args["claim-token"].trim().length > 0
582
- ? args["claim-token"].trim()
583
- : undefined;
584
- const ownerLaneId =
585
- typeof args["lane-id"] === "string" && args["lane-id"].trim().length > 0
586
- ? args["lane-id"].trim()
587
- : undefined;
588
- const leasedUntil =
589
- typeof args["lease-until"] === "string" && args["lease-until"].trim().length > 0
590
- ? args["lease-until"].trim()
591
- : undefined;
592
- const dependsOnRaw =
593
- typeof args["depends-on"] === "string" ? args["depends-on"].trim() : "";
594
- const dependsOn =
595
- dependsOnRaw.length > 0
596
- ? dependsOnRaw
597
- .split(",")
598
- .map((value) => value.trim())
599
- .filter((value) => value.length > 0)
600
- : undefined;
601
- const leaseState =
602
- leasedUntil && status === "scheduled" ? "claimed" : undefined;
603
- // v6.14.0: refactorOutcome folds REFACTOR into a phase=green event. We
604
- // also accept it on phase=refactor / phase=refactor-deferred for forward
605
- // compatibility with controllers that emit it on the legacy lifecycle.
606
- // When mode=deferred and a --refactor-rationale is supplied we also
607
- // mirror the rationale into evidenceRefs[0] so legacy linters keep
608
- // reading evidence (matches the v6.11.0 refactor-deferred behavior).
548
+ // refactorOutcome folds REFACTOR into a phase=green event. We also
549
+ // accept it on phase=refactor / phase=refactor-deferred for controllers
550
+ // that emit it on the per-phase lifecycle. When mode=deferred and a
551
+ // --refactor-rationale is supplied we mirror the rationale into
552
+ // evidenceRefs[0] so the linter keeps reading evidence (matches the
553
+ // refactor-deferred behavior).
609
554
  const refactorOutcomeMode =
610
555
  typeof args["refactor-outcome"] === "string"
611
556
  ? args["refactor-outcome"].trim()
@@ -659,12 +604,6 @@ function buildRow(args, status, runId, now, options) {
659
604
  claimedPaths: claimedPaths.length > 0 ? claimedPaths : undefined,
660
605
  sliceId,
661
606
  phase,
662
- claimToken,
663
- ownerLaneId,
664
- leasedUntil,
665
- leaseState,
666
- dependsOn,
667
- integrationState,
668
607
  refactorOutcome,
669
608
  riskTier
670
609
  };
@@ -690,9 +629,9 @@ function findActiveSpanForPairInline(stage, agent, runId, entries) {
690
629
  for (const entry of entries) {
691
630
  if (!entry || typeof entry !== "object") continue;
692
631
  if (typeof entry.spanId !== "string" || entry.spanId.length === 0) continue;
693
- // Strict run-scope (v6.9.0 R7 fix): legacy entries without a runId
694
- // are treated as foreign so they cannot keep an old span "active"
695
- // across runs and trip dispatch_duplicate on a fresh dispatch.
632
+ // Strict run-scope: entries without a runId are treated as foreign so
633
+ // they cannot keep an old span "active" across runs and trip
634
+ // dispatch_duplicate on a fresh dispatch.
696
635
  if (typeof entry.runId !== "string" || entry.runId.length === 0) continue;
697
636
  if (entry.runId !== runId) continue;
698
637
  if (entry.stage !== stage || entry.agent !== agent) continue;
@@ -730,7 +669,7 @@ function computeActiveSubagentsInline(entries) {
730
669
 
731
670
  // keep in sync with validateFileOverlap in src/delegation.ts
732
671
  function validateFileOverlapInline(stamped, activeEntries) {
733
- if (stamped.agent !== "slice-implementer" || stamped.stage !== "tdd") {
672
+ if (stamped.agent !== "slice-builder" || stamped.stage !== "tdd") {
734
673
  return { autoParallel: false, conflict: null };
735
674
  }
736
675
  const newPaths = Array.isArray(stamped.claimedPaths) ? stamped.claimedPaths : [];
@@ -767,10 +706,10 @@ function validateFileOverlapInline(stamped, activeEntries) {
767
706
  return { autoParallel: true, conflict: null };
768
707
  }
769
708
 
770
- const MAX_PARALLEL_SLICE_IMPLEMENTERS_INLINE = 5;
709
+ const MAX_PARALLEL_SLICE_BUILDERS_INLINE = 5;
771
710
 
772
711
  function readMaxParallelOverrideFromEnvInline() {
773
- const raw = process.env.CCLAW_MAX_PARALLEL_SLICE_IMPLEMENTERS;
712
+ const raw = process.env.CCLAW_MAX_PARALLEL_SLICE_BUILDERS;
774
713
  if (typeof raw !== "string" || raw.trim().length === 0) return null;
775
714
  const parsed = Number(raw);
776
715
  if (!Number.isFinite(parsed) || !Number.isInteger(parsed) || parsed < 1) return null;
@@ -779,13 +718,13 @@ function readMaxParallelOverrideFromEnvInline() {
779
718
 
780
719
  // keep in sync with validateFanOutCap in src/delegation.ts
781
720
  function validateFanOutCapInline(stamped, activeEntries, override) {
782
- if (stamped.agent !== "slice-implementer" || stamped.stage !== "tdd") return null;
721
+ if (stamped.agent !== "slice-builder" || stamped.stage !== "tdd") return null;
783
722
  if (stamped.status !== "scheduled") return null;
784
723
  let cap;
785
724
  if (override !== null && override !== undefined && Number.isInteger(override) && override >= 1) {
786
725
  cap = override;
787
726
  } else {
788
- cap = readMaxParallelOverrideFromEnvInline() || MAX_PARALLEL_SLICE_IMPLEMENTERS_INLINE;
727
+ cap = readMaxParallelOverrideFromEnvInline() || MAX_PARALLEL_SLICE_BUILDERS_INLINE;
789
728
  }
790
729
  const sameLaneActive = activeEntries.filter(
791
730
  (entry) =>
@@ -958,9 +897,9 @@ async function findLegacyEntry(root, spanId) {
958
897
  return ledger.entries.find((entry) => entry && entry.spanId === spanId) || null;
959
898
  }
960
899
 
961
- // v6.14.1 — allow-list of non-delegation audit events the controller
962
- // can emit via the helper. Keep in sync with NON_DELEGATION_AUDIT_EVENTS
963
- // in src/delegation.ts.
900
+ // Allow-list of non-delegation audit events the controller can emit via
901
+ // the helper. Keep in sync with NON_DELEGATION_AUDIT_EVENTS in
902
+ // src/delegation.ts.
964
903
  const VALID_AUDIT_KINDS = new Set([
965
904
  "cclaw_integration_overseer_skipped"
966
905
  ]);
@@ -1258,8 +1197,8 @@ async function main() {
1258
1197
  return;
1259
1198
  }
1260
1199
 
1261
- // v6.14.1 — audit-only emit path. When the controller wants to record
1262
- // a non-delegation audit row (e.g. \`cclaw_integration_overseer_skipped\`
1200
+ // Audit-only emit path. When the controller wants to record a
1201
+ // non-delegation audit row (e.g. \`cclaw_integration_overseer_skipped\`
1263
1202
  // when the wave heuristic chose to skip the overseer dispatch), pass
1264
1203
  // --audit-kind=<event-name> [--audit-reason=<text>] [--slice-ids=<csv>]
1265
1204
  // and the helper appends a single line to delegation-events.jsonl
@@ -1287,11 +1226,11 @@ async function main() {
1287
1226
  return;
1288
1227
  }
1289
1228
 
1290
- // v6.11.0 (D2) — TDD slice phase tagging validation. --phase is
1291
- // strictly enum-bound; --slice must be a non-empty string when
1292
- // provided; --phase=refactor-deferred requires either an explicit
1293
- // --refactor-rationale or an --evidence-ref with rationale text so
1294
- // the linter has something to render.
1229
+ // TDD slice phase tagging validation. --phase is strictly enum-bound;
1230
+ // --slice must be a non-empty string when provided;
1231
+ // --phase=refactor-deferred requires either an explicit
1232
+ // --refactor-rationale or an --evidence-ref with rationale text so the
1233
+ // linter has something to render.
1295
1234
  if (args.phase !== undefined && !VALID_DELEGATION_PHASES_SET.has(args.phase)) {
1296
1235
  problems.push("invalid --phase (allowed: " + VALID_DELEGATION_PHASES.join(", ") + ")");
1297
1236
  emitProblems(problems, json, 2);
@@ -1317,10 +1256,10 @@ async function main() {
1317
1256
  }
1318
1257
  }
1319
1258
 
1320
- // v6.14.0 — --refactor-outcome must be one of inline|deferred. When
1321
- // mode=deferred a rationale is required (either --refactor-rationale or
1322
- // --evidence-ref carrying the rationale text). --risk-tier must be one of
1323
- // low|medium|high if provided.
1259
+ // --refactor-outcome must be one of inline|deferred. When mode=deferred
1260
+ // a rationale is required (either --refactor-rationale or --evidence-ref
1261
+ // carrying the rationale text). --risk-tier must be one of low|medium|high
1262
+ // if provided.
1324
1263
  if (
1325
1264
  args["refactor-outcome"] !== undefined &&
1326
1265
  args["refactor-outcome"] !== "inline" &&
@@ -1442,9 +1381,9 @@ async function main() {
1442
1381
  return;
1443
1382
  }
1444
1383
 
1445
- // v6.10.0 (P1+P2): file-overlap scheduler + fan-out cap. Run before
1446
- // the legacy dispatch dedup so disjoint claimedPaths can auto-promote
1447
- // to allowParallel and bypass the duplicate guard.
1384
+ // File-overlap scheduler + fan-out cap. Run before the dispatch
1385
+ // dedup so disjoint claimedPaths can auto-promote to allowParallel and
1386
+ // bypass the duplicate guard.
1448
1387
  if (status === "scheduled") {
1449
1388
  const sameRunPrior = priorLedger.filter((entry) => entry.runId === runId);
1450
1389
  const activeForRun = computeActiveSubagentsInline(sameRunPrior);
@@ -1494,8 +1433,8 @@ async function main() {
1494
1433
  }
1495
1434
  }
1496
1435
 
1497
- // v6.14.2 Fix 4 — GREEN evidence freshness contract for
1498
- // \`slice-implementer --phase green --status=completed\`. Three checks:
1436
+ // GREEN evidence freshness contract for \`slice-builder --phase green
1437
+ // --status=completed\`. Three checks:
1499
1438
  // 1. green_evidence_red_test_mismatch — evidenceRefs[0] must contain
1500
1439
  // the basename/stem of the RED span's first evidenceRef.
1501
1440
  // 2. green_evidence_passing_assertion_missing — evidenceRefs[0]
@@ -1508,7 +1447,7 @@ async function main() {
1508
1447
  // --green-mode=observational. Both flags are required.
1509
1448
  if (
1510
1449
  clean.stage === "tdd" &&
1511
- clean.agent === "slice-implementer" &&
1450
+ clean.agent === "slice-builder" &&
1512
1451
  clean.phase === "green" &&
1513
1452
  clean.status === "completed"
1514
1453
  ) {
@@ -1625,34 +1564,8 @@ async function main() {
1625
1564
  }
1626
1565
  }
1627
1566
 
1628
- if (
1629
- clean.stage === "tdd" &&
1630
- clean.agent === "slice-implementer" &&
1631
- clean.phase === "green" &&
1632
- (await readWorktreeExecutionModeInline(root)) === "worktree-first"
1633
- ) {
1634
- const tok = typeof clean.claimToken === "string" ? clean.claimToken.trim() : "";
1635
- const lane = typeof clean.ownerLaneId === "string" ? clean.ownerLaneId.trim() : "";
1636
- const lease = typeof clean.leasedUntil === "string" ? clean.leasedUntil.trim() : "";
1637
- if (tok.length === 0 || lane.length === 0 || lease.length === 0) {
1638
- const missing = [];
1639
- if (tok.length === 0) missing.push("--claim-token");
1640
- if (lane.length === 0) missing.push("--lane-id");
1641
- if (lease.length === 0) missing.push("--lease-until");
1642
- emitErrorJson(
1643
- "dispatch_lane_metadata_missing",
1644
- {
1645
- missing,
1646
- remediation:
1647
- "worktree-first mode requires --claim-token, --lane-id, and --lease-until on every slice-implementer --phase green delegation-record write (from scheduled through completed)."
1648
- },
1649
- json
1650
- );
1651
- return;
1652
- }
1653
- }
1654
-
1655
1567
  await persistEntry(root, runId, clean, event);
1568
+
1656
1569
  process.stdout.write(JSON.stringify({ ok: true, event }, null, 2) + "\\n");
1657
1570
  }
1658
1571
 
@@ -250,7 +250,7 @@ ${frameBullets}
250
250
  letters. Default = "Start /cc on the top recommendation". When the user
251
251
  picks the start option, plumb the chosen candidate forward via
252
252
  \`start-flow --from-idea-artifact=<path> --from-idea-candidate=I-<n>\`
253
- (Wave 23 / v5.0.0) so brainstorm reuses the idea's divergent + critique +
253
+ so brainstorm reuses the idea's divergent + critique +
254
254
  rank work via \`interactionHints.brainstorm.fromIdeaArtifact\`; do NOT
255
255
  ask brainstorm to regenerate it.
256
256
 
@@ -395,7 +395,7 @@ Required options, in this order:
395
395
  ### Phase 6 - Execute the choice
396
396
 
397
397
  - Start /cc: load \`${RUNTIME_ROOT}/skills/using-cclaw/SKILL.md\` and run
398
- \`/cc <phrase>\`. **Wave 23 (v5.0.0) handoff carry-forward (mandatory when starting from /cc-idea):**
398
+ \`/cc <phrase>\`. **Handoff carry-forward (mandatory when starting from /cc-idea):**
399
399
  the harness shim that turns \`/cc <phrase>\` into a \`start-flow\` invocation
400
400
  MUST forward the originating idea artifact and chosen candidate so brainstorm
401
401
  reuses divergent + critique + rank work instead of redoing it. Equivalent CLI
@@ -158,7 +158,7 @@ function hardGateReference(law) {
158
158
  .join(", ");
159
159
  }
160
160
  export function ironLawsSkillMarkdown() {
161
- // v6.9.0: Phase A purged the `PreToolUse` / `PostToolUse` / pre-tool
161
+ // Phase A purged the `PreToolUse` / `PostToolUse` / pre-tool
162
162
  // pipeline handlers, so `review-coverage-complete-before-ship` is no
163
163
  // longer hook-enforced — it now lives in the ship stage HARD-GATE.
164
164
  // Only `stop-clean-or-handoff` (Stop hook) is still hook-enforced;
@@ -544,7 +544,7 @@ async function handleSessionStart(runtime) {
544
544
  );
545
545
  const knowledge = await buildKnowledgeDigest(runtime.root, state.currentStage, knowledgeRaw);
546
546
 
547
- // Wave 21 honest-core: session-start no longer runs background helper
547
+ // honest-core: session-start no longer runs background helper
548
548
  // pipelines or digest caches. It rehydrates flow + knowledge only.
549
549
  const ralphLoopLine = "";
550
550
  const earlyLoopLine = "";
@@ -614,7 +614,7 @@ async function handleSessionStart(runtime) {
614
614
  if (metaContent.length > 0) {
615
615
  parts.push(metaContent);
616
616
  }
617
- // v6.9.0: load iron-laws content into the session-start digest so the
617
+ // load iron-laws content into the session-start digest so the
618
618
  // non-negotiable workflow constraints are visible from the first turn,
619
619
  // not lazily on tool dispatch.
620
620
  if (ironLawsContent.length > 0) {
@@ -47,7 +47,7 @@ These behaviors are the exact reason this skill exists. The linter will block yo
47
47
  - Use harness-native question tools first; prose fallback is allowed only when the tool is unavailable.
48
48
  - Keep a running Q&A trace in the active artifact under \`## Q&A Log\` in \`${RUNTIME_ROOT}/artifacts/\` as append-only rows.
49
49
  - **Early-loop ledger discipline**: Never append \`.cclaw/state/early-loop-log.jsonl\` rows whose \`iteration\` exceeds the active \`maxIterations\`. If the cap fired, escalate or accept convergence outcomes—do not bump the iteration counter afterward. \`deriveEarlyLoopStatus\` clamps persistence, but the log source should stay honest too.
50
- - **Convergence floor (a.k.a. "Q&A Ralph Loop" / "Elicitation Convergence")**: do NOT advance the stage (do NOT call \`stage-complete.mjs\`) until Q&A converges. The machine contract matches \`evaluateQaLogFloor\` in \`src/artifact-linter/shared.ts\` (rule \`qa_log_unconverged\`). Pass when ANY holds: (a) every forcing-question topic id is tagged \`[topic:<id>]\` on at least one \`## Q&A Log\` row; (b) the Q&A Ralph Loop detector fires (last 2 substantive rows are non-decision-changing: \`skip\`/\`continue\`/\`no-change\`/\`done\`/etc.) **and** the log has at least \`max(2, questionBudgetHint(discoveryMode, stage).min)\` substantive rows — **unless** \`discoveryMode\` is \`guided\` or \`deep\` with pending forcing-topic ids (then the Q&A Ralph Loop alone cannot pass until topics are tagged, a stop-signal is recorded, or \`--skip-questions\` downgrades the finding to advisory); (c) an explicit user stop-signal row; or (d) \`--skip-questions\` was persisted (unconverged is advisory only). Wave 24 (v6.0.0) made \`[topic:<id>]\` mandatory (no English keyword fallback). The "Q&A Ralph Loop" is the elicitation-stage convergence mechanism; the producer/critic Concern Ledger that drives early-stage iteration is the **Early-Loop**, persisted in \`.cclaw/state/early-loop-log.jsonl\` and \`early-loop.json\` — they are different machines, do not conflate them.
50
+ - **Convergence floor (a.k.a. "Q&A Ralph Loop" / "Elicitation Convergence")**: do NOT advance the stage (do NOT call \`stage-complete.mjs\`) until Q&A converges. The machine contract matches \`evaluateQaLogFloor\` in \`src/artifact-linter/shared.ts\` (rule \`qa_log_unconverged\`). Pass when ANY holds: (a) every forcing-question topic id is tagged \`[topic:<id>]\` on at least one \`## Q&A Log\` row; (b) the Q&A Ralph Loop detector fires (last 2 substantive rows are non-decision-changing: \`skip\`/\`continue\`/\`no-change\`/\`done\`/etc.) **and** the log has at least \`max(2, questionBudgetHint(discoveryMode, stage).min)\` substantive rows — **unless** \`discoveryMode\` is \`guided\` or \`deep\` with pending forcing-topic ids (then the Q&A Ralph Loop alone cannot pass until topics are tagged, a stop-signal is recorded, or \`--skip-questions\` downgrades the finding to advisory); (c) an explicit user stop-signal row; or (d) \`--skip-questions\` was persisted (unconverged is advisory only). made \`[topic:<id>]\` mandatory (no English keyword fallback). The "Q&A Ralph Loop" is the elicitation-stage convergence mechanism; the producer/critic Concern Ledger that drives early-stage iteration is the **Early-Loop**, persisted in \`.cclaw/state/early-loop-log.jsonl\` and \`early-loop.json\` — they are different machines, do not conflate them.
51
51
  - **NEVER run shell hash commands** (\`shasum\`, \`sha256sum\`, \`md5sum\`, \`Get-FileHash\`, \`certutil\`, etc.) to compute artifact hashes. If a linter ever asks you for a hash, that is a linter bug — report failure and stop, do not auto-fix in bash.
52
52
  - **NEVER paste cclaw command lines into chat** (e.g. \`node .cclaw/hooks/stage-complete.mjs ... --evidence-json '{...}'\`). Run them via the tool layer; report only the resulting summary. The user does not run cclaw manually and seeing the command line is noise.
53
53
 
@@ -121,7 +121,7 @@ Default mapping note: \`lean\` maps to a lightweight specialist tier on early st
121
121
 
122
122
  ### Topic tagging (MANDATORY for forcing-question rows)
123
123
 
124
- Each forcing question has a stable topic id (kebab-case ASCII, e.g. \`pain\`, \`direct-path\`, \`data-flow\`). Tag the matching Q&A Log row's \`Decision impact\` cell with \`[topic:<id>]\` so the linter can verify coverage in any natural language. This is a **HARD requirement** in Wave 24 (v6.0.0): the linter no longer keyword-matches English question prose, so an un-tagged row does NOT count toward coverage even if the answer fully addresses the topic.
124
+ Each forcing question has a stable topic id (kebab-case ASCII, e.g. \`pain\`, \`direct-path\`, \`data-flow\`). Tag the matching Q&A Log row's \`Decision impact\` cell with \`[topic:<id>]\` so the linter can verify coverage in any natural language. This is a **HARD requirement** in the linter no longer keyword-matches English question prose, so an un-tagged row does NOT count toward coverage even if the answer fully addresses the topic.
125
125
 
126
126
  RU example (after asking \`pain\` in Russian):
127
127
 
@@ -19,15 +19,13 @@ export declare const INVESTIGATION_DISCIPLINE_STAGES: ReadonlySet<FlowStage>;
19
19
  export declare function investigationDisciplineBlock(): string;
20
20
  export declare function behaviorAnchorBlock(stage: FlowStage): string;
21
21
  /**
22
- * v6.12.0 Phase Ritual + Phase W TDD-only top-of-skill sections that
23
- * sit immediately after the `<EXTREMELY-IMPORTANT>` Iron Law block and
24
- * before `## Quick Start`. They establish the per-slice three-dispatch
25
- * ritual + wave batch mode in imperative voice with literal commands so
26
- * pattern-matching on read works in our favor.
22
+ * TDD-only prelude after `<EXTREMELY-IMPORTANT>`: wave routing + canonical
23
+ * `slice-builder` dispatch. Uses literal commands so pattern-matching on read
24
+ * matches operator scripts.
27
25
  *
28
26
  * Empty for non-TDD stages.
29
27
  */
30
28
  export declare function tddTopOfSkillBlock(stage: FlowStage): string;
31
29
  export declare function stageSkillFolder(stage: FlowStage): string;
32
- export declare function stageSkillMarkdown(stage: FlowStage, track?: FlowTrack): string;
30
+ export declare function stageSkillMarkdown(stage: FlowStage, track?: FlowTrack, _packageVersion?: string | null): string;
33
31
  export declare function executingWavesSkillMarkdown(): string;
@@ -103,7 +103,7 @@ Any "the failure is real" claim (failing test, broken build, regression catch, d
103
103
 
104
104
  \`proof: <iso-ts> | <observed snippet — first 200 chars> | source: <command or log path>\`
105
105
 
106
- For TDD specifically, this is the watched-RED proof and is required per new test before \`stage-complete\` accepts the stage. From v6.12.0 onward, every slice on every TDD run dispatches three roles in this exact order: (1) \`test-author --slice S-<id> --phase red\`, (2) ONE message with TWO concurrent Task calls — \`slice-implementer --slice S-<id> --phase green --paths <production paths>\` AND \`slice-documenter --slice S-<id> --phase doc --paths <artifacts-dir>/tdd-slices/S-<id>.md\`, (3) \`slice-implementer --phase refactor\` or \`--phase refactor-deferred --refactor-rationale "<why>"\`. The linter auto-derives the \`Watched-RED Proof\` and \`Vertical Slice Cycle\` tables in \`06-tdd.md\` from \`.cclaw/state/delegation-events.jsonl\`. Do NOT hand-edit those tables. \`slice-implementer\` and \`slice-documenter\` are mandatory regardless of \`discoveryMode\` (v6.12.0 Phase R/M); the controller MUST NOT write GREEN production code or per-slice prose itself. v6.10.0 sidecar (\`06-tdd-slices.jsonl\`) is removed; \`cclaw-cli sync\` cleans the file from existing installs.
106
+ For TDD, watched-RED proof is mandatory before \`stage-complete\` accepts the slice. Dispatch \`slice-builder\` end-to-end: it owns RED/GREEN evidence rows, refactor coverage per the hook flags, \`<artifacts-dir>/tdd-slices/S-<id>.md\`, and (when wired) \`slice-completed\`. The linter mirrors phase history into auto-render markers in \`06-tdd.md\` never hand-fill those fragments.
107
107
  `;
108
108
  }
109
109
  /**
@@ -172,67 +172,28 @@ ${items.map((item) => `- ${item}`).join("\n")}
172
172
  `;
173
173
  }
174
174
  /**
175
- * v6.12.0 Phase Ritual + Phase W TDD-only top-of-skill sections that
176
- * sit immediately after the `<EXTREMELY-IMPORTANT>` Iron Law block and
177
- * before `## Quick Start`. They establish the per-slice three-dispatch
178
- * ritual + wave batch mode in imperative voice with literal commands so
179
- * pattern-matching on read works in our favor.
175
+ * TDD-only prelude after `<EXTREMELY-IMPORTANT>`: wave routing + canonical
176
+ * `slice-builder` dispatch. Uses literal commands so pattern-matching on read
177
+ * matches operator scripts.
180
178
  *
181
179
  * Empty for non-TDD stages.
182
180
  */
183
181
  export function tddTopOfSkillBlock(stage) {
184
182
  if (stage !== "tdd")
185
183
  return "";
186
- return `## Per-Slice Ritual (v6.12.0+)
184
+ return `## TDD orchestration primer
187
185
 
188
- ONE slice = THREE dispatches, in this order. Do not skip, do not collapse.
186
+ **Always first:** run \`node .cclaw/cli.mjs internal wave-status --json\` it reads the managed plan markers; open \`05-plan.md\`/wave-plan files afterward for detail.
189
187
 
190
- 1. **RED** \`Task("test-author --slice S-<id> --phase red")\`.
191
- 2. **Verify RED** — wait for the \`phase=red\` event in \`.cclaw/state/delegation-events.jsonl\` with non-empty \`evidenceRefs\`. No production edits.
192
- 3. **GREEN+DOC fan-out** — ONE message, TWO concurrent Tasks:
193
- \`\`\`
194
- Task("slice-implementer --slice S-<id> --phase green --paths <prod paths>")
195
- Task("slice-documenter --slice S-<id> --phase doc --paths <artifacts-dir>/tdd-slices/S-<id>.md")
196
- \`\`\`
197
- The file-overlap scheduler auto-allows parallel dispatch because \`claimedPaths\` are disjoint. Fire BOTH calls in the same message — never serialize independent work.
198
- 4. **REFACTOR** — \`Task("slice-implementer --slice S-<id> --phase refactor")\` OR \`--phase refactor-deferred --refactor-rationale '<why>'\`.
188
+ **Several ready lanes:** Issue exactly one AskQuestion (**launch parallel wave**, default vs **single slice**).
199
189
 
200
- **Rule 1 (v6.13.1):** Before any slice-routing question, read \`<artifacts-dir>/05-plan.md\` (managed \`## Parallel Execution Plan\`) **and** list \`<artifacts-dir>/wave-plans/wave-NN.md\`. Merge mentally: Parallel Execution Plan first, wave files second; duplicate slices with conflicting wave membership are invalid. If the merged plan shows a wave with **two or more** scheduler-ready slices, issue **exactly one** \`AskQuestion\`: \`Launch wave W-NN with N parallel lanes (S-a, S-b, ...)?\` with default option **launch wave** and alternate **single-slice instead**. Do not ask "which slice next?" when that question is redundant (single ready slice or no wave). After **launch wave** confirmation, execute RED checkpoint → parallel GREEN+DOC → per-lane REFACTOR without further routing asks. After **single-slice instead**, fall back to the legacy single-slice ritual. **Wave dispatch resume:** if part of the wave is already done, parallelize only the remaining members.
190
+ **Delegation order:** Emit \`delegation-record\` \`--status=scheduled\` then \`--status=launched\` *before* every \`Task\`; workers ACK/complete locally.
201
191
 
202
- **FORBIDDEN:**
203
- - Controller writing GREEN production code. ALL GREEN goes through \`slice-implementer\` — linter rule \`tdd_slice_implementer_missing\` blocks the gate.
204
- - Controller writing per-slice prose into legacy \`06-tdd.md\` sections (Test Discovery / RED Evidence / GREEN Evidence / Watched-RED Proof / Vertical Slice Cycle / Per-Slice Review / Failure Analysis / Acceptance Mapping). \`slice-documenter\` owns \`tdd-slices/S-<id>.md\` — \`tdd_slice_documenter_missing\` blocks the gate.
205
- - Hand-editing auto-render blocks between \`auto-start: tdd-slice-summary\` / \`auto-start: slices-index\` markers — overwritten every lint.
192
+ **Per slice worker:** Prefer \`Task("slice-builder --slice S-<id> ...")\`. Pass explicit \`--paths\`; parallel Tasks are okay when overlaps are disjoint. Follow any lane lease flags the helper still mandates on your ledger.
206
193
 
207
- Delegation-record signature (extend with lane metadata for every GREEN row in \`worktree-first\`):
208
-
209
- \`node .cclaw/hooks/delegation-record.mjs --stage=tdd --agent=slice-implementer --mode=mandatory --status=scheduled --span-id=<id> --dispatch-id=<id> --dispatch-surface=<surface> --agent-definition-path=<path> --slice=S-1 --phase=green --paths=src/a.ts --claim-token=<opaque> --lane-id=<lane> --lease-until=<iso8601> --json\`
210
-
211
- ## Wave Batch Mode (v6.13.1+)
212
-
213
- **Triggers:** managed \`## Parallel Execution Plan\` in \`05-plan.md\` **or** any \`<artifacts-dir>/wave-plans/wave-NN.md\`, OR 2+ slices with disjoint \`claimedPaths\`. Cap = 5 \`slice-implementer\` lanes (10 subagents incl. paired documenters) via \`MAX_PARALLEL_SLICE_IMPLEMENTERS\`. **Preconditions:** Load both sources before routing. Worktree-first: every GREEN delegation-record MUST include \`--claim-token\`, \`--lane-id\`, \`--lease-until\` (hook exits \`2\`, \`dispatch_lane_metadata_missing\` otherwise).
214
-
215
- **Phase A — RED checkpoint** — ONE message, all test-authors:
216
- \`\`\`
217
- Task("test-author --slice S-1 --phase red")
218
- Task("test-author --slice S-2 --phase red")
219
- Task("test-author --slice S-3 --phase red")
220
- \`\`\`
221
- Wait for ALL Phase A REDs to land with non-empty \`evidenceRefs\` before Phase B. Linter \`tdd_red_checkpoint_violation\` (required: true) blocks any wave where a \`phase=green\` \`completedTs\` precedes the wave's last \`phase=red\` \`completedTs\`.
222
-
223
- **Phase B — GREEN+DOC fan-out** — ONE message; pair per slice (repeat for each lane, flags unique per lane):
224
-
225
- \`\`\`
226
- Task("slice-implementer --slice S-1 --phase green --paths <prod> --claim-token=<t> --lane-id=<lane-1> --lease-until=<iso>")
227
- Task("slice-documenter --slice S-1 --phase doc --paths <artifacts-dir>/tdd-slices/S-1.md")
228
- \`\`\`
229
-
230
- Launch every slice's pair in that same message. **Never serialize independent work.**
231
-
232
- **Phase C — REFACTOR per slice** — after GREEN+DOC lands, dispatch refactor/refactor-deferred per slice. **Fan-in (worktree-first):** echo claim/lane/lease on completed GREEN rows; stage-complete runs deterministic \`git apply --3way\` (no \`-X ours/theirs\`). Conflicts: \`slice-implementer --phase resolve-conflict\`. With 2+ lanes, still dispatch \`integration-overseer\` before review.
233
-
234
- **slice-documenter:** record the \`phase=doc\` row in the same message as GREEN; write a **provisional** row in \`tdd-slices/S-<id>.md\` immediately at dispatch, then **finalize** that file after the matching \`slice-implementer\` \`phase=green\` event lands (evidence-backed prose, not guesswork before GREEN exists).
194
+ Wave resume: reuse \`wave-status\` outputs and parallelize unfinished members instead of restarting finished slices.
235
195
 
196
+ ---
236
197
  `;
237
198
  }
238
199
  function artifactTemplatePathForStage(stage) {
@@ -469,7 +430,7 @@ function mergedAntiPatterns(philosophy, execution) {
469
430
  }
470
431
  function completionParametersBlock(schema, track) {
471
432
  const gateList = schema.executionModel.requiredGates.map((g) => `\`${g.id}\``).join(", ");
472
- // Wave 24 (v6.0.0): mandatory agents are dropped on `quick` track. Surface
433
+ // Mandatory agents are dropped on `quick` track. Surface
473
434
  // the empty list so the rendered SKILL.md doesn't tell quick-track runs to
474
435
  // dispatch agents the linter is going to skip.
475
436
  const trackAwareMandatoryAgents = track === "quick" ? [] : schema.reviewLens.mandatoryDelegations;
@@ -477,7 +438,7 @@ function completionParametersBlock(schema, track) {
477
438
  const mandatory = trackAwareMandatoryAgents.length > 0
478
439
  ? trackAwareMandatoryAgents.map((a) => `\`${a}\``).join(", ")
479
440
  : track === "quick" && schema.reviewLens.mandatoryDelegations.length > 0
480
- ? "none (skipped: quick track — Wave 24)"
441
+ ? "none (skipped: quick track)"
481
442
  : "none";
482
443
  const resolvedNextStage = nextStageForTrack(schema.stage, track);
483
444
  const nextStage = resolvedNextStage ?? "done";
@@ -619,7 +580,7 @@ function dedupeGuidance(items, blockedBy) {
619
580
  }
620
581
  return result;
621
582
  }
622
- export function stageSkillMarkdown(stage, track = "standard") {
583
+ export function stageSkillMarkdown(stage, track = "standard", _packageVersion) {
623
584
  const schema = stageSchema(stage, track);
624
585
  const trackContext = stageTrackRenderContext(track);
625
586
  const philosophy = schema.philosophy;
@@ -56,7 +56,7 @@ export declare function parseSkillEnvelope(raw: string): SkillEnvelope | null;
56
56
  /** Transition guard: agents with `mode: "mandatory"` in auto-subagent dispatch for this stage. */
57
57
  export declare function mandatoryDelegationsForStage(stage: FlowStage, complexityTier?: StageComplexityTier): string[];
58
58
  /**
59
- * Wave 24 (v6.0.0) — track-aware mandatory delegation lookup.
59
+ * Track-aware mandatory delegation lookup.
60
60
  *
61
61
  * Returns `[]` (skip the gate entirely) when the run is on a small-fix
62
62
  * track or classified as a software bugfix:
@@ -85,7 +85,7 @@ export declare function mandatoryDelegationsForStage(stage: FlowStage, complexit
85
85
  export type MandatoryDelegationTaskClass = "software-standard" | "software-trivial" | "software-bugfix";
86
86
  export declare function mandatoryAgentsFor(stage: FlowStage, track: FlowTrack, taskClass?: MandatoryDelegationTaskClass | null, complexityTier?: StageComplexityTier, discoveryMode?: DiscoveryMode): string[];
87
87
  /**
88
- * Wave 25 (v6.1.0) — track-aware artifact validation demotion.
88
+ * Track-aware artifact validation demotion.
89
89
  *
90
90
  * Mirrors `mandatoryAgentsFor`'s skip logic for the small-fix lanes.
91
91
  * Returns `true` when artifact-level "advanced" validation rules
@@ -96,7 +96,7 @@ export declare function mandatoryAgentsFor(stage: FlowStage, track: FlowTrack, t
96
96
  * - `track === "quick"` — quick-tier runs (single-purpose
97
97
  * landing-page edits, doc tweaks, config nudges). The advanced
98
98
  * checks fire on architecture surfaces a quick-track artifact
99
- * usually doesn't have. Same trigger as Wave 24 Phase B.
99
+ * usually doesn't have.
100
100
  * - `taskClass === "software-bugfix"` — bugfixes carry RED-first
101
101
  * repro coverage; tdd/review own the safety surface.
102
102
  *