cclaw-cli 6.14.3 → 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.
- package/README.md +0 -2
- package/dist/artifact-linter/brainstorm.js +1 -1
- package/dist/artifact-linter/design.js +2 -2
- package/dist/artifact-linter/findings-dedup.js +1 -1
- package/dist/artifact-linter/plan.js +6 -6
- package/dist/artifact-linter/review-army.d.ts +1 -1
- package/dist/artifact-linter/review-army.js +1 -1
- package/dist/artifact-linter/scope.js +6 -6
- package/dist/artifact-linter/shared.d.ts +37 -73
- package/dist/artifact-linter/shared.js +30 -37
- package/dist/artifact-linter/spec.js +1 -1
- package/dist/artifact-linter/tdd.d.ts +20 -33
- package/dist/artifact-linter/tdd.js +89 -617
- package/dist/artifact-linter.js +11 -32
- package/dist/cli.js +1 -1
- package/dist/config.js +1 -1
- package/dist/constants.js +1 -1
- package/dist/content/core-agents.d.ts +8 -26
- package/dist/content/core-agents.js +48 -94
- package/dist/content/examples.d.ts +1 -1
- package/dist/content/examples.js +4 -4
- package/dist/content/hooks.js +62 -149
- package/dist/content/idea.js +2 -2
- package/dist/content/iron-laws.js +1 -1
- package/dist/content/node-hooks.js +2 -2
- package/dist/content/skills-elicitation.js +2 -2
- package/dist/content/skills.d.ts +4 -6
- package/dist/content/skills.js +14 -53
- package/dist/content/stage-schema.d.ts +3 -3
- package/dist/content/stage-schema.js +8 -46
- package/dist/content/stages/brainstorm.js +5 -5
- package/dist/content/stages/plan.js +2 -2
- package/dist/content/stages/review.js +1 -1
- package/dist/content/stages/schema-types.d.ts +1 -1
- package/dist/content/stages/scope.js +1 -1
- package/dist/content/stages/spec.js +2 -2
- package/dist/content/stages/tdd.js +43 -108
- package/dist/content/start-command.js +3 -3
- package/dist/content/subagent-context-skills.js +5 -3
- package/dist/content/subagents.js +13 -74
- package/dist/content/templates.d.ts +6 -6
- package/dist/content/templates.js +23 -24
- package/dist/content/utility-skills.d.ts +1 -1
- package/dist/content/utility-skills.js +1 -1
- package/dist/delegation.d.ts +79 -139
- package/dist/delegation.js +83 -215
- package/dist/early-loop.js +1 -1
- package/dist/flow-state.d.ts +24 -129
- package/dist/flow-state.js +5 -30
- package/dist/gate-evidence.d.ts +2 -7
- package/dist/gate-evidence.js +2 -59
- package/dist/harness-adapters.d.ts +1 -1
- package/dist/harness-adapters.js +11 -10
- package/dist/install.js +24 -459
- package/dist/internal/advance-stage/advance.d.ts +5 -5
- package/dist/internal/advance-stage/advance.js +9 -24
- package/dist/internal/advance-stage/parsers.d.ts +1 -1
- package/dist/internal/advance-stage/review-loop.d.ts +1 -1
- package/dist/internal/advance-stage/review-loop.js +3 -3
- package/dist/internal/advance-stage/start-flow.js +1 -3
- package/dist/internal/advance-stage.js +4 -23
- package/dist/internal/cohesion-contract-stub.d.ts +8 -13
- package/dist/internal/cohesion-contract-stub.js +18 -24
- package/dist/internal/flow-state-repair.d.ts +1 -1
- package/dist/internal/plan-split-waves.d.ts +44 -7
- package/dist/internal/plan-split-waves.js +113 -12
- package/dist/internal/wave-status.d.ts +3 -6
- package/dist/internal/wave-status.js +5 -27
- package/dist/policy.js +1 -1
- package/dist/run-persistence.js +10 -44
- package/dist/runtime/run-hook.mjs +3 -3
- package/dist/track-heuristics.js +1 -1
- package/dist/types.d.ts +2 -2
- package/package.json +1 -1
- package/dist/integration-fanin.d.ts +0 -44
- package/dist/integration-fanin.js +0 -180
- package/dist/internal/set-checkpoint-mode.d.ts +0 -16
- package/dist/internal/set-checkpoint-mode.js +0 -72
- package/dist/internal/set-integration-overseer-mode.d.ts +0 -14
- package/dist/internal/set-integration-overseer-mode.js +0 -69
- package/dist/internal/set-worktree-mode.d.ts +0 -10
- package/dist/internal/set-worktree-mode.js +0 -28
- package/dist/worktree-manager.d.ts +0 -50
- package/dist/worktree-manager.js +0 -136
- package/dist/worktree-types.d.ts +0 -36
- package/dist/worktree-types.js +0 -6
package/dist/content/hooks.js
CHANGED
|
@@ -294,22 +294,9 @@ async function readRunId(root) {
|
|
|
294
294
|
}
|
|
295
295
|
}
|
|
296
296
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
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
|
-
//
|
|
327
|
-
//
|
|
328
|
-
//
|
|
329
|
-
//
|
|
330
|
-
//
|
|
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"
|
|
355
|
-
//
|
|
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] #
|
|
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
|
|
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
|
|
419
|
-
" --paths=<a,b,c> repo-relative paths the slice-
|
|
420
|
-
" --override-cap=<int> raise the slice
|
|
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
|
|
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
|
|
426
|
-
" --
|
|
427
|
-
" --
|
|
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
|
-
//
|
|
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
|
-
//
|
|
542
|
-
//
|
|
543
|
-
//
|
|
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
|
-
//
|
|
553
|
-
//
|
|
554
|
-
//
|
|
555
|
-
//
|
|
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
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
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
|
|
694
|
-
//
|
|
695
|
-
//
|
|
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-
|
|
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
|
|
709
|
+
const MAX_PARALLEL_SLICE_BUILDERS_INLINE = 5;
|
|
771
710
|
|
|
772
711
|
function readMaxParallelOverrideFromEnvInline() {
|
|
773
|
-
const raw = process.env.
|
|
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-
|
|
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() ||
|
|
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
|
-
//
|
|
962
|
-
//
|
|
963
|
-
//
|
|
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
|
-
//
|
|
1262
|
-
//
|
|
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
|
-
//
|
|
1291
|
-
//
|
|
1292
|
-
//
|
|
1293
|
-
// --refactor-rationale or an --evidence-ref with rationale text so
|
|
1294
|
-
//
|
|
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
|
-
//
|
|
1321
|
-
//
|
|
1322
|
-
//
|
|
1323
|
-
//
|
|
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
|
-
//
|
|
1446
|
-
//
|
|
1447
|
-
//
|
|
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
|
-
//
|
|
1498
|
-
//
|
|
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-
|
|
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
|
|
package/dist/content/idea.js
CHANGED
|
@@ -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
|
-
|
|
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>\`. **
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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).
|
|
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
|
|
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
|
|
package/dist/content/skills.d.ts
CHANGED
|
@@ -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
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
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;
|
package/dist/content/skills.js
CHANGED
|
@@ -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
|
|
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
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
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 `##
|
|
184
|
+
return `## TDD orchestration primer
|
|
187
185
|
|
|
188
|
-
|
|
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
|
-
|
|
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
|
-
**
|
|
190
|
+
**Delegation order:** Emit \`delegation-record\` \`--status=scheduled\` then \`--status=launched\` *before* every \`Task\`; workers ACK/complete locally.
|
|
201
191
|
|
|
202
|
-
**
|
|
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
|
-
|
|
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
|
-
//
|
|
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
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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.
|
|
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
|
*
|