cclaw-cli 6.1.1 → 6.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +2 -2
  2. package/dist/artifact-linter/brainstorm.js +13 -13
  3. package/dist/artifact-linter/design.js +5 -5
  4. package/dist/artifact-linter/scope.js +3 -3
  5. package/dist/artifact-linter/shared.d.ts +18 -19
  6. package/dist/artifact-linter/shared.js +34 -31
  7. package/dist/artifact-linter.js +4 -0
  8. package/dist/content/hooks.js +2 -2
  9. package/dist/content/skills-elicitation.js +8 -19
  10. package/dist/content/stage-schema.d.ts +3 -3
  11. package/dist/content/stage-schema.js +27 -4
  12. package/dist/content/stages/brainstorm.js +5 -5
  13. package/dist/content/stages/design.js +1 -1
  14. package/dist/content/stages/scope.js +2 -2
  15. package/dist/content/start-command.d.ts +2 -2
  16. package/dist/content/start-command.js +18 -17
  17. package/dist/content/subagents.js +1 -1
  18. package/dist/delegation.js +2 -2
  19. package/dist/flow-state.d.ts +5 -1
  20. package/dist/flow-state.js +6 -1
  21. package/dist/gate-evidence.js +4 -3
  22. package/dist/internal/advance-stage/advance.js +4 -3
  23. package/dist/internal/advance-stage/parsers.d.ts +2 -1
  24. package/dist/internal/advance-stage/parsers.js +11 -1
  25. package/dist/internal/advance-stage/proactive-delegation-trace.d.ts +19 -0
  26. package/dist/internal/advance-stage/proactive-delegation-trace.js +44 -0
  27. package/dist/internal/advance-stage/start-flow.js +17 -2
  28. package/dist/internal/advance-stage/verify.d.ts +0 -8
  29. package/dist/internal/advance-stage/verify.js +2 -30
  30. package/dist/run-persistence.js +10 -2
  31. package/dist/track-heuristics.d.ts +2 -2
  32. package/dist/track-heuristics.js +11 -6
  33. package/dist/types.d.ts +2 -0
  34. package/dist/types.js +1 -0
  35. package/package.json +1 -1
@@ -7,7 +7,7 @@ export const BRAINSTORM = {
7
7
  complexityTier: "standard",
8
8
  skillFolder: "brainstorm",
9
9
  skillName: "brainstorm",
10
- skillDescription: "Problem-discovery stage. Build a concise Problem Decision Record, choose lite/standard/deep depth, compare distinct directions, and hand approved decisions to scope.",
10
+ skillDescription: "Problem-discovery stage. Build a concise Problem Decision Record, compare distinct directions under the run's discovery mode (lean / guided / deep), and hand approved decisions to scope.",
11
11
  philosophy: {
12
12
  hardGate: "Do NOT invoke implementation skills, write code, scaffold projects, or mutate product behavior until a concrete direction is approved by the user.",
13
13
  ironLaw: "NO ARTIFACT IS COMPLETE WITHOUT AN EXPLICITLY APPROVED DIRECTION — SILENCE IS NOT APPROVAL.",
@@ -39,7 +39,7 @@ export const BRAINSTORM = {
39
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
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
- "**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.",
42
+ "**Discovery posture (flow-state `discoveryMode`)** — follow `lean` / `guided` / `deep` from the active run. Use lean for smallest safe discovery pass; guided as the default balanced pass; escalate to deep when ambiguity, architecture, external dependency, security/data risk, or explicit think-bigger requests warrant fuller option pressure and mandatory specialist coverage.",
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.",
45
45
  "**Reframe with How Might We** — write a single `How Might We …?` line that names the user/operator, the desired outcome, and the constraint. This is the altitude check before approaches.",
@@ -61,7 +61,7 @@ export const BRAINSTORM = {
61
61
  interactionProtocol: [
62
62
  "\"If something is unclear, stop. Name what's confusing. Ask.\"",
63
63
  "Start from observed project context; if the idea is vague, first narrow the project type with **one** structured question, then keep going.",
64
- "Select depth explicitly: `lite`, `standard`, or `deep`; keep lite concise, but escalate when risk/ambiguity changes decisions.",
64
+ "Honor the run's `discoveryMode` (`lean` | `guided` | `deep`) from flow-state: lean stays fastest, guided is the default breadth, deep pulls in fuller critique and mandatory delegations when the run is classified that way.",
65
65
  "Lead with the premise check (right problem / direct path / what if nothing) and the `How Might We` reframing before approaches; both go in the artifact, not just the chat.",
66
66
  "Ask at most one question per turn, only when decision-changing; if using a structured question tool, send exactly one question object, not a multi-question form.",
67
67
  "Run the shared adaptive elicitation cycle from `.cclaw/skills/adaptive-elicitation/SKILL.md`, including stop-signal handling (RU/EN/UA), smart-skip, conditional grilling triggers, and append-only `## Q&A Log` updates.",
@@ -72,7 +72,7 @@ export const BRAINSTORM = {
72
72
  "State exactly what is being approved, then **STOP** until the user explicitly approves the artifact."
73
73
  ],
74
74
  process: [
75
- "Explore project context and classify depth/scope.",
75
+ "Explore project context and align work to the run's discovery mode (lean / guided / deep).",
76
76
  "Use compact discovery for simple apps, short-circuit implementation-only asks, or ask one decision-changing question at a time.",
77
77
  "Compare 2-3 distinct approaches, including a higher-upside challenger.",
78
78
  "Collect reaction, then recommend with rationale tied to that reaction.",
@@ -145,7 +145,7 @@ export const BRAINSTORM = {
145
145
  { section: "Clarity Gate", required: false, validationRule: "Recommended before recommendation lock: include ambiguity score (0.00-1.00), decision boundaries, reaffirmed non-goals, and residual-risk handoff for scope." },
146
146
  { section: "Sharpening Questions", required: false, validationRule: "Recommended only when needed: one decision-changing question per turn with explicit `Decision impact`; compact tasks may record `None - early exit` with rationale." },
147
147
  { section: "Clarifying Questions", required: false, validationRule: "Must capture question, answer, and decision impact for each clarifying question." },
148
- { section: "Approach Tier", required: true, validationRule: "Must classify depth as lite/standard/deep and explain the risk/uncertainty signal." },
148
+ { section: "Approach Tier", required: true, validationRule: "Must record how much discovery/evidence breadth is warranted in discoveryMode terms (`lean`, `guided`, or `deep`) relative to flow-state—and explain what risk or uncertainty drives that calibration (not merely the label)." },
149
149
  { section: "Short-Circuit Decision", required: false, validationRule: "Must include Status/Why/Scope handoff lines when short-circuit is discussed; compact stubs are valid for concrete asks." },
150
150
  { section: "Reference Pattern Candidates", required: false, validationRule: "Recommended when examples influence direction: list pattern/source, reusable invariant, accept/reject/defer disposition, and reason before approaches are finalized." },
151
151
  { section: "Idea Evidence Carry-forward", required: false, validationRule: "Wave 23 (v5.0.0): when `flow-state.interactionHints.brainstorm.fromIdeaArtifact` is set, this section MUST cite the idea artifact path and the chosen `I-#`, list reused fields (Title, Why-now, Expected impact, Risk, Counter-argument), and explicitly state that only challenger row(s) were newly generated. Honors `/cc-ideate` handoff so divergent + critique + rank work is reused, not redone." },
@@ -78,7 +78,7 @@ export const DESIGN = {
78
78
  "Run compact research by default; write `.cclaw/artifacts/02a-research.md` only when deep/high-risk uncertainty requires a separate research artifact.",
79
79
  "Run investigator pass plus scope challenge/search-before-building.",
80
80
  "Walk review sections interactively and lock boundaries, data flow, state transitions, edge cases, and failure modes.",
81
- "Cover security, observability, deployment, tests, and performance for Standard+ changes.",
81
+ "Cover security, observability, deployment, tests, and performance for guided/deep-shaped design work; lean slices may omit heavy add-ons only when scope and risk justify the compact path.",
82
82
  "Run stale-diagram audit (enabled by default unless explicitly disabled).",
83
83
  "Produce required outputs: blast-radius diff (scope owns full repo audit), tier diagrams, failure table, completion dashboard. Out-of-scope is carried from scope via Upstream Handoff — do NOT re-author it.",
84
84
  "Plant high-upside deferred ideas when useful and reconcile critic/outside-voice findings.",
@@ -52,7 +52,7 @@ export const SCOPE = {
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`.",
54
54
  "**Pick one operational mode with the user** — HOLD SCOPE preserves focus; SELECTIVE EXPANSION cherry-picks high-leverage reference ideas; SCOPE EXPANSION explores ambitious alternatives; SCOPE REDUCTION cuts to the essential wedge. Recommend one, state why and what signal would change it, then keep elicitation focused until the user either approves or asks to proceed with draft boundaries.",
55
- "**Run mode-specific analysis only to needed depth** — lite keeps the selected-mode row compact; standard adds requirements/locked decisions/discretion; deep may add Landscape Check, Taste Calibration, Reference Pattern Registry, Reference Pull, Ambitious Alternatives, and Ruthless Minimum Slice evidence when mode/risk warrants it.",
55
+ "**Run mode-specific analysis only to needed depth** — lean discovery keeps the selected-mode row compact; guided adds the standard contract rows; deep may add Landscape Check, Taste Calibration, Reference Pattern Registry, Reference Pull, Ambitious Alternatives, and Ruthless Minimum Slice evidence when mode/risk warrants it.",
56
56
  "**Decision-driver contract** — list weighted decision drivers (value, risk, reversibility, effort, timeline) and score candidate scope moves so the selected mode and boundaries are evidence-backed, not preference-led.",
57
57
  "**Architecture handoff (do NOT pick architecture tier here)** — design OWNS architecture choice (minimum-viable / product-grade / ideal). Scope only picks the SCOPE MODE (HOLD/SELECTIVE/EXPAND/REDUCE) and boundary; record in `## Scope Contract > Design handoff` what design must decide (e.g. `architecture-tier`, `framework`, `data-model`). Do NOT enumerate Implementation Alternatives in scope.",
58
58
  "**Constraints (carry-forward from brainstorm/external sources)** — record explicit external/regulatory/system/integration constraints in `## Scope Contract > Constraints`. Spec OWNS testable assumptions (`## Assumptions Before Finalization`); do NOT duplicate constraint material as assumption material.",
@@ -65,7 +65,7 @@ export const SCOPE = {
65
65
  "\"Strong success criteria let you loop independently. Weak criteria require constant clarification.\"",
66
66
  decisionProtocolInstruction("scope mode selection", "present expand/selective/hold/reduce as labeled options with trade-offs and mark one as (recommended)", "recommend the option that best covers the prime-directive failure modes, four data-flow paths, observability, and deferred handling for the in-scope set with the smallest blast radius. Base your recommendation on default heuristics: greenfield -> expand, enhancement -> selective, bugfix/hotfix/refactor -> hold, broad blast radius -> reduce"),
67
67
  "Run the shared adaptive elicitation cycle from `.cclaw/skills/adaptive-elicitation/SKILL.md`, including stop-signal handling (RU/EN/UA), smart-skip, conditional grilling triggers, and append-only `## Q&A Log` updates.",
68
- "**Lead with adaptive elicitation, not with a proposed contract.** First walk scope forcing questions one-at-a-time per `adaptive-elicitation` skill. Only AFTER the Q&A loop converges (forcing-Qs answered/waived OR user stop-signal row recorded) propose the scope contract draft for approval. Lite-tier may compress: ask the smallest forcing-Q set (>= linter floor for `lightweight`/`scope`), then propose contract.",
68
+ "**Lead with adaptive elicitation, not with a proposed contract.** First walk scope forcing questions one-at-a-time per `adaptive-elicitation` skill. Only AFTER the Q&A loop converges (forcing-Qs answered/waived OR user stop-signal row recorded) propose the scope contract draft for approval. Lean discovery may compress: ask the smallest forcing-Q set that satisfies the convergence floor, then propose contract.",
69
69
  "For low-risk concrete asks, keep the proposal compact but still explicit: recommend (do not auto-select) one mode, show exact in/out/deferred boundaries, and request explicit approval before finalizing the artifact or completing the stage.",
70
70
  "Cite brainstorm's premise via `## Upstream Handoff` and take a firm position on whether scope-stage Q&A surfaced any premise drift; do NOT re-author the brainstorm Premise Check table.",
71
71
  "Push back on weak framing: vague scope needs a specific user/problem, platform vision needs a narrow wedge, social proof needs behavioral evidence.",
@@ -2,8 +2,8 @@
2
2
  * Command contract for /cc — the unified entry point.
3
3
  * No args → reads existing flow state and progresses it when a tracked flow
4
4
  * already exists; missing state/fresh placeholder state blocks with
5
- * init/start guidance. With prompt → classifies the idea, selects a track, and
6
- * starts the first stage of that track (brainstorm for medium/standard, spec for quick).
5
+ * init/start guidance. With prompt → classifies the idea, asks for one discovery mode,
6
+ * resolves the internal track, and starts the first stage of that track (brainstorm for medium/standard, spec for quick).
7
7
  */
8
8
  export declare function startCommandContract(): string;
9
9
  /**
@@ -9,8 +9,8 @@ function flowStatePath() {
9
9
  * Command contract for /cc — the unified entry point.
10
10
  * No args → reads existing flow state and progresses it when a tracked flow
11
11
  * already exists; missing state/fresh placeholder state blocks with
12
- * init/start guidance. With prompt → classifies the idea, selects a track, and
13
- * starts the first stage of that track (brainstorm for medium/standard, spec for quick).
12
+ * init/start guidance. With prompt → classifies the idea, asks for one discovery mode,
13
+ * resolves the internal track, and starts the first stage of that track (brainstorm for medium/standard, spec for quick).
14
14
  */
15
15
  export function startCommandContract() {
16
16
  const flowPath = flowStatePath();
@@ -21,7 +21,7 @@ export function startCommandContract() {
21
21
  **The unified entry point for the cclaw flow.**
22
22
 
23
23
  - \`/cc\` (no arguments) → reads existing flow state and resumes/progresses the active flow. If flow state is missing or still a fresh init placeholder, stop and guide the user to run \`/cc <prompt>\` or \`npx cclaw-cli init\`; do not silently create a brainstorm run.
24
- - \`/cc <prompt>\` (with an idea/description) → saves the prompt as idea context and starts the first stage of the resolved track.
24
+ - \`/cc <prompt>\` (with an idea/description) → saves the prompt as idea context, asks for one discovery mode, and starts the first stage of the resolved internal track.
25
25
 
26
26
  This is the **recommended way to start, resume, and continue** working with cclaw.
27
27
 
@@ -72,7 +72,7 @@ ${conversationLanguagePolicyMarkdown()}
72
72
 
73
73
  5. Read \`${flowPath}\`.
74
74
  6. If flow already has completed stages, warn the user that starting a new tracked flow will reset progress. Ask for confirmation before proceeding. A fresh init placeholder state with \`completedStages: []\`, no passed gates, and no \`00-idea.md\` is **not** an active flow; do not ask the user to resume it.
75
- 7. **Track heuristic** — classify the idea text and **recommend** a track (the user can override before any state mutation):
75
+ 7. **Internal track heuristic** — classify the idea text and compute an internal track recommendation before any state mutation:
76
76
  - First, load \`${RUNTIME_ROOT}/config.yaml\`. If \`trackHeuristics\` is defined, apply those per-track vocabulary hints (\`fallback\`, \`tracks.<id>.{triggers,veto}\`) on top of the built-in defaults. Evaluation order is always \`standard -> medium -> quick\` (narrow-to-broad).
77
77
  - **quick** (\`spec → tdd → review → ship\`) — single-purpose work where the spec is essentially already known. Quick skips ceremony, not safety: spec approval, TDD evidence, review, and ship gates remain mandatory.
78
78
  Triggers (case-insensitive substring or close variant): \`bug\`, \`bugfix\`, \`fix\`, \`hotfix\`, \`patch\`, \`typo\`, \`regression\`, \`copy change\`, \`rename\`, \`bump\`, \`upgrade dep\`, \`config tweak\`, \`docs only\`, \`comment\`, \`lint\`, \`format\`, \`small\`, \`tiny\`, \`one-liner\`, \`revert\`.
@@ -82,14 +82,14 @@ ${conversationLanguagePolicyMarkdown()}
82
82
  Triggers: \`new feature\`, \`refactor\`, \`migration\`, \`platform\`, \`architecture\`, \`schema\`, \`integrate\`, \`workflow\`, \`onboarding\`, or any prompt that does not match quick/medium confidently.
83
83
  - When triggers conflict, prefer **standard** over **medium**, and **medium** over **quick**.
84
84
  - Report **track selection confidence** as high/medium/low with the matched trigger or fallback reason, plus one sentence explaining what the selected track skips and what safety gates remain. Be explicit that this recommendation is advisory until the user accepts and the managed helper writes state; after that, \`/cc\` follows the configured track.
85
- 8. Present one compact **Start framing** summary: class, recommended track, track selection confidence, stack, origin docs, seed recalls, and the recommended next action. Ask a single confirmation question only when there is a destructive reset, a real contradiction, or ambiguous software/non-software classification.
86
- 9. Present the recommendation as a single decision with explicit options:
87
- > \`Recommended track: <quick|medium|standard>\` because \`<one-line reason citing matched triggers>\`.
88
- > \`Safety retained: <spec/TDD/review/ship gates that still apply>\`.
89
- > Override? (A) keep \`<recommended>\` (B) switch track with reason (C) cancel.
85
+ 8. Present one compact **Start framing** summary: class, internal track recommendation, track selection confidence, stack, origin docs, seed recalls, and the recommended next action. Ask a single confirmation question only when there is a destructive reset, a real contradiction, or ambiguous software/non-software classification.
86
+ 9. Ask one explicit **discovery mode** question and make it the only normal start-of-run user choice:
87
+ > \`Choose discovery mode: Lean / Guided / Deep\`.
88
+ > \`Lean\` = compact shaping, \`Guided\` = recommended default with enough questions and key specialists before drafting, \`Deep\` = stronger probing and broader specialist/research passes.
89
+ > Mention the internal track recommendation only as context, not as the primary decision. Offer track override only when reset, contradiction, or reclassification evidence makes the internal recommendation suspect.
90
90
  If the harness's native ask tool is available (\`AskUserQuestion\` / \`AskQuestion\` / \`question\` / \`request_user_input\`), send exactly ONE question; on schema error, fall back to a plain-text lettered list.
91
91
  10. Start the tracked flow only through the managed helper:
92
- \`node .cclaw/hooks/start-flow.mjs --track=<quick|medium|standard> --class=<class> --prompt=<prompt> --stack=<stack> --reason=<matched heuristic>\`
92
+ \`node .cclaw/hooks/start-flow.mjs --track=<quick|medium|standard> --discovery-mode=<lean|guided|deep> --class=<class> --prompt=<prompt> --stack=<stack> --reason=<matched heuristic>\`
93
93
  If this helper fails, STOP. Report one human-readable failure line from the JSON \`error\` field, include the helper JSON payload in a fenced \`json\` block, and never echo the invoking command line. Do **not** manually edit \`${flowPath}\`.
94
94
  11. The helper persists \`${flowPath}\`, computes \`skippedStages\`, sets the first stage for the track, resets the gate catalog, and writes \`.cclaw/artifacts/00-idea.md\`.
95
95
  12. Load the **first-stage skill for the chosen track** and its command file:
@@ -103,9 +103,9 @@ ${conversationLanguagePolicyMarkdown()}
103
103
  If during any stage the agent discovers evidence that contradicts the initial Phase 0 / track decision (e.g. a supposedly \`trivial\` change turns out to require schema migration, a \`quick\` bug fix turns out to need design discussion, an origin doc reveals scope 3× larger than the prompt), STOP and re-classify:
104
104
 
105
105
  1. Surface the new evidence in plain text.
106
- 2. Propose the updated \`Class\` + \`Track\` with a one-line reason.
106
+ 2. Propose the updated \`Class\`, internal \`Track\`, and (when discovery posture should change) \`Discovery mode\` with a one-line reason.
107
107
  3. Use the Decision Protocol to let the user accept, override, or cancel.
108
- 4. On acceptance: run \`node .cclaw/hooks/start-flow.mjs --reclassify --track=<new-track> --class=<new-class> --reason=<why>\`. The helper appends a \`Reclassification:\` entry to \`00-idea.md\` and updates flow state atomically. If it fails, STOP and report one human-readable line plus the helper JSON payload in a fenced \`json\` block; never echo the invoking command line. Do NOT manually edit \`flow-state.json\`.
108
+ 4. On acceptance: run \`node .cclaw/hooks/start-flow.mjs --reclassify --track=<new-track> --discovery-mode=<lean|guided|deep> --class=<new-class> --reason=<why>\`. The helper appends a \`Reclassification:\` entry to \`00-idea.md\` and updates flow state atomically. If it fails, STOP and report one human-readable line plus the helper JSON payload in a fenced \`json\` block; never echo the invoking command line. Do NOT manually edit \`flow-state.json\`.
109
109
 
110
110
  ### Without prompt (\`/cc\`)
111
111
 
@@ -153,7 +153,7 @@ description: "Unified entry point for the cclaw flow. No args = resume/next. Wit
153
153
  \`/cc\` is the **starting command** for cclaw. It intelligently routes:
154
154
 
155
155
  - **No arguments** → resumes or progresses an existing tracked flow; missing/fresh placeholder state blocks with start guidance
156
- - **With a prompt** → classifies the task, picks a track (quick/medium/standard), and starts the **first stage of that track** (not always brainstorm — e.g. the \`quick\` track starts at \`spec\`)
156
+ - **With a prompt** → classifies the task, asks for one discovery mode (lean/guided/deep), resolves an internal track (quick/medium/standard), and starts the **first stage of that track** (not always brainstorm — e.g. the \`quick\` track starts at \`spec\`)
157
157
 
158
158
  ## HARD-GATE
159
159
 
@@ -174,7 +174,7 @@ ${conversationLanguagePolicyMarkdown()}
174
174
  - Ask: "Continue with reset? (A) Yes, start fresh (B) No, resume current flow"
175
175
  - If (B) → switch to Path B behavior.
176
176
  If \`completedStages\` is empty, all gate \`passed\` arrays are empty, and \`${RUNTIME_ROOT}/artifacts/00-idea.md\` is missing, treat it as a fresh init placeholder — do **not** ask whether to continue the current flow.
177
- 7. **Classify the idea** using the heuristic below and present one compact Start framing summary (class, track, stack, origin docs, seed recalls, next action). Wait for explicit confirmation or override before mutating any state only when reset/conflict/ambiguity makes it necessary.
177
+ 7. **Classify the idea** using the heuristic below and present one compact Start framing summary (class, internal track recommendation, stack, origin docs, seed recalls, next action). Wait for explicit confirmation or override before mutating any state only when reset/conflict/ambiguity makes it necessary.
178
178
  - If \`${RUNTIME_ROOT}/config.yaml\` defines \`trackHeuristics\`, apply those vocabulary hints (\`fallback\`, \`tracks.<id>.{triggers,veto}\`) on top of built-in defaults. Evaluation order is fixed: \`standard -> medium -> quick\`. (Honest note: this is advisory prose; the LLM applies it, not a Node-level router.)
179
179
 
180
180
  **Track heuristic** (lowercase substring match against the user prompt):
@@ -187,12 +187,13 @@ ${conversationLanguagePolicyMarkdown()}
187
187
 
188
188
  - On conflict, prefer \`standard\` over \`medium\`, and \`medium\` over \`quick\`.
189
189
  - Always state the recommendation as a one-line reason citing matched triggers and a high/medium/low track selection confidence. Clarify that the heuristic is advisory until the managed helper writes state; after that, \`/cc\` follows the selected track. Include override guidance: switch to standard when architecture, schema, migration, security, or unclear scope appears; switch to medium when product framing is needed but architecture is known.
190
- 8. Run the managed start helper: \`node .cclaw/hooks/start-flow.mjs --track=<quick|medium|standard> --class=<class> --prompt=<prompt> --stack=<stack> --reason=<matched heuristic>\`. The helper writes \`${flowPath}\`, computes \`skippedStages\`, resets the gate catalog, and writes \`${RUNTIME_ROOT}/artifacts/00-idea.md\`. If it fails, STOP, report one human-readable failure line from the JSON \`error\` field, and include the helper JSON payload in a fenced \`json\` block; do not echo the invoking command line, and do not manually edit flow state.
190
+ 8. Ask for the single explicit start choice: \`Lean / Guided / Deep\`. Use \`Guided\` as the recommended default unless the user clearly wants compact shaping or unusually deep probing. Keep track internal unless contradiction/reset/reclassification requires surfacing an override.
191
+ 9. Run the managed start helper: \`node .cclaw/hooks/start-flow.mjs --track=<quick|medium|standard> --discovery-mode=<lean|guided|deep> --class=<class> --prompt=<prompt> --stack=<stack> --reason=<matched heuristic>\`. The helper writes \`${flowPath}\`, including \`discoveryMode\`, computes \`skippedStages\`, resets the gate catalog, and writes \`${RUNTIME_ROOT}/artifacts/00-idea.md\`. If it fails, STOP, report one human-readable failure line from the JSON \`error\` field, and include the helper JSON payload in a fenced \`json\` block; do not echo the invoking command line, and do not manually edit flow state.
191
192
  9. Load and execute the **first stage skill of the chosen track** (\`brainstorm\` for medium/standard, \`spec\` for quick) plus its matching command file.
192
193
 
193
194
  ### Reclassification on discovery
194
195
 
195
- If mid-stage evidence contradicts the initial Class/Track decision (the "trivial" change needs a migration, the "quick" bug fix needs architecture work, an origin doc multiplies scope), STOP and re-classify using the Decision Protocol. On acceptance, run \`node .cclaw/hooks/start-flow.mjs --reclassify --track=<new-track> --class=<new-class> --reason=<why>\`; the helper records \`Reclassification:\` in \`00-idea.md\` and updates state atomically. If it fails, report one human-readable line plus the helper JSON payload in a fenced \`json\` block, never echo the invoking command line, and do not rewrite prior artifacts or manually edit flow-state.
196
+ If mid-stage evidence contradicts the initial Class/Track/Discovery decision (the "trivial" change needs a migration, the "quick" bug fix needs architecture work, an origin doc multiplies scope), STOP and re-classify using the Decision Protocol. On acceptance, run \`node .cclaw/hooks/start-flow.mjs --reclassify --track=<new-track> --discovery-mode=<lean|guided|deep> --class=<new-class> --reason=<why>\`; the helper records \`Reclassification:\` in \`00-idea.md\` and updates state atomically. If it fails, report one human-readable line plus the helper JSON payload in a fenced \`json\` block, never echo the invoking command line, and do not rewrite prior artifacts or manually edit flow-state.
196
197
 
197
198
  ### Path B: \`/cc\` (no arguments)
198
199
 
@@ -217,6 +218,6 @@ Use \`/cc\` for the happy path:
217
218
  | Progressing after completing a stage | \`/cc\` |
218
219
  | Starting with a specific idea | \`/cc <idea>\` |
219
220
 
220
- \`/cc <prompt>\` resolves class + track and starts that track's first stage; \`/cc\` without a prompt follows the current \`flow-state.json\`.
221
+ \`/cc <prompt>\` resolves class + internal track, asks for one discovery mode, and starts the selected track's first stage; \`/cc\` without a prompt follows the current \`flow-state.json\`.
221
222
  `;
222
223
  }
@@ -18,7 +18,7 @@ function automaticStageDelegationTable() {
18
18
  |---|---|---|
19
19
  ${rows}
20
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.`;
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 are trigger-driven opportunities, not a blanket completion gate, and lean/lightweight early-stage runs may intentionally record none.`;
22
22
  }
23
23
  function stageSummary(stage) {
24
24
  return stageDelegationSummary("standard").find((row) => row.stage === stage)
@@ -481,9 +481,9 @@ export async function checkMandatoryDelegations(projectRoot, stage, options = {}
481
481
  // via `flow-state.json`. Forward-typed `null` callers still suppress
482
482
  // the lookup explicitly; only `undefined` triggers the fallback.
483
483
  const resolvedTaskClass = options.taskClass !== undefined ? options.taskClass : flowState.taskClass ?? null;
484
- const mandatory = mandatoryAgentsFor(stage, flowState.track, resolvedTaskClass);
484
+ const mandatory = mandatoryAgentsFor(stage, flowState.track, resolvedTaskClass, "standard", flowState.discoveryMode);
485
485
  const skippedByTrack = mandatory.length === 0 &&
486
- stageSchema(stage, flowState.track).mandatoryDelegations.length > 0;
486
+ stageSchema(stage, flowState.track, flowState.discoveryMode, resolvedTaskClass).mandatoryDelegations.length > 0;
487
487
  if (skippedByTrack) {
488
488
  await recordMandatorySkippedByTrack(projectRoot, {
489
489
  stage,
@@ -1,4 +1,4 @@
1
- import type { FlowStage, FlowTrack, TransitionRule } from "./types.js";
1
+ import type { DiscoveryMode, FlowStage, FlowTrack, TransitionRule } from "./types.js";
2
2
  export declare const TRANSITION_RULES: TransitionRule[];
3
3
  export declare const FLOW_STATE_SCHEMA_VERSION = 1;
4
4
  export interface StageGateState {
@@ -76,6 +76,8 @@ export interface FlowState {
76
76
  stageGateCatalog: Record<FlowStage, StageGateState>;
77
77
  /** Active flow track (determines which stages are in the critical path for this run). */
78
78
  track: FlowTrack;
79
+ /** Run-level upstream shaping mode chosen once at start (`lean` / `guided` / `deep`). */
80
+ discoveryMode: DiscoveryMode;
79
81
  /**
80
82
  * Wave 25 (v6.1.0) — optional task class for the active run.
81
83
  *
@@ -123,8 +125,10 @@ export interface StageInteractionHint {
123
125
  export interface InitialFlowStateOptions {
124
126
  activeRunId?: string;
125
127
  track?: FlowTrack;
128
+ discoveryMode?: DiscoveryMode;
126
129
  }
127
130
  export declare function isFlowTrack(value: unknown): value is FlowTrack;
131
+ export declare function isDiscoveryMode(value: unknown): value is DiscoveryMode;
128
132
  export declare function trackStages(track: FlowTrack): FlowStage[];
129
133
  export declare function skippedStagesForTrack(track: FlowTrack): FlowStage[];
130
134
  export declare function firstStageForTrack(track: FlowTrack): FlowStage;
@@ -1,5 +1,5 @@
1
1
  import { buildTransitionRules, orderedStageSchemas, stageGateIds, stageRecommendedGateIds } from "./content/stage-schema.js";
2
- import { FLOW_STAGES, FLOW_TRACKS, TRACK_STAGES } from "./types.js";
2
+ import { DISCOVERY_MODES, FLOW_STAGES, FLOW_TRACKS, TRACK_STAGES } from "./types.js";
3
3
  export const TRANSITION_RULES = buildTransitionRules();
4
4
  export const FLOW_STATE_SCHEMA_VERSION = 1;
5
5
  /**
@@ -47,6 +47,9 @@ export function createInitialCloseoutState() {
47
47
  export function isFlowTrack(value) {
48
48
  return typeof value === "string" && FLOW_TRACKS.includes(value);
49
49
  }
50
+ export function isDiscoveryMode(value) {
51
+ return typeof value === "string" && DISCOVERY_MODES.includes(value);
52
+ }
50
53
  export function trackStages(track) {
51
54
  return [...TRACK_STAGES[track]];
52
55
  }
@@ -67,6 +70,7 @@ export function createInitialFlowState(activeRunIdOrOptions = {}, maybeTrack) {
67
70
  : activeRunIdOrOptions;
68
71
  const activeRunId = options.activeRunId ?? createRunId();
69
72
  const track = options.track ?? "standard";
73
+ const discoveryMode = options.discoveryMode ?? "guided";
70
74
  const skippedStages = skippedStagesForTrack(track);
71
75
  const stageGateCatalog = {};
72
76
  for (const schema of orderedStageSchemas(track)) {
@@ -87,6 +91,7 @@ export function createInitialFlowState(activeRunIdOrOptions = {}, maybeTrack) {
87
91
  guardEvidence: {},
88
92
  stageGateCatalog,
89
93
  track,
94
+ discoveryMode,
90
95
  skippedStages,
91
96
  staleStages: {},
92
97
  rewinds: [],
@@ -210,7 +210,7 @@ const DESIGN_RESEARCH_REQUIRED_SECTIONS = [
210
210
  ];
211
211
  export async function verifyCurrentStageGateEvidence(projectRoot, flowState, options = {}) {
212
212
  const stage = flowState.currentStage;
213
- const schema = stageSchema(stage, flowState.track);
213
+ const schema = stageSchema(stage, flowState.track, flowState.discoveryMode, flowState.taskClass ?? null);
214
214
  const catalog = flowState.stageGateCatalog[stage];
215
215
  const required = schema.requiredGates
216
216
  .filter((gate) => gate.tier === "required")
@@ -462,6 +462,7 @@ export async function verifyCurrentStageGateEvidence(projectRoot, flowState, opt
462
462
  const skipQuestionsHint = flowState.interactionHints?.[stage]?.skipQuestions === true ||
463
463
  (options.extraStageFlags ?? []).includes("--skip-questions");
464
464
  const floor = evaluateQaLogFloor(qaLogBody, flowState.track, stage, {
465
+ discoveryMode: flowState.discoveryMode,
465
466
  skipQuestions: skipQuestionsHint
466
467
  });
467
468
  qaLogFloor = {
@@ -498,7 +499,7 @@ export function verifyCompletedStagesGateClosure(flowState) {
498
499
  const issues = [];
499
500
  const openStages = [];
500
501
  for (const stage of flowState.completedStages) {
501
- const schema = stageSchema(stage, flowState.track);
502
+ const schema = stageSchema(stage, flowState.track, flowState.discoveryMode, flowState.taskClass ?? null);
502
503
  const catalog = flowState.stageGateCatalog[stage];
503
504
  const required = schema.requiredGates
504
505
  .filter((gate) => gate.tier === "required")
@@ -526,7 +527,7 @@ export function verifyCompletedStagesGateClosure(flowState) {
526
527
  }
527
528
  export function reconcileCurrentStageGateCatalog(flowState) {
528
529
  const stage = flowState.currentStage;
529
- const schema = stageSchema(stage, flowState.track);
530
+ const schema = stageSchema(stage, flowState.track, flowState.discoveryMode, flowState.taskClass ?? null);
530
531
  const required = schema.requiredGates
531
532
  .filter((gate) => gate.tier === "required")
532
533
  .map((gate) => gate.id);
@@ -11,7 +11,7 @@ import { stageSchema } from "../../content/stage-schema.js";
11
11
  import { extractReviewLoopEnvelopeFromArtifact } from "../../content/review-loop.js";
12
12
  import { unique } from "./helpers.js";
13
13
  import { AUTO_REVIEW_LOOP_GATE_BY_STAGE, reviewLoopArtifactFixHint, reviewLoopEnvelopeExample, validateGateEvidenceShape } from "./review-loop.js";
14
- import { ensureProactiveDelegationTrace } from "./verify.js";
14
+ import { ensureProactiveDelegationTrace } from "./proactive-delegation-trace.js";
15
15
  function resolveSuccessorTransition(stage, track, transitionTargets, satisfiedGuards, selectedTransitionGuards) {
16
16
  const natural = transitionTargets[0] ?? null;
17
17
  const specialTargets = transitionTargets.filter((target) => target !== natural);
@@ -299,7 +299,7 @@ export async function runAdvanceStage(projectRoot, args, io) {
299
299
  io.stderr.write(`cclaw internal advance-stage: current stage is "${flowState.currentStage}", not "${args.stage}".\n`);
300
300
  return 1;
301
301
  }
302
- const schema = stageSchema(args.stage, flowState.track);
302
+ const schema = stageSchema(args.stage, flowState.track, flowState.discoveryMode, flowState.taskClass ?? null);
303
303
  const requiredGateIds = schema.requiredGates
304
304
  .filter((gate) => gate.tier === "required")
305
305
  .map((gate) => gate.id);
@@ -530,7 +530,8 @@ export async function runAdvanceStage(projectRoot, args, io) {
530
530
  }
531
531
  const proactiveTrace = await ensureProactiveDelegationTrace(projectRoot, args.stage, {
532
532
  acceptWaiver: args.acceptProactiveWaiver,
533
- waiverReason: args.acceptProactiveWaiverReason
533
+ waiverReason: args.acceptProactiveWaiverReason,
534
+ discoveryMode: flowState.discoveryMode
534
535
  });
535
536
  if (proactiveTrace.missingRules.length > 0) {
536
537
  const missingSummary = proactiveTrace.missingRules
@@ -1,4 +1,4 @@
1
- import { type FlowStage, type FlowTrack } from "../../types.js";
1
+ import { type DiscoveryMode, type FlowStage, type FlowTrack } from "../../types.js";
2
2
  import type { ArchiveDisposition } from "../../runs.js";
3
3
  export interface AdvanceStageArgs {
4
4
  stage: FlowStage;
@@ -32,6 +32,7 @@ export interface RewindArgs {
32
32
  }
33
33
  export interface StartFlowArgs {
34
34
  track: FlowTrack;
35
+ discoveryMode: DiscoveryMode;
35
36
  className?: string;
36
37
  prompt?: string;
37
38
  reason?: string;
@@ -1,5 +1,5 @@
1
1
  import { FLOW_STAGES } from "../../types.js";
2
- import { isFlowTrack } from "../../flow-state.js";
2
+ import { isDiscoveryMode, isFlowTrack } from "../../flow-state.js";
3
3
  import { isFlowStageValue, parseCsv, parseEvidenceByGate, unique } from "./helpers.js";
4
4
  export function parseAdvanceStageArgs(tokens) {
5
5
  const [stageRaw, ...flagTokens] = tokens;
@@ -204,6 +204,7 @@ export function parseHookArgs(tokens) {
204
204
  }
205
205
  export function parseStartFlowArgs(tokens) {
206
206
  let track;
207
+ let discoveryMode = "guided";
207
208
  let className;
208
209
  let prompt;
209
210
  let reason;
@@ -245,6 +246,14 @@ export function parseStartFlowArgs(tokens) {
245
246
  track = raw;
246
247
  continue;
247
248
  }
249
+ if (token === "--discovery-mode" || token.startsWith("--discovery-mode=")) {
250
+ const raw = readValue("--discovery-mode").trim();
251
+ if (!isDiscoveryMode(raw)) {
252
+ throw new Error(`--discovery-mode must be one of: lean, guided, deep.`);
253
+ }
254
+ discoveryMode = raw;
255
+ continue;
256
+ }
248
257
  if (token === "--class" || token.startsWith("--class=")) {
249
258
  className = readValue("--class").trim();
250
259
  continue;
@@ -281,6 +290,7 @@ export function parseStartFlowArgs(tokens) {
281
290
  }
282
291
  return {
283
292
  track,
293
+ discoveryMode,
284
294
  className,
285
295
  prompt,
286
296
  reason,
@@ -0,0 +1,19 @@
1
+ import { type StageAutoSubagentDispatch } from "../../content/stage-schema.js";
2
+ import type { DiscoveryMode, FlowStage } from "../../types.js";
3
+ export interface ProactiveDelegationTraceResult {
4
+ missingRules: StageAutoSubagentDispatch[];
5
+ }
6
+ /**
7
+ * Ensure every proactive dispatch rule for the stage has a ledger row for the
8
+ * active run, or an explicit user-flag waiver.
9
+ *
10
+ * Lean/guided discovery on early elicitation stages intentionally does not
11
+ * require a full proactive trace: specialists run only when triggers warrant
12
+ * them. Deep discovery keeps the blanket trace so mandatory + proactive
13
+ * coverage stays auditably complete before advance.
14
+ */
15
+ export declare function ensureProactiveDelegationTrace(projectRoot: string, stage: FlowStage, options: {
16
+ acceptWaiver: boolean;
17
+ waiverReason?: string;
18
+ discoveryMode: DiscoveryMode;
19
+ }): Promise<ProactiveDelegationTraceResult>;
@@ -0,0 +1,44 @@
1
+ import { appendDelegation, readDelegationLedger } from "../../delegation.js";
2
+ import { stageAutoSubagentDispatch } from "../../content/stage-schema.js";
3
+ function isEarlyElicitationStage(stage) {
4
+ return stage === "brainstorm" || stage === "scope" || stage === "design";
5
+ }
6
+ /**
7
+ * Ensure every proactive dispatch rule for the stage has a ledger row for the
8
+ * active run, or an explicit user-flag waiver.
9
+ *
10
+ * Lean/guided discovery on early elicitation stages intentionally does not
11
+ * require a full proactive trace: specialists run only when triggers warrant
12
+ * them. Deep discovery keeps the blanket trace so mandatory + proactive
13
+ * coverage stays auditably complete before advance.
14
+ */
15
+ export async function ensureProactiveDelegationTrace(projectRoot, stage, options) {
16
+ if (isEarlyElicitationStage(stage) && (options.discoveryMode === "lean" || options.discoveryMode === "guided")) {
17
+ return { missingRules: [] };
18
+ }
19
+ const proactiveRules = stageAutoSubagentDispatch(stage).filter((rule) => rule.mode === "proactive");
20
+ if (proactiveRules.length === 0)
21
+ return { missingRules: [] };
22
+ const ledger = await readDelegationLedger(projectRoot);
23
+ const currentRunEntries = ledger.entries.filter((entry) => entry.runId === ledger.runId);
24
+ const missingRules = proactiveRules.filter((rule) => !currentRunEntries.some((entry) => entry.stage === stage && entry.agent === rule.agent && entry.mode === "proactive"));
25
+ if (missingRules.length === 0)
26
+ return { missingRules: [] };
27
+ if (!options.acceptWaiver)
28
+ return { missingRules };
29
+ const waiverReason = options.waiverReason?.trim() || "accepted via --accept-proactive-waiver";
30
+ for (const rule of missingRules) {
31
+ await appendDelegation(projectRoot, {
32
+ stage,
33
+ agent: rule.agent,
34
+ mode: "proactive",
35
+ status: "waived",
36
+ waiverReason,
37
+ acceptedBy: "user-flag",
38
+ conditionTrigger: rule.when,
39
+ skill: rule.skill,
40
+ ts: new Date().toISOString()
41
+ });
42
+ }
43
+ return { missingRules: [] };
44
+ }
@@ -7,6 +7,12 @@ import { listExistingFiles, listFilesUnder, pathExists } from "./helpers.js";
7
7
  import { TRACK_STAGES } from "../../types.js";
8
8
  import { buildValidationReport } from "./advance.js";
9
9
  import { carriedCompletedStageCatalog, completedStageClosureEvidenceIssues, firstIncompleteStageForTrack } from "./verify.js";
10
+ function resolveTaskClass(className, fallback) {
11
+ if (className === "software-standard" || className === "software-trivial" || className === "software-bugfix") {
12
+ return className;
13
+ }
14
+ return fallback;
15
+ }
10
16
  export async function discoverStartFlowContext(projectRoot) {
11
17
  const lines = [];
12
18
  const seedFiles = (await listFilesUnder(projectRoot, path.join(RUNTIME_ROOT, "seeds"), 10))
@@ -58,6 +64,7 @@ export async function appendIdeaArtifact(projectRoot, args, previous) {
58
64
  `- From: ${previous?.track ?? "unknown"}`,
59
65
  `- To: ${args.track}`,
60
66
  `- Class: ${args.className || "unspecified"}`,
67
+ `- Discovery mode: ${args.discoveryMode}`,
61
68
  `- Reason: ${args.reason || "unspecified"}`
62
69
  ].join("\n") + "\n";
63
70
  await fs.appendFile(artifactPath, entry, "utf8");
@@ -68,6 +75,7 @@ export async function appendIdeaArtifact(projectRoot, args, previous) {
68
75
  "# Idea",
69
76
  `Class: ${args.className || "unspecified"}`,
70
77
  `Track: ${args.track}${args.reason ? ` (${args.reason})` : ""}`,
78
+ `Discovery mode: ${args.discoveryMode}`,
71
79
  `Stack: ${args.stack || "unknown"}`,
72
80
  "",
73
81
  "## User prompt",
@@ -85,10 +93,11 @@ export async function runStartFlow(projectRoot, args, io) {
85
93
  io.stderr.write("cclaw internal start-flow: refusing to reset an active flow with completed stages without --force-reset. Ask the user before resetting.\n");
86
94
  return 1;
87
95
  }
96
+ const nextTaskClass = resolveTaskClass(args.className, current.taskClass);
88
97
  let nextState;
89
98
  if (args.reclassify) {
90
99
  const completedInNewTrack = current.completedStages.filter((stage) => TRACK_STAGES[args.track].includes(stage));
91
- const fresh = createInitialFlowState({ activeRunId: current.activeRunId, track: args.track });
100
+ const fresh = createInitialFlowState({ activeRunId: current.activeRunId, track: args.track, discoveryMode: args.discoveryMode });
92
101
  const stageGateCatalog = { ...fresh.stageGateCatalog };
93
102
  const guardEvidence = {};
94
103
  for (const stage of completedInNewTrack) {
@@ -98,6 +107,7 @@ export async function runStartFlow(projectRoot, args, io) {
98
107
  }
99
108
  nextState = {
100
109
  ...fresh,
110
+ ...(nextTaskClass !== undefined ? { taskClass: nextTaskClass } : {}),
101
111
  completedStages: completedInNewTrack,
102
112
  currentStage: firstIncompleteStageForTrack(args.track, completedInNewTrack),
103
113
  guardEvidence,
@@ -117,7 +127,10 @@ export async function runStartFlow(projectRoot, args, io) {
117
127
  }
118
128
  }
119
129
  else {
120
- nextState = createInitialFlowState({ track: args.track });
130
+ nextState = createInitialFlowState({ track: args.track, discoveryMode: args.discoveryMode });
131
+ if (nextTaskClass !== undefined) {
132
+ nextState = { ...nextState, taskClass: nextTaskClass };
133
+ }
121
134
  }
122
135
  if (args.fromIdeaArtifact) {
123
136
  const existingHints = nextState.interactionHints ?? {};
@@ -140,6 +153,8 @@ export async function runStartFlow(projectRoot, args, io) {
140
153
  command: "start-flow",
141
154
  reclassify: args.reclassify,
142
155
  track: nextState.track,
156
+ discoveryMode: nextState.discoveryMode,
157
+ taskClass: nextState.taskClass ?? null,
143
158
  currentStage: nextState.currentStage,
144
159
  skippedStages: nextState.skippedStages,
145
160
  activeRunId: nextState.activeRunId
@@ -1,4 +1,3 @@
1
- import { type StageAutoSubagentDispatch } from "../../content/stage-schema.js";
2
1
  import { type FlowState, type StageGateState } from "../../flow-state.js";
3
2
  import { type FlowStage, type FlowTrack } from "../../types.js";
4
3
  import type { VerifyCurrentStateArgs, VerifyFlowStateDiffArgs } from "./parsers.js";
@@ -7,9 +6,6 @@ interface InternalIo {
7
6
  stdout: Writable;
8
7
  stderr: Writable;
9
8
  }
10
- interface ProactiveDelegationTraceResult {
11
- missingRules: StageAutoSubagentDispatch[];
12
- }
13
9
  export declare function runVerifyFlowStateDiff(projectRoot: string, args: VerifyFlowStateDiffArgs, io: InternalIo): Promise<number>;
14
10
  export declare function runVerifyCurrentState(projectRoot: string, args: VerifyCurrentStateArgs, io: InternalIo): Promise<number>;
15
11
  export declare function firstIncompleteStageForTrack(track: FlowTrack, completedStages: FlowStage[]): FlowStage;
@@ -18,10 +14,6 @@ export declare function carriedCompletedStageCatalog(current: FlowState, fresh:
18
14
  evidence: Record<string, string>;
19
15
  };
20
16
  export declare function completedStageClosureEvidenceIssues(flowState: FlowState): string[];
21
- export declare function ensureProactiveDelegationTrace(projectRoot: string, stage: FlowStage, options: {
22
- acceptWaiver: boolean;
23
- waiverReason?: string;
24
- }): Promise<ProactiveDelegationTraceResult>;
25
17
  export declare function pathExists(projectRoot: string, relPath: string): Promise<boolean>;
26
18
  export declare function listExistingFiles(projectRoot: string, relPaths: string[]): Promise<string[]>;
27
19
  export declare function listFilesUnder(projectRoot: string, relDir: string, limit?: number): Promise<string[]>;