cclaw-cli 5.0.0 → 6.1.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.
@@ -4,6 +4,8 @@ import { exists } from "./fs-utils.js";
4
4
  import { stageSchema } from "./content/stage-schema.js";
5
5
  import { readFlowState } from "./run-persistence.js";
6
6
  import { duplicateH2Headings, extractH2Sections, extractRequirementIdsFromMarkdown, isShortCircuitActivated, normalizeHeadingTitle, parseFrontmatter, parseLearningsSection, sectionBodyByAnyName, sectionBodyByHeadingPrefix, sectionBodyByName, validateSectionBody } from "./artifact-linter/shared.js";
7
+ import { shouldDemoteArtifactValidationByTrack } from "./content/stage-schema.js";
8
+ import { recordArtifactValidationDemotedByTrack } from "./delegation.js";
7
9
  import { lintBrainstormStage } from "./artifact-linter/brainstorm.js";
8
10
  import { lintDesignStage } from "./artifact-linter/design.js";
9
11
  import { lintPlanStage } from "./artifact-linter/plan.js";
@@ -105,6 +107,34 @@ export async function lintArtifact(projectRoot, stage, track = "standard", optio
105
107
  const overrideSet = isTrivialOverride
106
108
  ? new Set(schema.trivialOverrideSections.map((s) => normalizeHeadingTitle(s).toLowerCase()))
107
109
  : null;
110
+ // Wave 25: precompute the lite-tier signal so the per-section
111
+ // validators (Interaction Edge Case matrix today, others tomorrow)
112
+ // can relax network-dependent mandatory rows for lite/quick/bugfix
113
+ // runs without each validator having to re-derive the predicate.
114
+ // Same flow-state read powers the post-loop demotion + audit log
115
+ // below; we cache the result here to avoid two disk reads.
116
+ let activeStageFlags = [];
117
+ let taskClass = null;
118
+ let activeRunId = null;
119
+ try {
120
+ const flowState = await readFlowState(projectRoot);
121
+ const hint = flowState.interactionHints?.[stage];
122
+ if (hint?.skipQuestions === true)
123
+ activeStageFlags.push("--skip-questions");
124
+ taskClass = flowState.taskClass ?? null;
125
+ activeRunId = flowState.activeRunId ?? null;
126
+ }
127
+ catch {
128
+ activeStageFlags = [];
129
+ taskClass = null;
130
+ activeRunId = null;
131
+ }
132
+ for (const extra of options.extraStageFlags ?? []) {
133
+ if (typeof extra === "string" && extra.length > 0 && !activeStageFlags.includes(extra)) {
134
+ activeStageFlags.push(extra);
135
+ }
136
+ }
137
+ const liteTierForValidators = shouldDemoteArtifactValidationByTrack(track, taskClass);
108
138
  for (const v of schema.artifactValidation) {
109
139
  const sectionKey = normalizeHeadingTitle(v.section).toLowerCase();
110
140
  const scopeBoundaryAlias = stage === "scope" && sectionKey === "in scope / out of scope";
@@ -122,7 +152,10 @@ export async function lintArtifact(projectRoot, stage, track = "standard", optio
122
152
  : effectiveRequiredFromOverride;
123
153
  const validation = body === null
124
154
  ? { ok: false, details: `No ## heading matching required section "${v.section}".` }
125
- : validateSectionBody(body, v.validationRule, v.section);
155
+ : validateSectionBody(body, v.validationRule, v.section, {
156
+ sections,
157
+ liteTier: liteTierForValidators
158
+ });
126
159
  const found = hasHeading && validation.ok;
127
160
  findings.push({
128
161
  section: v.section,
@@ -158,21 +191,6 @@ export async function lintArtifact(projectRoot, stage, track = "standard", optio
158
191
  details: `${learnings.details}${meaningfulStageNoneWarning}`
159
192
  });
160
193
  }
161
- let activeStageFlags = [];
162
- try {
163
- const flowState = await readFlowState(projectRoot);
164
- const hint = flowState.interactionHints?.[stage];
165
- if (hint?.skipQuestions === true)
166
- activeStageFlags.push("--skip-questions");
167
- }
168
- catch {
169
- activeStageFlags = [];
170
- }
171
- for (const extra of options.extraStageFlags ?? []) {
172
- if (typeof extra === "string" && extra.length > 0 && !activeStageFlags.includes(extra)) {
173
- activeStageFlags.push(extra);
174
- }
175
- }
176
194
  const stageContext = {
177
195
  projectRoot,
178
196
  stage,
@@ -188,7 +206,8 @@ export async function lintArtifact(projectRoot, stage, track = "standard", optio
188
206
  staleDiagramAuditEnabled,
189
207
  isTrivialOverride,
190
208
  overrideSet,
191
- activeStageFlags
209
+ activeStageFlags,
210
+ taskClass
192
211
  };
193
212
  switch (stage) {
194
213
  case "brainstorm":
@@ -257,6 +276,53 @@ export async function lintArtifact(projectRoot, stage, track = "standard", optio
257
276
  });
258
277
  }
259
278
  }
279
+ const demote = shouldDemoteArtifactValidationByTrack(track, taskClass);
280
+ const demotedSections = [];
281
+ if (demote) {
282
+ for (const finding of findings) {
283
+ if (!ARTIFACT_VALIDATION_LITE_DEMOTE_SECTIONS.has(finding.section))
284
+ continue;
285
+ if (finding.found)
286
+ continue;
287
+ if (!finding.required)
288
+ continue;
289
+ finding.required = false;
290
+ finding.details =
291
+ `${finding.details} (Wave 25: demoted to advisory by track="${track}"` +
292
+ (taskClass ? `, taskClass="${taskClass}"` : "") +
293
+ ").";
294
+ demotedSections.push(finding.section);
295
+ }
296
+ if (demotedSections.length > 0 && activeRunId) {
297
+ await recordArtifactValidationDemotedByTrack(projectRoot, {
298
+ stage,
299
+ track,
300
+ taskClass: taskClass ?? null,
301
+ runId: activeRunId,
302
+ sections: demotedSections
303
+ }).catch(() => { });
304
+ }
305
+ }
260
306
  const passed = findings.every((f) => !f.required || f.found);
261
307
  return { stage, file: relFile, passed, findings };
262
308
  }
309
+ /**
310
+ * Wave 25 (v6.1.0) — section names whose required-finding outcome is
311
+ * demoted from blocking → advisory when
312
+ * `shouldDemoteArtifactValidationByTrack(track, taskClass)` returns
313
+ * `true`. Mirrors the user-reported quick-tier failure modes:
314
+ *
315
+ * - `Architecture Diagram` — sync/async + failure-edge enforcement
316
+ * - `Data Flow` — Interaction Edge Case mandatory rows
317
+ * - `Stale Diagram Drift Check` — blast-radius file mtime audit
318
+ * - `Expansion Strategist Delegation` — product-discovery delegation
319
+ *
320
+ * Findings remain in the result so the caller can surface them as
321
+ * advisory hints; only `required` flips to `false`.
322
+ */
323
+ const ARTIFACT_VALIDATION_LITE_DEMOTE_SECTIONS = new Set([
324
+ "Architecture Diagram",
325
+ "Data Flow",
326
+ "Stale Diagram Drift Check",
327
+ "Expansion Strategist Delegation"
328
+ ]);
@@ -47,7 +47,7 @@ These behaviors are the exact reason this skill exists. The linter will block yo
47
47
  - Ask exactly one question per turn and wait for the answer before asking the next one.
48
48
  - Use harness-native question tools first; prose fallback is allowed only when the tool is unavailable.
49
49
  - Keep a running Q&A trace in the active artifact under \`## Q&A Log\` in \`${RUNTIME_ROOT}/artifacts/\` as append-only rows.
50
- - **Convergence floor**: do NOT advance the stage (do NOT call \`stage-complete.mjs\`) until Q&A converges. Convergence is reached when ANY of: (a) all forcing-question topics are addressed in \`## Q&A Log\`, (b) the last 2 substantive rows produce no decision-changing impact (\`skip\`/\`continue\`/\`no-change\`/\`done\`), or (c) an explicit user stop-signal row is recorded. The linter rule \`qa_log_unconverged\` enforces this; \`stage-complete\` will fail otherwise. Wave 23 (v5.0.0) replaced the fixed-count floor with this convergence detector.
50
+ - **Convergence floor**: do NOT advance the stage (do NOT call \`stage-complete.mjs\`) until Q&A converges. Convergence is reached when ANY of: (a) every forcing-question topic id is tagged \`[topic:<id>]\` on at least one \`## Q&A Log\` row, (b) the last 2 substantive rows produce no decision-changing impact (\`skip\`/\`continue\`/\`no-change\`/\`done\`), or (c) an explicit user stop-signal row is recorded. The linter rule \`qa_log_unconverged\` enforces this; \`stage-complete\` will fail otherwise. Wave 24 (v6.0.0) made the topic tag MANDATORY (no English keyword fallback) so the gate works in any natural language.
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
 
@@ -127,24 +127,38 @@ How to use the columns:
127
127
  - \`skipped (already covered: turn N)\` — answered implicitly by an earlier reply; cite the turn.
128
128
  - \`waived (user override)\` — user explicitly waived this question.
129
129
 
130
- Stage forcing question lists:
130
+ ### Topic tagging (MANDATORY for forcing-question rows)
131
+
132
+ Each forcing question has a stable topic id (kebab-case ASCII, e.g. \`pain\`, \`do-nothing\`, \`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.
133
+
134
+ RU example (after asking \`pain\` in Russian):
135
+
136
+ \`\`\`
137
+ | Turn | Question | User answer (1-line) | Decision impact |
138
+ |---|---|---|---|
139
+ | 1 | Какую боль мы решаем? | Регистрация занимает 30 минут. | scope-shaping [topic:pain] |
140
+ \`\`\`
141
+
142
+ Multiple tags in one row are allowed when one answer covers several topics: \`[topic:pain] [topic:do-nothing]\`. Stop-signal rows do NOT need a tag.
143
+
144
+ Stage forcing question lists (id → topic):
131
145
 
132
146
  - **Brainstorm**:
133
- - What pain are we solving?
134
- - What is the most direct path?
135
- - What happens if we do nothing?
136
- - Who is the operator/user impacted first?
137
- - What are non-negotiable no-go boundaries?
147
+ - \`pain\` — What pain are we solving?
148
+ - \`direct-path\` — What is the most direct path?
149
+ - \`do-nothing\` — What happens if we do nothing?
150
+ - \`operator\` — Who is the operator/user impacted first?
151
+ - \`no-go\` — What are non-negotiable no-go boundaries?
138
152
  - **Scope**:
139
- - What is definitely in and definitely out?
140
- - Which decisions are already locked upstream?
141
- - What is the rollback path if this fails?
142
- - What are the top failure modes we must design for?
153
+ - \`in-out\` — What is definitely in and definitely out?
154
+ - \`locked-upstream\` — Which decisions are already locked upstream?
155
+ - \`rollback\` — What is the rollback path if this fails?
156
+ - \`failure-modes\` — What are the top failure modes we must design for?
143
157
  - **Design**:
144
- - What is the data flow end-to-end?
145
- - Where are the seams/interfaces and ownership boundaries?
146
- - Which invariants must always hold?
147
- - What will we explicitly NOT refactor now?
158
+ - \`data-flow\` — What is the data flow end-to-end?
159
+ - \`seams\` — Where are the seams/interfaces and ownership boundaries?
160
+ - \`invariants\` — Which invariants must always hold?
161
+ - \`not-refactor\` — What will we explicitly NOT refactor now?
148
162
 
149
163
  ## One-Way Override (Irreversible Decisions)
150
164
 
@@ -360,10 +360,16 @@ function mergedAntiPatterns(philosophy, execution) {
360
360
  }
361
361
  function completionParametersBlock(schema, track) {
362
362
  const gateList = schema.executionModel.requiredGates.map((g) => `\`${g.id}\``).join(", ");
363
- const mandatoryAgents = schema.reviewLens.mandatoryDelegations;
364
- const mandatory = schema.reviewLens.mandatoryDelegations.length > 0
365
- ? schema.reviewLens.mandatoryDelegations.map((a) => `\`${a}\``).join(", ")
366
- : "none";
363
+ // Wave 24 (v6.0.0): mandatory agents are dropped on `quick` track. Surface
364
+ // the empty list so the rendered SKILL.md doesn't tell quick-track runs to
365
+ // dispatch agents the linter is going to skip.
366
+ const trackAwareMandatoryAgents = track === "quick" ? [] : schema.reviewLens.mandatoryDelegations;
367
+ const mandatoryAgents = trackAwareMandatoryAgents;
368
+ const mandatory = trackAwareMandatoryAgents.length > 0
369
+ ? trackAwareMandatoryAgents.map((a) => `\`${a}\``).join(", ")
370
+ : track === "quick" && schema.reviewLens.mandatoryDelegations.length > 0
371
+ ? "none (skipped: quick track — Wave 24)"
372
+ : "none";
367
373
  const resolvedNextStage = nextStageForTrack(schema.stage, track);
368
374
  const nextStage = resolvedNextStage ?? "done";
369
375
  const nextDescription = nextStage === "done"
@@ -55,6 +55,58 @@ export declare function validateSkillEnvelope(value: unknown): SkillEnvelopeVali
55
55
  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
+ /**
59
+ * Wave 24 (v6.0.0) — track-aware mandatory delegation lookup.
60
+ *
61
+ * Returns `[]` (skip the gate entirely) when the run is on a small-fix
62
+ * track or classified as a software bugfix:
63
+ *
64
+ * - `track === "quick"` — the quick track is for trivial single-purpose
65
+ * fixes (landing-page copy, doc edits, config tweaks). Mandatory
66
+ * subagent dispatch is theatre on that surface area.
67
+ * - `taskClass === "software-bugfix"` — bugfixes carry a RED-first
68
+ * repro contract; the test author + reviewer in the tdd/review
69
+ * stages already cover the safety surface, so mandatory upstream
70
+ * delegation only burns tokens.
71
+ *
72
+ * Otherwise returns the registered mandatory list for the stage at the
73
+ * given tier. Callers (gate-evidence, advance-stage validator,
74
+ * subagents.ts table generator) MUST go through this helper instead of
75
+ * `mandatoryDelegationsForStage` so the track-aware drop applies
76
+ * uniformly.
77
+ *
78
+ * NOTE: the user query also calls this `lite/quick`. There is no `lite`
79
+ * FlowTrack — the closest concept in cclaw is the `quick` track plus the
80
+ * brainstorm `lightweight` complexity tier. We key on the FlowTrack
81
+ * because the run-level decision is what matters at gate time;
82
+ * complexity tier is a per-stage knob that doesn't survive the dispatch
83
+ * boundary.
84
+ */
85
+ export type MandatoryDelegationTaskClass = "software-standard" | "software-trivial" | "software-bugfix";
86
+ export declare function mandatoryAgentsFor(stage: FlowStage, track: FlowTrack, taskClass?: MandatoryDelegationTaskClass | null, complexityTier?: StageComplexityTier): string[];
87
+ /**
88
+ * Wave 25 (v6.1.0) — track-aware artifact validation demotion.
89
+ *
90
+ * Mirrors `mandatoryAgentsFor`'s skip logic for the small-fix lanes.
91
+ * Returns `true` when artifact-level "advanced" validation rules
92
+ * (architecture-diagram async/failure edges, interaction edge-case
93
+ * mandatory rows, stale-diagram drift check, expansion-strategist
94
+ * delegation) should be DEMOTED from required → advisory.
95
+ *
96
+ * - `track === "quick"` — quick-tier runs (single-purpose
97
+ * landing-page edits, doc tweaks, config nudges). The advanced
98
+ * checks fire on architecture surfaces a quick-track artifact
99
+ * usually doesn't have. Same trigger as Wave 24 Phase B.
100
+ * - `taskClass === "software-bugfix"` — bugfixes carry RED-first
101
+ * repro coverage; tdd/review own the safety surface.
102
+ *
103
+ * When this returns `true`, the linter still runs the rules and prints
104
+ * their findings (so authors see them as advisory info), but does NOT
105
+ * block stage advance. An audit event of type
106
+ * `artifact_validation_demoted_by_track` is appended to
107
+ * `delegation-events.jsonl` once per stage advance for traceability.
108
+ */
109
+ export declare function shouldDemoteArtifactValidationByTrack(track: FlowTrack, taskClass?: MandatoryDelegationTaskClass | null): boolean;
58
110
  export declare function stageSchema(stage: FlowStage, track?: FlowTrack): StageSchema;
59
111
  export declare function orderedStageSchemas(track?: FlowTrack): StageSchema[];
60
112
  export declare function stageGateIds(stage: FlowStage, track?: FlowTrack): string[];
@@ -811,6 +811,42 @@ export function mandatoryDelegationsForStage(stage, complexityTier = "standard")
811
811
  .find((row) => row.stage === stage);
812
812
  return summary ? summary.mandatoryAgents : [];
813
813
  }
814
+ export function mandatoryAgentsFor(stage, track, taskClass, complexityTier = "standard") {
815
+ if (track === "quick")
816
+ return [];
817
+ if (taskClass === "software-bugfix")
818
+ return [];
819
+ return mandatoryDelegationsForStage(stage, complexityTier);
820
+ }
821
+ /**
822
+ * Wave 25 (v6.1.0) — track-aware artifact validation demotion.
823
+ *
824
+ * Mirrors `mandatoryAgentsFor`'s skip logic for the small-fix lanes.
825
+ * Returns `true` when artifact-level "advanced" validation rules
826
+ * (architecture-diagram async/failure edges, interaction edge-case
827
+ * mandatory rows, stale-diagram drift check, expansion-strategist
828
+ * delegation) should be DEMOTED from required → advisory.
829
+ *
830
+ * - `track === "quick"` — quick-tier runs (single-purpose
831
+ * landing-page edits, doc tweaks, config nudges). The advanced
832
+ * checks fire on architecture surfaces a quick-track artifact
833
+ * usually doesn't have. Same trigger as Wave 24 Phase B.
834
+ * - `taskClass === "software-bugfix"` — bugfixes carry RED-first
835
+ * repro coverage; tdd/review own the safety surface.
836
+ *
837
+ * When this returns `true`, the linter still runs the rules and prints
838
+ * their findings (so authors see them as advisory info), but does NOT
839
+ * block stage advance. An audit event of type
840
+ * `artifact_validation_demoted_by_track` is appended to
841
+ * `delegation-events.jsonl` once per stage advance for traceability.
842
+ */
843
+ export function shouldDemoteArtifactValidationByTrack(track, taskClass) {
844
+ if (track === "quick")
845
+ return true;
846
+ if (taskClass === "software-bugfix")
847
+ return true;
848
+ return false;
849
+ }
814
850
  export function stageSchema(stage, track = "standard") {
815
851
  const rawInput = stage === "tdd" ? tddStageForTrack(track) : STAGE_SCHEMA_MAP[stage];
816
852
  const base = normalizeStageSchemaInput(rawInput);
@@ -36,9 +36,9 @@ export const BRAINSTORM = {
36
36
  },
37
37
  executionModel: {
38
38
  checklist: [
39
- "**ADAPTIVE ELICITATION COMES FIRST (no exceptions, no subagent dispatch before).** Load `.cclaw/skills/adaptive-elicitation/SKILL.md`. Walk the brainstorm forcing questions one-at-a-time via the harness-native question tool, append one row to `## Q&A Log` (`Turn | Question | User answer (1-line) | Decision impact`) after each user answer. Continue until forcing-questions converge (all answered/skipped/waived) OR Ralph-Loop convergence detector says no new decision-changing rows in last 2 iterations OR user records an explicit stop-signal row. Only then proceed to delegations, drafts, or analysis. The linter `qa_log_unconverged` rule will block `stage-complete` if convergence is not reached.",
39
+ "**ADAPTIVE ELICITATION COMES FIRST (no exceptions, no subagent dispatch before).** Load `.cclaw/skills/adaptive-elicitation/SKILL.md`. Walk the brainstorm forcing questions one-at-a-time via the harness-native question tool, append one row to `## Q&A Log` (`Turn | Question | User answer (1-line) | Decision impact`) after each user answer **and stamp the row's `Decision impact` cell with the matching `[topic:<id>]` tag** (e.g. `[topic:pain]`). Continue until every forcing-question topic id is tagged on a row OR Ralph-Loop convergence detector says no new decision-changing rows in last 2 iterations OR user records an explicit stop-signal row. Only then proceed to delegations, drafts, or analysis. The linter `qa_log_unconverged` rule will block `stage-complete` if convergence is not reached.",
40
40
  "**Explore project context** — after the elicitation loop converges, inspect existing files/docs/recent activity to refine the Discovered context section; capture matching files/patterns/seeds in `Context > Discovered context` so downstream stages don't redo discovery.",
41
- "**Brainstorm forcing questions (must be covered or explicitly waived)** — what pain are we solving, what is the direct path, what happens if we do nothing, who is the first operator/user affected, and what no-go boundaries are non-negotiable.",
41
+ "**Brainstorm forcing questions (must be covered or explicitly waived)** — `pain: what pain are we solving`; `direct-path: what is the direct path`; `do-nothing: what happens if we do nothing`; `operator: who is the first operator/user affected`; `no-go: what no-go boundaries are non-negotiable`. Tag the matching `## Q&A Log` row's `Decision impact` cell with `[topic:<id>]` (e.g. `[topic:pain]`) so the linter can verify coverage in any natural language. Tags are MANDATORY for forcing-question rows; un-tagged rows do NOT count toward coverage.",
42
42
  "**Classify stage depth** — choose `lite` for clear low-risk tasks, `standard` for normal engineering/product changes, or `deep` for ambiguity, architecture, external dependency, security/data risk, or explicit think-bigger requests.",
43
43
  "**Write the Problem Decision Record** — pick a free-form `Frame type` label that names how this work is framed (examples: product, technical-maintenance, research-spike, ops-incident, infrastructure), then fill the universal Framing fields: affected user/role/operator, current state/failure mode/opportunity, desired observable outcome, evidence/signal, why now, do-nothing consequence, and non-goals.",
44
44
  "**Premise check (one pass)** — answer the three gstack-style questions in the artifact body: *Right problem? Direct path? What if we do nothing?* Take a position; do not hedge.",
@@ -41,8 +41,8 @@ export const DESIGN = {
41
41
  },
42
42
  executionModel: {
43
43
  checklist: [
44
- "**ADAPTIVE ELICITATION COMES FIRST (no exceptions, no subagent dispatch before).** Load `.cclaw/skills/adaptive-elicitation/SKILL.md`. Walk the design forcing questions one-at-a-time via the harness-native question tool, append one row to `## Q&A Log` (`Turn | Question | User answer (1-line) | Decision impact`) after each user answer. Continue until forcing-questions converge (all answered/skipped/waived) OR Ralph-Loop convergence detector says no new decision-changing rows in last 2 iterations OR user records an explicit stop-signal row. Only then proceed to research, investigator pass, architecture lock, or any delegations. The linter `qa_log_unconverged` rule will block `stage-complete` if convergence is not reached.",
45
- "**Design forcing questions (must be covered or explicitly waived)** — what is the end-to-end data flow, where are seams/ownership boundaries, which invariants must hold, and what will explicitly NOT be refactored now.",
44
+ "**ADAPTIVE ELICITATION COMES FIRST (no exceptions, no subagent dispatch before).** Load `.cclaw/skills/adaptive-elicitation/SKILL.md`. Walk the design forcing questions one-at-a-time via the harness-native question tool, append one row to `## Q&A Log` (`Turn | Question | User answer (1-line) | Decision impact`) after each user answer **and stamp the row's `Decision impact` cell with the matching `[topic:<id>]` tag** (e.g. `[topic:data-flow]`). Continue until every forcing-question topic id is tagged on a row OR Ralph-Loop convergence detector says no new decision-changing rows in last 2 iterations OR user records an explicit stop-signal row. Only then proceed to research, investigator pass, architecture lock, or any delegations. The linter `qa_log_unconverged` rule will block `stage-complete` if convergence is not reached.",
45
+ "**Design forcing questions (must be covered or explicitly waived)** — `data-flow: what is the end-to-end data flow`; `seams: where are seams/ownership boundaries`; `invariants: which invariants must hold`; `not-refactor: what will explicitly NOT be refactored now`. Tag the matching `## Q&A Log` row's `Decision impact` cell with `[topic:<id>]` (e.g. `[topic:data-flow]`) so the linter can verify coverage in any natural language. Tags are MANDATORY for forcing-question rows; un-tagged rows do NOT count toward coverage.",
46
46
  "**Out-of-scope carry-forward (do NOT re-author)** — scope OWNS the out-of-scope list. Cite scope's `## In Scope / Out of Scope > Out of Scope` via `## Upstream Handoff > Decisions carried forward`; do NOT add a separate `## NOT in scope` section in the design artifact. Add a row to `## Spec Handoff` only if a design-stage decision NEWLY excludes something not already in scope's out-of-scope.",
47
47
  "Compact design lock — design does not decide what to build; it decides how the approved scope works. For simple slices, produce a tight lock: upstream handoff, existing fit, architecture boundary, one labeled diagram, data/state flow, critical path, failure/rescue, trust boundaries, test/perf expectations, rollout/rollback, rejected alternative, and spec handoff.",
48
48
  "Trivial-Change Escape Hatch — for <=3 files, no new interfaces, and no cross-module data flow, produce a mini-design (rationale, changed files, one risk) and proceed to spec.",
@@ -46,8 +46,8 @@ export const SCOPE = {
46
46
  },
47
47
  executionModel: {
48
48
  checklist: [
49
- "**ADAPTIVE ELICITATION COMES FIRST (no exceptions, no subagent dispatch before).** Load `.cclaw/skills/adaptive-elicitation/SKILL.md`. Walk the scope forcing questions one-at-a-time via the harness-native question tool, append one row to `## Q&A Log` (`Turn | Question | User answer (1-line) | Decision impact`) after each user answer. Continue until forcing-questions converge (all answered/skipped/waived) OR Ralph-Loop convergence detector says no new decision-changing rows in last 2 iterations OR user records an explicit stop-signal row. Only then propose the scope contract draft, recommend a mode, or dispatch any delegations. The linter `qa_log_unconverged` rule will block `stage-complete` if convergence is not reached.",
50
- "**Scope forcing questions (must be covered or explicitly waived)** — what is definitely in/out, which upstream decisions are locked, and what rollback path protects users if scope assumptions fail.",
49
+ "**ADAPTIVE ELICITATION COMES FIRST (no exceptions, no subagent dispatch before).** Load `.cclaw/skills/adaptive-elicitation/SKILL.md`. Walk the scope forcing questions one-at-a-time via the harness-native question tool, append one row to `## Q&A Log` (`Turn | Question | User answer (1-line) | Decision impact`) after each user answer **and stamp the row's `Decision impact` cell with the matching `[topic:<id>]` tag** (e.g. `[topic:in-out]`). Continue until every forcing-question topic id is tagged on a row OR Ralph-Loop convergence detector says no new decision-changing rows in last 2 iterations OR user records an explicit stop-signal row. Only then propose the scope contract draft, recommend a mode, or dispatch any delegations. The linter `qa_log_unconverged` rule will block `stage-complete` if convergence is not reached.",
50
+ "**Scope forcing questions (must be covered or explicitly waived)** — `in-out: what is definitely in/out`; `locked-upstream: which upstream decisions are locked`; `rollback: what rollback path protects users if scope assumptions fail`; `failure-modes: what are the top failure modes we must design for`. Tag the matching `## Q&A Log` row's `Decision impact` cell with `[topic:<id>]` (e.g. `[topic:in-out]`) so the linter can verify coverage in any natural language. Tags are MANDATORY for forcing-question rows; un-tagged rows do NOT count toward coverage.",
51
51
  "**Scope contract first** — read brainstorm handoff, name upstream decisions used, explicit drift, confidence, unresolved questions, and next-stage risk hints; draft the in-scope/out-of-scope/deferred/discretion contract before any design choice.",
52
52
  "**Premise carry-forward (do NOT re-author)** — brainstorm OWNS the premise check (right problem / direct path / what if nothing). Cite brainstorm's `## Premise Check` section in `## Upstream Handoff > Decisions carried forward`. Add a row to `## Premise Drift` only when the scope-stage Q&A surfaced NEW evidence that materially changes the brainstorm answer (e.g. new constraint, new user signal). Otherwise mark `Premise Drift: None` — do not duplicate the brainstorm premise table.",
53
53
  "**Conditional 10-star boundary** — for deep/high-risk/product-strategy work, show what would make the product meaningfully better, then explicitly choose what ships now, what is deferred, and what is excluded without vague `later/for now` placeholders. Skip this for straightforward repair work and record `not needed: compact scope`.",
@@ -16,7 +16,9 @@ function automaticStageDelegationTable() {
16
16
  }).join("\n");
17
17
  return `| Stage | Mandatory agents | Proactive agents |
18
18
  |---|---|---|
19
- ${rows}`;
19
+ ${rows}
20
+
21
+ > **Track-aware skip (Wave 24, v6.0.0):** mandatory agents are skipped entirely when \`track === "quick"\` OR \`taskClass === "software-bugfix"\`. Use \`mandatoryAgentsFor(stage, track, taskClass)\` from \`src/content/stage-schema.ts\` for the authoritative list at runtime. Proactive agents stay enforced because they fire only on triggers (high blast radius, security-sensitive paths, etc.), not on every run.`;
20
22
  }
21
23
  function stageSummary(stage) {
22
24
  return stageDelegationSummary("standard").find((row) => row.stage === stage)
@@ -6,6 +6,6 @@ export declare const RULEBOOK_MARKDOWN = "# Cclaw Rulebook\n\n## MUST_ALWAYS\n-
6
6
  * loading skills. Three hard rules cover the most common Wave 22 regressions
7
7
  * (premature draft, premature subagent dispatch, command-line echo to chat).
8
8
  */
9
- export declare const CURSOR_GUIDELINES_RULE_MDC = "---\ndescription: cclaw zero-install behavior baseline (always-on)\nglobs:\n - \"**/*\"\nalwaysApply: true\n---\n\n<!-- cclaw-managed-cursor-guidelines-rule -->\n\n# Cclaw Baseline Guidelines\n\nThese three rules apply to every Cursor agent session in this project,\nregardless of whether stage skills loaded.\n\n## 1. Q&A floor before drafting (brainstorm/scope/design)\n\nBefore drafting any `.cclaw/artifacts/01-brainstorm-*.md`,\n`02-scope-*.md`, or `03-design-*.md`, verify that the artifact's\n`## Q&A Log` table demonstrates Ralph-Loop convergence: forcing-question\ntopics are addressed (see the stage's forcing-questions checklist row),\nthe last 2 turns produce no new decision-changing impact, OR an explicit\nuser stop-signal row is recorded. Walk the stage forcing questions one at\na time via the `AskQuestion` tool. If you find yourself proposing a\ndraft after 1-2 questions while forcing topics remain unaddressed, STOP\nand continue the loop.\n\nThe `qa_log_unconverged` linter rule will block `stage-complete` when\nconvergence has not been reached.\n\n## 2. Mandatory subagents run after Q&A approval\n\nFor brainstorm / scope / design, mandatory subagents (\n`product-discovery`, `critic`, `planner`, `architect`,\n`test-author`) run **only AFTER the user approves the elicitation\noutcome**, never before the Q&A loop converges. Dispatching them early\npreempts the user dialogue and violates the elicitation contract \u2014 the\nlinter will block stage-complete.\n\nSee each stage's \"Run Phase: post-elicitation\" rows in the materialized\nAutomatic Subagent Dispatch table.\n\n## 3. Never echo cclaw command lines to chat\n\nThe user does not run cclaw helpers (`node .cclaw/hooks/...`) manually.\nNEVER paste full command lines, `--evidence-json '{...}'` payloads,\n`--waive-delegation=...`, or shell hash commands (`shasum`,\n`sha256sum`, `Get-FileHash`, `certutil`, etc.) into chat. Run the\nhelper via the tool layer and report only the resulting summary. On\nfailure, report a compact human-readable summary plus the helper JSON in\na single fenced `json` block.\n";
10
- export declare const CURSOR_WORKFLOW_RULE_MDC = "---\ndescription: cclaw workflow guardrails for Cursor agent sessions\nglobs:\n - \"**/*\"\nalwaysApply: true\n---\n\n<!-- cclaw-managed-cursor-workflow-rule -->\n\n# Cclaw Workflow Guardrails\n\n## Activation Rule\n\nBefore responding to coding work:\n1. Read `.cclaw/state/flow-state.json`.\n2. Start with `/cc` or continue with `/cc`.\n3. If no software-stage flow applies, respond normally.\n\n## Stage Order\n\n`brainstorm -> scope -> design -> spec -> plan -> tdd -> review -> ship`\n\nTrack-specific skips are allowed only when `flow-state.track` + `skippedStages` explicitly say so.\n\n## Task Classification\n\n| Class | Route |\n|---|---|\n| non-trivial software work | `/cc <idea>` |\n| trivial software fix | `/cc <idea>` (quick track) |\n| bugfix with repro | `/cc <idea>` and enforce RED-first in tdd |\n| pure question / non-software | direct answer (no stage flow) |\n\n## Command Surface\n\n- `/cc` = entry and resume.\n- `/cc` = only progression path.\n- Knowledge capture and recall use the `learnings` skill when requested.\n\n## Verification Discipline\n\n- No completion claim without fresh command evidence in this turn.\n- Do not mark gates passed from memory.\n- Keep evidence in `.cclaw/artifacts/`; archive through closeout via `/cc` or cancel early via `node .cclaw/hooks/cancel-run.mjs`.\n\n## Delegation And Approvals\n\n- Machine-only checks in design/plan/tdd/review/ship should auto-dispatch when tooling supports it.\n- **For brainstorm / scope / design stages**: ask user input continuously via adaptive elicitation (one question per turn through the harness-native question tool \u2014 `AskQuestion` in Cursor). Walk the stage forcing-questions list one-by-one. Do NOT batch and do NOT defer to a single approval gate at the end. The `qa_log_unconverged` linter rule will block `stage-complete` when convergence is not reached (forcing topics unaddressed AND last 2 turns still produce decision-changing rows AND no stop-signal).\n- **For other stages** (spec/plan/tdd/build/review/ship): ask user input only at explicit approval gates (scope mode, plan approval, challenge resolution, ship finalization), not for routine progress updates.\n- If you find yourself proposing a draft after 1-2 questions in brainstorm/scope/design, STOP \u2014 go back to the forcing-questions list and continue.\n- Mandatory subagents in brainstorm/scope/design run only AFTER the user approves the elicitation outcome (see each stage's \"Run Phase: post-elicitation\" rows). Dispatching them before the Q&A loop converges violates the contract.\n- Never echo cclaw command lines (`node .cclaw/hooks/...`, `--evidence-json '{...}'`) to chat \u2014 the user does not run cclaw manually. Run helpers via the tool layer; report only the resulting summary.\n- If harness capabilities are partial, record waiver reasons in delegation logs.\n\n## Routing Source Of Truth\n\n- Primary router: `.cclaw/skills/using-cclaw/SKILL.md`.\n- Stage behavior: current stage skill plus `.cclaw/state/flow-state.json`.\n- Preamble budget: keep role/status announcements brief and avoid repeating\n them unless the stage or role changes.\n";
9
+ export declare const CURSOR_GUIDELINES_RULE_MDC = "---\ndescription: cclaw zero-install behavior baseline (always-on)\nglobs:\n - \"**/*\"\nalwaysApply: true\n---\n\n<!-- cclaw-managed-cursor-guidelines-rule -->\n\n# Cclaw Baseline Guidelines\n\nThese three rules apply to every Cursor agent session in this project,\nregardless of whether stage skills loaded.\n\n## 1. Q&A floor before drafting (brainstorm/scope/design)\n\nBefore drafting any `.cclaw/artifacts/01-brainstorm-*.md`,\n`02-scope-*.md`, or `03-design-*.md`, verify that the artifact's\n`## Q&A Log` table demonstrates Ralph-Loop convergence: every\nforcing-question topic id is tagged `[topic:<id>]` on at least one row\n(see the stage's forcing-questions checklist for the id list), the last\n2 turns produce no new decision-changing impact, OR an explicit user\nstop-signal row is recorded. Walk the stage forcing questions one at a\ntime via the `AskQuestion` tool. If you find yourself proposing a\ndraft after 1-2 questions while forcing topic ids remain untagged, STOP\nand continue the loop.\n\nThe `qa_log_unconverged` linter rule will block `stage-complete` when\nconvergence has not been reached. Wave 24 (v6.0.0) made `[topic:<id>]`\ntagging mandatory; the English keyword fallback was removed because it\nmis-reported convergence on RU/UA Q&A logs.\n\n## 2. Mandatory subagents run after Q&A approval\n\nFor brainstorm / scope / design, mandatory subagents (\n`product-discovery`, `critic`, `planner`, `architect`,\n`test-author`) run **only AFTER the user approves the elicitation\noutcome**, never before the Q&A loop converges. Dispatching them early\npreempts the user dialogue and violates the elicitation contract \u2014 the\nlinter will block stage-complete.\n\nSee each stage's \"Run Phase: post-elicitation\" rows in the materialized\nAutomatic Subagent Dispatch table.\n\n## 3. Never echo cclaw command lines to chat\n\nThe user does not run cclaw helpers (`node .cclaw/hooks/...`) manually.\nNEVER paste full command lines, `--evidence-json '{...}'` payloads,\n`--waive-delegation=...`, or shell hash commands (`shasum`,\n`sha256sum`, `Get-FileHash`, `certutil`, etc.) into chat. Run the\nhelper via the tool layer and report only the resulting summary. On\nfailure, report a compact human-readable summary plus the helper JSON in\na single fenced `json` block.\n";
10
+ export declare const CURSOR_WORKFLOW_RULE_MDC = "---\ndescription: cclaw workflow guardrails for Cursor agent sessions\nglobs:\n - \"**/*\"\nalwaysApply: true\n---\n\n<!-- cclaw-managed-cursor-workflow-rule -->\n\n# Cclaw Workflow Guardrails\n\n## Activation Rule\n\nBefore responding to coding work:\n1. Read `.cclaw/state/flow-state.json`.\n2. Start with `/cc` or continue with `/cc`.\n3. If no software-stage flow applies, respond normally.\n\n## Stage Order\n\n`brainstorm -> scope -> design -> spec -> plan -> tdd -> review -> ship`\n\nTrack-specific skips are allowed only when `flow-state.track` + `skippedStages` explicitly say so.\n\n## Task Classification\n\n| Class | Route |\n|---|---|\n| non-trivial software work | `/cc <idea>` |\n| trivial software fix | `/cc <idea>` (quick track) |\n| bugfix with repro | `/cc <idea>` and enforce RED-first in tdd |\n| pure question / non-software | direct answer (no stage flow) |\n\n## Command Surface\n\n- `/cc` = entry and resume.\n- `/cc` = only progression path.\n- Knowledge capture and recall use the `learnings` skill when requested.\n\n## Verification Discipline\n\n- No completion claim without fresh command evidence in this turn.\n- Do not mark gates passed from memory.\n- Keep evidence in `.cclaw/artifacts/`; archive through closeout via `/cc` or cancel early via `node .cclaw/hooks/cancel-run.mjs`.\n\n## Delegation And Approvals\n\n- Machine-only checks in design/plan/tdd/review/ship should auto-dispatch when tooling supports it.\n- **For brainstorm / scope / design stages**: ask user input continuously via adaptive elicitation (one question per turn through the harness-native question tool \u2014 `AskQuestion` in Cursor). Walk the stage forcing-questions list one-by-one. **Tag each Q&A Log row's `Decision impact` cell with `[topic:<id>]`** (the id is given in the stage's forcing-questions checklist) so the linter can verify coverage in any natural language. Do NOT batch and do NOT defer to a single approval gate at the end. The `qa_log_unconverged` linter rule will block `stage-complete` when convergence is not reached (forcing topic ids untagged AND last 2 turns still produce decision-changing rows AND no stop-signal).\n- **For other stages** (spec/plan/tdd/build/review/ship): ask user input only at explicit approval gates (scope mode, plan approval, challenge resolution, ship finalization), not for routine progress updates.\n- If you find yourself proposing a draft after 1-2 questions in brainstorm/scope/design, STOP \u2014 go back to the forcing-questions list and continue.\n- Mandatory subagents in brainstorm/scope/design run only AFTER the user approves the elicitation outcome (see each stage's \"Run Phase: post-elicitation\" rows). Dispatching them before the Q&A loop converges violates the contract.\n- Never echo cclaw command lines (`node .cclaw/hooks/...`, `--evidence-json '{...}'`) to chat \u2014 the user does not run cclaw manually. Run helpers via the tool layer; report only the resulting summary.\n- If harness capabilities are partial, record waiver reasons in delegation logs.\n\n## Routing Source Of Truth\n\n- Primary router: `.cclaw/skills/using-cclaw/SKILL.md`.\n- Stage behavior: current stage skill plus `.cclaw/state/flow-state.json`.\n- Preamble budget: keep role/status announcements brief and avoid repeating\n them unless the stage or role changes.\n";
11
11
  export declare function buildRulesJson(): Record<string, unknown>;
@@ -86,9 +86,10 @@ export const ARTIFACT_TEMPLATES = {
86
86
  ## Q&A Log
87
87
  | Turn | Question | User answer (1-line) | Decision impact |
88
88
  |---|---|---|---|
89
- | 1 | | | |
89
+ | 1 | | | scope-shaping [topic:pain] |
90
90
 
91
91
  > Append-only by turn. Add one row after each user answer; do not rewrite prior rows.
92
+ > **Topic tag is MANDATORY for forcing-question rows.** Stamp \`[topic:<id>]\` in the \`Decision impact\` cell so the linter can verify coverage in any natural language (RU/EN/UA/etc.). Brainstorm IDs: \`pain\`, \`direct-path\`, \`do-nothing\`, \`operator\`, \`no-go\`. Multiple tags allowed when one answer covers several topics. Stop-signal rows do NOT need a tag. Wave 24 (v6.0.0) removed the English keyword fallback.
92
93
 
93
94
  ## Approach Tier
94
95
  - Tier: lite | standard | deep
@@ -209,9 +210,10 @@ ${MARKDOWN_CODE_FENCE}
209
210
  ## Q&A Log
210
211
  | Turn | Question | User answer (1-line) | Decision impact |
211
212
  |---|---|---|---|
212
- | 1 | | | |
213
+ | 1 | | | scope-shaping [topic:in-out] |
213
214
 
214
215
  > Append-only by turn. Add one row after each user answer; do not rewrite prior rows.
216
+ > **Topic tag is MANDATORY for forcing-question rows.** Stamp \`[topic:<id>]\` in the \`Decision impact\` cell so the linter can verify coverage in any natural language (RU/EN/UA/etc.). Scope IDs: \`in-out\`, \`locked-upstream\`, \`rollback\`, \`failure-modes\`. Multiple tags allowed when one answer covers several topics. Stop-signal rows do NOT need a tag. Wave 24 (v6.0.0) removed the English keyword fallback.
215
217
 
216
218
  ## Pre-Scope System Audit
217
219
  | Check | Command | Findings |
@@ -447,9 +449,10 @@ ${MARKDOWN_CODE_FENCE}
447
449
  ## Q&A Log
448
450
  | Turn | Question | User answer (1-line) | Decision impact |
449
451
  |---|---|---|---|
450
- | 1 | | | |
452
+ | 1 | | | architecture-shaping [topic:data-flow] |
451
453
 
452
454
  > Append-only by turn. Add one row after each user answer; do not rewrite prior rows.
455
+ > **Topic tag is MANDATORY for forcing-question rows.** Stamp \`[topic:<id>]\` in the \`Decision impact\` cell so the linter can verify coverage in any natural language (RU/EN/UA/etc.). Design IDs: \`data-flow\`, \`seams\`, \`invariants\`, \`not-refactor\`. Multiple tags allowed when one answer covers several topics. Stop-signal rows do NOT need a tag. Wave 24 (v6.0.0) removed the English keyword fallback.
453
456
 
454
457
  ## Codebase Investigation
455
458
  | File | Current responsibility | Patterns discovered | Existing fit / reuse candidate |
@@ -1484,16 +1487,19 @@ regardless of whether stage skills loaded.
1484
1487
 
1485
1488
  Before drafting any \`.cclaw/artifacts/01-brainstorm-*.md\`,
1486
1489
  \`02-scope-*.md\`, or \`03-design-*.md\`, verify that the artifact's
1487
- \`## Q&A Log\` table demonstrates Ralph-Loop convergence: forcing-question
1488
- topics are addressed (see the stage's forcing-questions checklist row),
1489
- the last 2 turns produce no new decision-changing impact, OR an explicit
1490
- user stop-signal row is recorded. Walk the stage forcing questions one at
1491
- a time via the \`AskQuestion\` tool. If you find yourself proposing a
1492
- draft after 1-2 questions while forcing topics remain unaddressed, STOP
1490
+ \`## Q&A Log\` table demonstrates Ralph-Loop convergence: every
1491
+ forcing-question topic id is tagged \`[topic:<id>]\` on at least one row
1492
+ (see the stage's forcing-questions checklist for the id list), the last
1493
+ 2 turns produce no new decision-changing impact, OR an explicit user
1494
+ stop-signal row is recorded. Walk the stage forcing questions one at a
1495
+ time via the \`AskQuestion\` tool. If you find yourself proposing a
1496
+ draft after 1-2 questions while forcing topic ids remain untagged, STOP
1493
1497
  and continue the loop.
1494
1498
 
1495
1499
  The \`qa_log_unconverged\` linter rule will block \`stage-complete\` when
1496
- convergence has not been reached.
1500
+ convergence has not been reached. Wave 24 (v6.0.0) made \`[topic:<id>]\`
1501
+ tagging mandatory; the English keyword fallback was removed because it
1502
+ mis-reported convergence on RU/UA Q&A logs.
1497
1503
 
1498
1504
  ## 2. Mandatory subagents run after Q&A approval
1499
1505
 
@@ -1565,7 +1571,7 @@ Track-specific skips are allowed only when \`flow-state.track\` + \`skippedStage
1565
1571
  ## Delegation And Approvals
1566
1572
 
1567
1573
  - Machine-only checks in design/plan/tdd/review/ship should auto-dispatch when tooling supports it.
1568
- - **For brainstorm / scope / design stages**: ask user input continuously via adaptive elicitation (one question per turn through the harness-native question tool — \`AskQuestion\` in Cursor). Walk the stage forcing-questions list one-by-one. Do NOT batch and do NOT defer to a single approval gate at the end. The \`qa_log_unconverged\` linter rule will block \`stage-complete\` when convergence is not reached (forcing topics unaddressed AND last 2 turns still produce decision-changing rows AND no stop-signal).
1574
+ - **For brainstorm / scope / design stages**: ask user input continuously via adaptive elicitation (one question per turn through the harness-native question tool — \`AskQuestion\` in Cursor). Walk the stage forcing-questions list one-by-one. **Tag each Q&A Log row's \`Decision impact\` cell with \`[topic:<id>]\`** (the id is given in the stage's forcing-questions checklist) so the linter can verify coverage in any natural language. Do NOT batch and do NOT defer to a single approval gate at the end. The \`qa_log_unconverged\` linter rule will block \`stage-complete\` when convergence is not reached (forcing topic ids untagged AND last 2 turns still produce decision-changing rows AND no stop-signal).
1569
1575
  - **For other stages** (spec/plan/tdd/build/review/ship): ask user input only at explicit approval gates (scope mode, plan approval, challenge resolution, ship finalization), not for routine progress updates.
1570
1576
  - If you find yourself proposing a draft after 1-2 questions in brainstorm/scope/design, STOP — go back to the forcing-questions list and continue.
1571
1577
  - Mandatory subagents in brainstorm/scope/design run only AFTER the user approves the elicitation outcome (see each stage's "Run Phase: post-elicitation" rows). Dispatching them before the Q&A loop converges violates the contract.
@@ -1,5 +1,7 @@
1
1
  import { type SubagentFallback } from "./harness-adapters.js";
2
+ import { type MandatoryDelegationTaskClass } from "./content/stage-schema.js";
2
3
  import type { FlowStage } from "./types.js";
4
+ import type { FlowState } from "./flow-state.js";
3
5
  export type DelegationMode = "mandatory" | "proactive";
4
6
  export type DelegationStatus = "scheduled" | "launched" | "acknowledged" | "completed" | "failed" | "waived" | "stale";
5
7
  export declare const DELEGATION_DISPATCH_SURFACES: readonly ["claude-task", "cursor-task", "opencode-agent", "codex-agent", "generic-task", "role-switch", "manual"];
@@ -143,6 +145,13 @@ export declare function appendDelegation(projectRoot: string, entry: DelegationE
143
145
  export declare function expectedFulfillmentMode(fallbacks: SubagentFallback[]): DelegationFulfillmentMode;
144
146
  export declare function checkMandatoryDelegations(projectRoot: string, stage: FlowStage, options?: {
145
147
  repairFeatureSystem?: boolean;
148
+ /**
149
+ * Optional task class for the active run. When set to
150
+ * `"software-bugfix"`, the mandatory delegation gate is skipped
151
+ * entirely (Wave 24). Callers that don't classify the run leave
152
+ * this undefined and rely on the track-based skip.
153
+ */
154
+ taskClass?: MandatoryDelegationTaskClass | null;
146
155
  }): Promise<{
147
156
  satisfied: boolean;
148
157
  missing: string[];
@@ -160,4 +169,47 @@ export declare function checkMandatoryDelegations(projectRoot: string, stage: Fl
160
169
  staleWorkers: string[];
161
170
  /** Expected fulfillment mode for the active harness set. */
162
171
  expectedMode: DelegationFulfillmentMode;
172
+ /**
173
+ * Wave 24 (v6.0.0): true when `mandatoryAgentsFor` returned [] for
174
+ * this (track, taskClass) combination — i.e. the gate was skipped
175
+ * entirely on quick track or software-bugfix runs. The skip is also
176
+ * recorded as a `mandatory_delegations_skipped_by_track` event in
177
+ * `delegation-events.jsonl` for audit traceability.
178
+ */
179
+ skippedByTrack: boolean;
163
180
  }>;
181
+ /**
182
+ * Wave 25 (v6.1.0) — append a non-delegation audit event recording
183
+ * that one or more required artifact-validation findings were
184
+ * demoted from blocking to advisory because the active run is on a
185
+ * small-fix lane (`track === "quick"` or `taskClass === "software-bugfix"`).
186
+ *
187
+ * The event mirrors the Wave 24 `mandatory_delegations_skipped_by_track`
188
+ * audit pattern: best-effort write to `delegation-events.jsonl`, no
189
+ * agent payload, recognized by `readDelegationEvents` so it does not
190
+ * corrupt downstream parsers. Failures are swallowed.
191
+ */
192
+ export declare function recordArtifactValidationDemotedByTrack(projectRoot: string, params: {
193
+ stage: FlowStage;
194
+ track: FlowState["track"];
195
+ taskClass: MandatoryDelegationTaskClass | null;
196
+ runId: string;
197
+ sections: string[];
198
+ }): Promise<void>;
199
+ /**
200
+ * Wave 25 (v6.1.0) — append a non-delegation audit event recording
201
+ * that the scope-stage Expansion Strategist (`product-discovery`)
202
+ * delegation requirement was skipped because the active run is on a
203
+ * small-fix lane (`track === "quick"` or `taskClass === "software-bugfix"`).
204
+ *
205
+ * Mirrors the Wave 24 `mandatory_delegations_skipped_by_track`
206
+ * audit pattern: best-effort write to `delegation-events.jsonl`, no
207
+ * agent payload, recognized by `readDelegationEvents` so it does not
208
+ * corrupt downstream parsers. Failures are swallowed.
209
+ */
210
+ export declare function recordExpansionStrategistSkippedByTrack(projectRoot: string, params: {
211
+ track: FlowState["track"];
212
+ taskClass: MandatoryDelegationTaskClass | null;
213
+ runId: string;
214
+ selectedScopeMode: string;
215
+ }): Promise<void>;