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.
- package/dist/artifact-linter/brainstorm.js +1 -1
- package/dist/artifact-linter/design.d.ts +16 -0
- package/dist/artifact-linter/design.js +83 -19
- package/dist/artifact-linter/scope.js +60 -21
- package/dist/artifact-linter/shared.d.ts +158 -14
- package/dist/artifact-linter/shared.js +319 -109
- package/dist/artifact-linter.js +83 -17
- package/dist/content/skills-elicitation.js +29 -15
- package/dist/content/skills.js +10 -4
- package/dist/content/stage-schema.d.ts +52 -0
- package/dist/content/stage-schema.js +36 -0
- package/dist/content/stages/brainstorm.js +2 -2
- package/dist/content/stages/design.js +2 -2
- package/dist/content/stages/scope.js +2 -2
- package/dist/content/subagents.js +3 -1
- package/dist/content/templates.d.ts +2 -2
- package/dist/content/templates.js +17 -11
- package/dist/delegation.d.ts +52 -0
- package/dist/delegation.js +128 -3
- package/dist/flow-state.d.ts +14 -0
- package/dist/harness-adapters.js +1 -1
- package/dist/internal/advance-stage/advance.d.ts +38 -0
- package/dist/internal/advance-stage/advance.js +93 -5
- package/dist/internal/advance-stage/review-loop.d.ts +9 -0
- package/dist/internal/advance-stage/review-loop.js +42 -4
- package/package.json +1 -1
package/dist/artifact-linter.js
CHANGED
|
@@ -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)
|
|
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
|
-
|
|
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
|
|
package/dist/content/skills.js
CHANGED
|
@@ -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
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
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-
|
|
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
|
|
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-
|
|
45
|
-
"**Design forcing questions (must be covered or explicitly waived)** — what is the end-to-end data flow
|
|
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-
|
|
50
|
-
"**Scope forcing questions (must be covered or explicitly waived)** — what is definitely in/out
|
|
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:
|
|
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
|
|
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:
|
|
1488
|
-
|
|
1489
|
-
the
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
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
|
|
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.
|
package/dist/delegation.d.ts
CHANGED
|
@@ -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>;
|