cclaw-cli 7.6.0 → 7.7.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.
@@ -10,8 +10,8 @@ export const PLAN = {
10
10
  skillDescription: "Execution planning stage with strict confirmation gate before implementation.",
11
11
  philosophy: {
12
12
  hardGate: "Do NOT write code or tests. Planning only. This stage produces a task graph and execution order. WAIT_FOR_CONFIRM before any handoff to implementation.",
13
- ironLaw: "EVERY TASK IS 2–5 MINUTES, FULLY SPELLED OUT, AND CARRIES A STABLE ID NO PLACEHOLDERS, NO ‘ETC.’.",
14
- purpose: "Create small executable tasks with dependencies and pause for explicit user confirmation.",
13
+ ironLaw: "EVERY IMPLEMENTATION UNIT IS FEATURE-ATOMIC, WITH INTERNAL 2–5 MINUTE TDD STEPS STRICT MICRO-SLICES ARE RESERVED FOR HIGH-RISK WORK.",
14
+ purpose: "Create feature-atomic implementation units with dependencies, internal TDD steps, and explicit confirmation before execution.",
15
15
  whenToUse: [
16
16
  "After spec approval",
17
17
  "Before writing tests or implementation",
@@ -43,21 +43,21 @@ export const PLAN = {
43
43
  "Read upstream — load spec, design, and scope artifacts. Cross-reference acceptance criteria.",
44
44
  "Build dependency graph — identify task ordering, parallel opportunities, and blocking dependencies.",
45
45
  "Group tasks into dependency batches — batch N+1 cannot start until batch N has verification evidence.",
46
- "Slice into vertical tasks — each task targets 2-5 minutes, produces one testable outcome, and touches one coherent area.",
47
- "Task Contract — every task has one coherent outcome, AC mapping, exact verification command/manual step, and expected evidence snippet or pass condition. Avoid vague `run tests` wording.",
46
+ "Slice into implementation units — each unit is feature-atomic and testable end-to-end, with internal 2-5 minute RED/GREEN/REFACTOR steps. Use `strict-micro` only for high-risk or explicitly requested micro-slice execution.",
47
+ "Task Contract — every unit has one coherent outcome, AC mapping, exact verification command/manual step, and expected evidence snippet or pass condition. Internal steps may be `T-NNN` rows, but they are not automatically separate schedulable agents in balanced/fast mode.",
48
48
  "Annotate slice-review metadata — task rows may carry `touchCount` (rough number of files expected to change), `touchPaths` (glob hints, e.g. `migrations/**`, `src/auth/**`), and optional `highRisk: true` to force a review pass. These fields feed the TDD stage's Per-Slice Review point.",
49
49
  "For every `### Implementation Unit U-<n>`, declare parallel metadata bullets: `id`, `dependsOn` (unit ids or `none`), `claimedPaths` (repo-relative), `parallelizable` (true|false), `riskTier` (low|standard|high), optional `lane` — used for conflict-aware wave plans and schedulers.",
50
50
  "Map scope Locked Decisions — every D-XX ID from scope is referenced by at least one plan task (or explicitly marked deferred with reason).",
51
51
  "Run anti-placeholder + anti-scope-reduction scans — block `TODO/TBD/...` and phrasing like `v1`, `for now`, `later` for locked boundaries.",
52
52
  "Define validation points — mark where progress must be checked before continuing, with concrete command and expected evidence.",
53
- "Define execution posture — record whether execution should be sequential, dependency-batched, parallel-safe, or blocked; include risk triggers and RED/GREEN/REFACTOR checkpoint/commit expectations when the repo workflow supports them. This fulfills the `plan_execution_posture_recorded` gate.",
54
- "**Author the FULL Parallel Execution Plan.** Inside the `<!-- parallel-exec-managed-start -->` block, enumerate ALL waves W-02..W-N covering EVERY T-NNN task in `## Task List` no `we'll author waves later`, `next batch only`, or open-ended Backlog handwave is acceptable. Each task gets a slice with `sliceId | taskId | dependsOn | claimedPaths | parallelizable | riskTier | lane`. Spike rows (`S-N`) and tasks marked `deferred` in an explicit `Deferred:` column may be omitted, but every other T-NNN must be claimed. This fulfills the `plan_parallel_exec_full_coverage` gate. The TDD stage downstream is a pure consumer of these waves — if the plan does not author them, TDD cannot fan out that work.",
55
- "After authoring/refreshing the managed parallel-exec block, render a Mermaid `flowchart` or `gantt` covering waves (`W-*`) and slice dependencies (`S-*`) so parallelism and fan-in boundaries are visually auditable.",
53
+ "Define execution topology — record `execution.topology` (`auto|inline|single-builder|parallel-builders|strict-micro`), `execution.strictness` (`fast|balanced|strict`), `execution.maxBuilders`, `plan.sliceGranularity`, `plan.microTaskPolicy`, stop conditions, and RED/GREEN/REFACTOR checkpoint/commit expectations. Default posture is `auto` + `balanced`: choose the cheapest safe route, not the most parallel one.",
54
+ "**Author the FULL Parallel Execution Plan.** Inside the `<!-- parallel-exec-managed-start -->` block, enumerate all waves W-01..W-N covering every feature-atomic `U-*` implementation unit/slice. Legacy strict-micro plans may cover each non-deferred `T-NNN` task instead. Each row carries `unit|sliceId | dependsOn | claimedPaths | parallelizable | riskTier | lane`. Do not leave `we'll author waves later`, `next batch only`, or open-ended Backlog handwaves. This fulfills the `plan_parallel_exec_full_coverage` gate. The TDD stage downstream is a pure consumer of these waves — if the plan does not author them, TDD cannot fan out that work.",
55
+ "After authoring/refreshing the managed parallel-exec block, render a Mermaid `flowchart` or `gantt` covering waves (`W-*`) and unit/slice dependencies (`U-*`/`S-*`) so topology and fan-in boundaries are visually auditable.",
56
56
  "WAIT_FOR_CONFIRM — write plan artifact and explicitly pause. **STOP.** Do NOT proceed until user confirms. Then close the stage with `node .cclaw/hooks/stage-complete.mjs plan` and tell user to run `/cc`."
57
57
  ],
58
58
  interactionProtocol: [
59
59
  "Plan in read-only mode relative to implementation.",
60
- "Split work into small vertical slices (target 2-5 minute tasks).",
60
+ "Split work into feature-atomic vertical units; place 2-5 minute TDD steps inside each unit.",
61
61
  "Publish explicit dependency batches with entry and exit checks for each batch.",
62
62
  "Expose execution posture: sequential vs batch/parallel, stop conditions, and checkpoint cadence for the TDD handoff.",
63
63
  "Keep same-wave `claimedPaths` disjoint; if overlap exists, split waves or serialize explicitly before handoff.",
@@ -79,18 +79,18 @@ export const PLAN = {
79
79
  "Write plan artifact and pause at WAIT_FOR_CONFIRM."
80
80
  ],
81
81
  requiredGates: [
82
- { id: "plan_tasks_sliced_2_5_min", description: "Tasks are small, executable slices." },
82
+ { id: "plan_tasks_sliced_2_5_min", description: "Implementation units are feature-atomic and contain internal 2-5 minute TDD steps; strict micro-slices are explicit." },
83
83
  { id: "plan_dependency_batches_defined", description: "Tasks are grouped into executable batches with gate checks and execution posture." },
84
84
  { id: "plan_acceptance_mapped", description: "Each task maps to a spec acceptance criterion." },
85
- { id: "plan_execution_posture_recorded", description: "Execution posture is recorded before implementation handoff." },
86
- { id: "plan_parallel_exec_full_coverage", description: "Every T-NNN task in `## Task List` (other than spikes/explicitly-deferred) is assigned to at least one slice inside the `<!-- parallel-exec-managed-start -->` block; TDD cannot fan out work that the plan never authored as waves." },
85
+ { id: "plan_execution_posture_recorded", description: "Execution topology/posture is recorded before implementation handoff." },
86
+ { id: "plan_parallel_exec_full_coverage", description: "Every U-* implementation unit/slice (or every T-NNN task in explicit strict-micro plans) is assigned inside the `<!-- parallel-exec-managed-start -->` block; TDD cannot fan out work that the plan never authored as waves." },
87
87
  { id: "plan_wave_paths_disjoint", description: "Within each authored wave, slice `claimedPaths` remain disjoint so `wave-fanout` can dispatch safely without overlap conflicts." },
88
88
  { id: "plan_module_introducing_slice_wires_root", description: "When a slice introduces a new module file, the stack-adapter's wiring aggregator (Rust `lib.rs`, Python `__init__.py`, Node-TS barrel when present) must appear in the same slice's claim or a transitive predecessor's claim so RED can be expressed." },
89
89
  { id: "plan_wait_for_confirm", description: "Execution blocked until explicit user confirmation." }
90
90
  ],
91
91
  requiredEvidence: [
92
92
  "Artifact written to `.cclaw/artifacts/05-plan.md`.",
93
- "Task list includes acceptance mapping, exact verification command/manual step, and expected evidence/pass condition.",
93
+ "Implementation units include acceptance mapping, internal 2-5 minute TDD steps, exact verification command/manual step, and expected evidence/pass condition.",
94
94
  "Locked decision coverage table present with D-XX trace links.",
95
95
  "Dependency graph documented.",
96
96
  "Dependency batches documented with batch-by-batch verification gates.",
@@ -136,13 +136,13 @@ export const PLAN = {
136
136
  { section: "Upstream Handoff", required: false, validationRule: "Summarizes spec/design/scope decisions, constraints, open questions, and explicit drift before task breakdown." },
137
137
  { section: "Dependency Graph", required: false, validationRule: "Ordering and parallel opportunities explicit. No circular dependencies." },
138
138
  { section: "Dependency Batches", required: true, validationRule: "Every task belongs to a batch. Each batch has an exit gate and dependency statement." },
139
- { section: "Task List", required: true, validationRule: "Each task row includes ID, description, acceptance criterion, exact verification command/manual step, expected evidence/pass condition, and effort estimate (S/M/L). Every task must also carry a minutes estimate within the 2-5 minute budget. When present, touchCount/touchPaths/highRisk metadata drives Per-Slice Review escalation in TDD." },
139
+ { section: "Task List", required: true, validationRule: "Task rows may describe internal 2-5 minute TDD steps. In balanced/fast mode, the schedulable unit is the feature-atomic Implementation Unit, not every T-NNN row. Strict-micro plans may still use one T-NNN per slice." },
140
140
  { section: "Acceptance Mapping", required: true, validationRule: "Every spec criterion is covered by at least one task." },
141
- { section: "Execution Posture", required: true, validationRule: "States sequential/batch/parallel posture, stop conditions, risk triggers, and RED/GREEN/REFACTOR checkpoint or commit expectations for TDD when consistent with the repo workflow." },
141
+ { section: "Execution Posture", required: true, validationRule: "States `execution.topology` (`auto|inline|single-builder|parallel-builders|strict-micro`), `execution.strictness`, `execution.maxBuilders`, `plan.sliceGranularity`, `plan.microTaskPolicy`, stop conditions, risk triggers, and RED/GREEN/REFACTOR checkpoint or commit expectations for TDD when consistent with the repo workflow." },
142
142
  { section: "Locked Decision Coverage", required: false, validationRule: "Every locked decision ID (D-XX) from scope is listed with linked task IDs or explicit defer rationale." },
143
143
  { section: "Risk Assessment", required: false, validationRule: "If present: per-task or per-batch risk identification with likelihood, impact, and mitigation strategy." },
144
144
  { section: "Boundary Map", required: false, validationRule: "If present: per-batch or per-task interface contracts listing what each task produces (exports) and consumes (imports) from other tasks." },
145
- { section: "Implementation Units", required: false, validationRule: "If present: each `### Implementation Unit U-<n>` includes Goal, Files, Approach, Test scenarios, Verification fields, plus bullets (`id`, `dependsOn`, `claimedPaths`, `parallelizable`, `riskTier`, optional `lane`)." },
145
+ { section: "Implementation Units", required: false, validationRule: "Each `### Implementation Unit U-<n>` includes Goal, Files, Approach, Test scenarios, Verification, internal 2-5 minute TDD steps, plus bullets (`id`, `dependsOn`, `claimedPaths`, `parallelizable`, `riskTier`, optional `lane`)." },
146
146
  { section: "Calibrated Findings", required: false, validationRule: "If present: either `None this stage` or one or more lines in `[P1|P2|P3] (confidence: <n>/10) <path>[:<line>] — <description>` format." },
147
147
  { section: "Regression Iron Rule", required: false, validationRule: "If present: includes `Iron rule acknowledged: yes`." },
148
148
  { section: "WAIT_FOR_CONFIRM", required: true, validationRule: "Explicit marker present. Status: pending until user approves." },
@@ -156,7 +156,7 @@ export const PLAN = {
156
156
  title: "Task Decomposition Audit",
157
157
  evaluationPoints: [
158
158
  "Does every task target a single coherent area (vertical slice)?",
159
- "Can each task be completed in 2-5 minutes?",
159
+ "Is each implementation unit feature-atomic, with internal steps that fit 2-5 minutes each?",
160
160
  "Does every task have an acceptance criterion link, exact verification command/manual step, and expected evidence/pass condition?",
161
161
  "Are there tasks that touch multiple unrelated areas?",
162
162
  "Would a new engineer understand and start each task within two minutes?"
@@ -178,7 +178,7 @@ export const PLAN = {
178
178
  {
179
179
  title: "Five-Minute Budget + No-Placeholders Audit",
180
180
  evaluationPoints: [
181
- "Does every task carry an explicit minutes estimate (e.g. `[~3m]`) and does every estimate fit the 2-to-5-minute budget? Estimates >5 minutes must be split.",
181
+ "Does every internal TDD step carry a bounded 2-to-5-minute estimate or checkbox-level step? Whole units may be larger when feature-atomic.",
182
182
  "Are all file paths, test commands, verification commands, and expected evidence copy-pasteable/specific as written — no `TODO`, `TBD`, `FIXME`, `<fill-in>`, `<your-*-here>`, `xxx`, bare `run tests`, or ellipsis standing in for omitted args?",
183
183
  "Does every acceptance-criterion reference resolve to a real R# / AC-### in the spec (not a blank link)?",
184
184
  "If an estimate is genuinely uncertain (first-time integration, unfamiliar library), is the uncertainty named explicitly and scheduled as a spike task in batch 0, rather than hidden behind a large estimate?"
@@ -8,7 +8,7 @@ export const TDD = {
8
8
  complexityTier: "standard",
9
9
  skillFolder: "tdd",
10
10
  skillName: "tdd",
11
- skillDescription: "Full vertical-slice TDD cycle: discover existing tests and system impact, then RED (failing tests), GREEN (minimal implementation), REFACTOR (cleanup). One source item at a time with strict traceability.",
11
+ skillDescription: "Adaptive vertical-slice TDD cycle: route each feature-atomic implementation unit through inline, single-builder, parallel-builder, or strict-micro execution while preserving RED-first traceability.",
12
12
  philosophy: {
13
13
  hardGate: "Do NOT merge, ship, or skip review. Follow RED → GREEN → REFACTOR strictly for each plan slice. Do NOT write implementation code before RED tests exist. Do NOT write RED tests before discovering relevant existing tests and impacted contracts. Do NOT skip the REFACTOR step.",
14
14
  ironLaw: "NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST — THE RED FAILURE IS THE SPEC.",
@@ -37,19 +37,21 @@ export const TDD = {
37
37
  },
38
38
  executionModel: {
39
39
  checklist: [
40
- "**Wave discovery:** Entering TDD, first call `node .cclaw/cli.mjs internal wave-status --json`. It parses the managed `<!-- parallel-exec-managed-start -->` block; read `05-plan.md`/`wave-plans/` only once `wave-status` names work. Restore partial waves by parallelizing remaining members.",
41
- "**Routing AskQuestion:** Two or more ready slices exactly one AskQuestion (“launch wave …” vs single slice …”, default wave). Otherwise do not ask “which slice next?” when the plan already resolves it.",
40
+ "**Wave discovery:** Entering TDD, first call `node .cclaw/cli.mjs internal wave-status --json`. It parses the managed `<!-- parallel-exec-managed-start -->` block and reports the adaptive `topology`; read `05-plan.md`/`wave-plans/` only once `wave-status` names work. Restore partial waves by resuming remaining units.",
41
+ "**Topology routing:** Default `auto` + `balanced` means cheapest safe route: inline for one low-risk inline-safe unit, single-builder for one feature-atomic unit or conflicts, parallel-builders only for genuinely independent substantial units, strict-micro for high-risk/configured micro-slice work.",
42
+ "**Routing AskQuestion:** Two or more ready units with `topology=parallel-builders` ⇒ exactly one AskQuestion (“launch wave …” vs “single builder …”, default wave). Otherwise do not ask “which slice next?” when the plan already resolves it.",
42
43
  "**Record before dispatch:** For every `Task`, write `delegation-record` `--status=scheduled` then `--status=launched` before the tool call. Workers self-record `acknowledged` and `completed`; back-fill is `--repair` only.",
43
- "**One worker per slice:** Dispatch `slice-builder` with `--slice S-<id>` and explicit `--paths` from the plan. Parallel builders are allowed when paths are disjoint; honor any lane/lease flags the hook requires today.",
44
- "**Single span owns the slice:** `slice-builder` runs RED GREEN REFACTOR (separate phase rows or `--refactor-outcome` on GREEN) and authors `<artifacts-dir>/tdd-slices/S-<id>.md`. Follow the agent body and `delegation-record` snippets it embeds.",
45
- "**Wave closure:** When every slice in the wave has GREEN + REFACTOR coverage, call `integrationCheckRequired`. Dispatch `integration-overseer` when required; otherwise emit `cclaw_integration_overseer_skipped` via `delegation-record --audit-kind=...`.",
44
+ "**One worker per feature-atomic unit when delegated:** Dispatch `slice-builder` with `--slice S-<id>` and explicit `--paths` from the plan. The worker owns the unit's internal 2-5 minute RED/GREEN/REFACTOR steps. Parallel builders are allowed only when topology says `parallel-builders` and paths are disjoint; honor any lane/lease flags the hook requires today.",
45
+ "**Inline topology:** When the router/guidance chooses `inline`, the controller may execute the unit without a builder dispatch, but must still keep RED-before-GREEN, AC traceability, path containment, verification-before-completion, lockfile twin handling, managed commit/worktree policy, and orphan-change gates intact.",
46
+ "**Single span owns the delegated unit:** `slice-builder` runs RED GREEN REFACTOR (separate phase rows or `--refactor-outcome` on GREEN) and authors `<artifacts-dir>/tdd-slices/S-<id>.md`. Follow the agent body and `delegation-record` snippets it embeds.",
47
+ "**Wave closure:** When every slice/unit in the wave has GREEN + REFACTOR coverage, call `integrationCheckRequired`. Dispatch `integration-overseer` when required; otherwise emit `cclaw_integration_overseer_skipped` via `delegation-record --audit-kind=...`.",
46
48
  "**Plan triggers:** If the unit row demands extra scrutiny (`touchCount >= filesChangedThreshold`, matching `touchPaths`, or `highRisk`), capture that review posture in `tdd-slices/S-<id>.md` or via a reviewer dispatch before closing the slice.",
47
49
  "**Auto-render tables:** Do not hand-edit content between `auto-start: tdd-slice-summary` markers; the linter overwrites them from `delegation-events.jsonl`.",
48
50
  "**Active-span collisions:** If scheduling fails with `dispatch_duplicate` / `dispatch_active_span_collision`, identify the live span; use `--allow-parallel` or `--supersede` deliberately. Do not silence errors blindly.",
49
51
  ],
50
52
  interactionProtocol: [
51
- "Parallel `slice-builder` tasks are allowed when `claimedPaths` are disjoint; remain serial when the plan orders dependencies.",
52
- "Controller never writes production code or per-slice prose the delegated worker does. Record routing decisions; cite `wave-status` before redundant slice questions.",
53
+ "Parallel `slice-builder` tasks are allowed only when topology is `parallel-builders` and `claimedPaths` are disjoint; remain serial for dependencies, conflicts, high-risk units, or strict-micro chains.",
54
+ "Controller normally orchestrates delegated builders. In `inline` topology it may execute directly, but must record the routing decision and satisfy the same RED/GREEN/REFACTOR evidence gates before completion.",
53
55
  "Discover existing tests and commands before RED; run a system-wide impact check (callbacks, state, interfaces, contracts) before GREEN.",
54
56
  "RED must fail for the right reason; capture logs. GREEN must run the full relevant suite, not a narrow subset.",
55
57
  "Before calling a slice done, run verification-before-completion (command + PASS/FAIL + durable commit evidence: managed-per-slice git commits when `.git` is present, or explicit no-VCS attestation + hash).",
@@ -59,8 +61,9 @@ export const TDD = {
59
61
  process: [
60
62
  "Map the slice to acceptance criteria; read `ralph-loop.json` for open RED cycles before starting new work.",
61
63
  "Discover tests, fixtures, helpers, and commands; record impact on public surfaces.",
62
- "Dispatch `slice-builder` for RED (failing tests, no production edits beyond test files).",
63
- "Dispatch the same builder for GREEN with minimal production changes and full-suite evidence.",
64
+ "Route the active unit via topology (`inline`, `single-builder`, `parallel-builders`, or `strict-micro`) before RED.",
65
+ "For delegated units, dispatch `slice-builder` for RED (failing tests, no production edits beyond test files).",
66
+ "For delegated units, dispatch the same builder for GREEN with minimal production changes and full-suite evidence.",
64
67
  "Close REFACTOR inline, via deferred phase, or `--refactor-outcome` on GREEN — match what `delegation-record` expects.",
65
68
  "Keep `tdd-slices/S-<id>.md` aligned with evidence as the builder finishes.",
66
69
  "Run fresh verification and attach traceability (plan task + spec criterion).",
@@ -117,9 +117,9 @@ If during any stage the agent discovers evidence that contradicts the initial Ph
117
117
  4. Otherwise check current stage gates, resume if incomplete, and advance if complete.
118
118
  5. **TDD wave dispatch:** When \`currentStage\` is \`tdd\`, run \`node .cclaw/cli.mjs internal wave-status --json\` first, then read the managed **Parallel Execution Plan** block inside \`${RUNTIME_ROOT}/artifacts/05-plan.md\` plus \`${RUNTIME_ROOT}/artifacts/wave-plans/\` for detail. Resume partial waves on remaining members only.
119
119
 
120
- **The controller never edits production code in TDD.** When \`mode: wave-fanout\` and \`pathConflicts: []\`, fan out the entire wave in a SINGLE controller message: one harness \`Task(subagent_type=…, description="slice-builder S-<id>", prompt=<full slice context>)\` call per ready slice, **side by side in the same tool batch**. Each \`slice-builder\` span owns the full RED → GREEN → REFACTOR → DOC cycle for its slice and emits its own \`delegation-record --phase=red|green|refactor|refactor-deferred|doc\` rows. RED-before-GREEN is enforced per-slice by the linter.
120
+ **The controller preserves TDD evidence.** When \`topology: parallel-builders\` and \`pathConflicts: []\`, fan out the ready independent units in a SINGLE controller message: one harness \`Task(subagent_type=…, description="slice-builder S-<id>", prompt=<full slice context>)\` call per routed builder, **side by side in the same tool batch**. Each \`slice-builder\` span owns the full RED → GREEN → REFACTOR → DOC cycle for its feature-atomic unit and emits its own \`delegation-record --phase=red|green|refactor|refactor-deferred|doc\` rows. RED-before-GREEN is enforced per-slice by the linter.
121
121
 
122
- When \`mode: blocked\` with \`pathConflicts\`, surface exactly one AskQuestion that lets the user resolve the overlap (drop / split / serialize). When \`mode: single-slice\`, dispatch one \`Task\` for the next ready slice.
122
+ When \`mode: blocked\` with \`pathConflicts\`, surface exactly one AskQuestion that lets the user resolve the overlap (drop / split / serialize). When \`topology: single-builder\`, dispatch one \`Task\` for the next ready unit. When \`topology: inline\`, execute inline only if the same RED/GREEN/REFACTOR evidence and path/commit gates can be satisfied.
123
123
 
124
124
  6. **Auto-advance after stage-complete:** when \`stage-complete\` returns \`ok\` with a new \`currentStage\`, immediately load the next stage skill and continue without waiting for the user to retype \`/cc\`. Announce \`Stage <prev> complete → entering <next>. Continuing.\` and proceed.
125
125
 
@@ -214,7 +214,7 @@ Progress the tracked flow only when one exists:
214
214
  2. If missing, guide the user to run \`npx cclaw-cli init\` and stop.
215
215
  3. If it is only a fresh init placeholder (\`completedStages: []\`, no passed gates, and no \`${RUNTIME_ROOT}/artifacts/00-idea.md\`), stop and ask for \`/cc <prompt>\` to start a tracked run. Do not silently create a brainstorm run.
216
216
  4. Check gates for \`currentStage\`.
217
- 5. **TDD:** When \`currentStage\` is \`tdd\`, run \`wave-status --json\`, then reconcile the managed **Parallel Execution Plan** in \`05-plan.md\` with \`wave-plans/wave-NN.md\`. **The controller never edits production code in TDD.** When \`mode: wave-fanout\` and \`pathConflicts: []\`, fan out the wave in a SINGLE controller message — one \`Task\` per ready slice, side by side. If \`mode: blocked\`, resolve overlaps first. Each \`slice-builder\` span owns its full RED → GREEN → REFACTOR → DOC cycle. Mirror plan \`dependsOn\` ordering between waves.
217
+ 5. **TDD:** When \`currentStage\` is \`tdd\`, run \`wave-status --json\`, then reconcile the managed **Parallel Execution Plan** in \`05-plan.md\` with \`wave-plans/wave-NN.md\`. Route by \`nextDispatch.topology\`: \`parallel-builders\` fans out independent units in one controller message, \`single-builder\` dispatches one builder, \`inline\` executes directly only with equivalent evidence, and \`strict-micro\` preserves tiny-slice sequencing. If \`mode: blocked\`, resolve overlaps first. Each delegated \`slice-builder\` span owns its full RED → GREEN → REFACTOR → DOC cycle. Mirror plan \`dependsOn\` ordering between waves.
218
218
  6. **Wave resume:** Parallelize unfinished members; never restart completed lanes. Integration-overseer follows \`integrationCheckRequired\`; when skipped, emit \`cclaw_integration_overseer_skipped\` per the hook contract.
219
219
  7. If incomplete → load current stage skill and execute.
220
220
  8. If complete → advance to next stage and execute. **Auto-advance:** when \`stage-complete\` returns \`ok\`, immediately load the next stage skill and continue without waiting for the user to retype \`/cc\`.
@@ -10,7 +10,7 @@ function skillFrontmatter(name, description) {
10
10
  function tddCycleEvidenceSkill() {
11
11
  return `${skillFrontmatter("tdd-cycle-evidence", "Evidence contract for the mandatory slice-builder delegation across RED/GREEN/REFACTOR/DOC.")}# TDD Cycle Evidence
12
12
 
13
- Use with the \`slice-builder\` delegation in the \`tdd\` stage. One \`slice-builder\` span owns the full cycle for a single vertical slice.
13
+ Use with the \`slice-builder\` delegation in the \`tdd\` stage. One \`slice-builder\` span owns the full cycle for a feature-atomic implementation unit/slice, including its internal 2-5 minute TDD steps.
14
14
 
15
15
  ## Required Output
16
16
 
@@ -25,7 +25,7 @@ Use with the \`slice-builder\` delegation in the \`tdd\` stage. One \`slice-buil
25
25
  - No production code before RED evidence exists.
26
26
  - If a RED test cannot be expressed, stop and route back to design/spec with the blocker.
27
27
  - Record command output summaries, not just "tests passed".
28
- - Multiple \`slice-builder\` spans run in parallel inside one wave only when their \`claimedPaths\` are disjoint.
28
+ - Multiple \`slice-builder\` spans run in parallel inside one wave only when topology is \`parallel-builders\` and their \`claimedPaths\` are disjoint. \`strict-micro\` keeps tiny tasks separate; \`inline\` skips delegation but not RED/GREEN/REFACTOR evidence.
29
29
  `;
30
30
  }
31
31
  function reviewSpecPassSkill() {
@@ -37,7 +37,7 @@ description: "Orchestrate implementation via isolated subagents — one fresh ag
37
37
  Use a **controller -> coder -> overseer** loop when building multi-step software work.
38
38
 
39
39
  - **Controller (parent agent):** owns the plan, gating, sequencing, and dispatch decisions; never mixes deep implementation context with review evidence.
40
- - **Coder / slice-builder (subagent):** receives a **single self-contained task** and edits code only within that scope; exits with a structured status contract.
40
+ - **Coder / slice-builder (subagent):** receives a **single feature-atomic implementation unit/slice** and edits code only within that scope; exits with a structured status contract.
41
41
  - **Overseer / reviewer (subagent):** validates outputs against the specification **by reading code** and never edits during the overseer pass.
42
42
 
43
43
  This pattern is intentionally **Superpowers-style**: cheap parallelism where it doesn’t corrupt state, strict serialization where it would.
@@ -62,7 +62,7 @@ Reconcile findings into \`.cclaw/artifacts/07-review-army.json\` with explicit s
62
62
 
63
63
  ### TDD evidence protocol
64
64
 
65
- Each parallel slice runs end-to-end inside one \`slice-builder\` delegation, with RED, GREEN, REFACTOR, and per-slice DOC as phase intents on a single span:
65
+ Each delegated feature-atomic slice runs end-to-end inside one \`slice-builder\` delegation, with RED, GREEN, REFACTOR, and per-slice DOC as phase intents on a single span. The slice may contain internal 2-5 minute TDD steps; \`strict-micro\` is the explicit mode for one tiny task per slice:
66
66
 
67
67
  - \`--phase red\`: failing tests only, no production writes
68
68
  - \`--phase green\`: minimal production implementation that passes the matching RED
@@ -70,7 +70,7 @@ Each parallel slice runs end-to-end inside one \`slice-builder\` delegation, wit
70
70
  - \`--phase doc\`: write \`<artifacts-dir>/tdd-slices/S-<id>.md\` for the slice
71
71
 
72
72
  Set \`CCLAW_ACTIVE_AGENT\` to the active phase name when possible so workflow-guard
73
- can enforce phase-appropriate write boundaries. The mandatory gate is the evidence-backed \`slice-builder\` row, not multiple default subagents.
73
+ can enforce phase-appropriate write boundaries. The mandatory gate is the evidence-backed \`slice-builder\` row for delegated topologies, not multiple default subagents. When TDD topology is \`inline\`, the controller may skip the builder but must preserve the same RED-before-GREEN, AC traceability, path containment, verification, managed commit/worktree, lockfile twin, and orphan-change gates.
74
74
 
75
75
  ## Model & Harness Routing Notes
76
76
 
@@ -154,7 +154,7 @@ If you catch yourself writing “read PLAN.md Task 3” or “implement the next
154
154
  Borrow the good part of Team/Ruflo-style orchestration without adding a swarm runtime:
155
155
 
156
156
  - **One controller owns alignment.** The parent keeps the task list, gate state, and final synthesis.
157
- - **Small fan-out by default.** Run at most 3-5 parallel agents, and only for independent read-only research or non-overlapping files.
157
+ - **Small fan-out by topology.** Run at most configured \`maxBuilders\` parallel builders, and only for independent substantial units or independent read-only research/review lenses.
158
158
  - **No parallel writes to adjacent surfaces.** If tasks may touch the same module, serialize them.
159
159
  - **Checkpoint before synthesis.** Each agent returns status, files inspected/changed, evidence, and blockers before the parent acts.
160
160
  - **Consensus is for hard calls only.** Use two reviewers when severity or architecture is disputed; otherwise one evidence-backed reviewer is enough.
@@ -177,7 +177,7 @@ Before parallel dispatch, answer yes to all gates: tasks are independent, write
177
177
  - Copy each task verbatim into a working queue (checklist is fine).
178
178
  - Normalize each task so it includes: goal, acceptance criteria, constraints, and explicit “out of scope.”
179
179
 
180
- 2. **For each tasksequential by default; parallel only with cohesion controls:**
180
+ 2. **For each unitcheapest safe topology first; parallel only with cohesion controls:**
181
181
  - Implementation subagents are sequential by default. Parallel implementers
182
182
  are allowed only when ALL three conditions hold:
183
183
  - (a) the lanes touch non-overlapping files (verify via the plan's task
@@ -397,7 +397,7 @@ This document bridges **Superpowers-style task isolation** with the **gstack “
397
397
  ${conversationLanguagePolicyMarkdown()}
398
398
  **Default rule:** parallel implementation agents are SAFE for investigation, analysis, review, and the **TDD wave-fanout** path; otherwise keep implementation sequential.
399
399
 
400
- **TDD wave-fanout is the supported parallel-implementation path.** When \`cclaw-cli internal wave-status --json\` reports \`mode: wave-fanout\` and \`pathConflicts: []\`, fan out one \`slice-builder\` span per ready slice in a single controller message. Each span owns its disjoint \`claimedPaths\`; the dispatcher rejects overlapping spans with \`DispatchOverlapError\` inline, so the disjoint-paths invariant is enforced for you.
400
+ **TDD wave-fanout is the supported parallel-implementation path.** When \`cclaw-cli internal wave-status --json\` reports \`topology: parallel-builders\` and \`pathConflicts: []\`, fan out one \`slice-builder\` span per ready feature-atomic unit/slice in a single controller message, capped by \`maxBuilders\`. Each span owns its disjoint \`claimedPaths\`; the dispatcher rejects overlapping spans with \`DispatchOverlapError\` inline, so the disjoint-paths invariant is enforced for you.
401
401
 
402
402
  **Outside wave-fanout** — for ad-hoc parallel implementation that touches shared source trees — keep work **sequential** unless you have proven disjoint filesystem ownership and an explicit merge protocol.
403
403
 
@@ -868,7 +868,7 @@ Execution rule: complete and verify each batch before starting the next batch.
868
868
  ## Task List
869
869
 
870
870
  **Rules (apply before writing rows):**
871
- - Every task fits the **2-5 minute budget**. If \`[~Nm]\` is >5, split the task.
871
+ - Task rows are internal TDD steps unless \`Execution Topology\` is \`strict-micro\`. Keep each step in the **2-5 minute budget**; group related steps into feature-atomic \`U-*\` Implementation Units.
872
872
  - **No placeholders.** Forbidden tokens anywhere in this table: \`TODO\`, \`TBD\`, \`FIXME\`, \`<fill-in>\`, \`<your-*-here>\`, \`xxx\`, bare ellipsis. Every file path, test, and verification command must be copy-pasteable as written.
873
873
  - **No silent scope reduction.** Forbidden phrasing when locked decisions exist: \`v1\`, \`for now\`, \`later\`, \`temporary\`, \`placeholder\`, \`mock for now\`, \`hardcoded for now\`, \`will improve later\`.
874
874
  - If an estimate is genuinely uncertain (new library, unfamiliar subsystem), add a **spike task in batch 0** to de-risk — do NOT hide the uncertainty inside a large estimate.
@@ -883,7 +883,12 @@ Execution rule: complete and verify each batch before starting the next batch.
883
883
  | AC-1 | T-1 |
884
884
 
885
885
  ## Execution Posture
886
- - Posture: sequential | dependency-batched | parallel-safe | blocked
886
+ - execution.topology: auto | inline | single-builder | parallel-builders | strict-micro
887
+ - execution.strictness: fast | balanced | strict
888
+ - execution.maxBuilders: 5
889
+ - plan.sliceGranularity: feature-atomic | strict-micro
890
+ - plan.microTaskPolicy: advisory | strict
891
+ - Posture rationale: (why this is the cheapest safe topology)
887
892
  - Stop conditions:
888
893
  - Risk triggers:
889
894
  - TDD checkpoint plan: RED commit/checkpoint -> GREEN commit/checkpoint -> REFACTOR commit/checkpoint (or deferred because: )
@@ -904,7 +909,7 @@ Execution rule: complete and verify each batch before starting the next batch.
904
909
  | | | |
905
910
 
906
911
  ## Implementation Units
907
- > Required structural form per implementation unit. Use ≥1 unit; bite-sized 2-5 minute steps inside each. The linter validates shape, not topic.
912
+ > Required structural form per implementation unit. Default is feature-atomic units with bite-sized 2-5 minute TDD steps inside each. Use strict micro-slices only for high-risk work or when explicitly configured.
908
913
 
909
914
  ### Implementation Unit U-1
910
915
  - **id:** U-1
@@ -947,10 +952,10 @@ Execution rule: complete and verify each batch before starting the next batch.
947
952
  - Required pre-merge proof:
948
953
 
949
954
  ## Execution Handoff
950
- - **Posture chosen:** Subagent-Driven (recommended) | Inline executor
951
- - **Why this posture:** (one line tying choice to plan size, parallelism, novelty)
952
- - **Subagent recipe (if Subagent-Driven):** \`<harness>\` -> \`<dispatch surface>\` -> \`<agent-definition path>\` (substitute neutral placeholders; full recipes in \`docs/harnesses.md\`)
953
- - **Inline recipe (if Inline executor):** TDD loop unit-by-unit with batch checkpoints
955
+ - **Topology chosen:** execution.topology = auto | inline | single-builder | parallel-builders | strict-micro
956
+ - **Why this topology:** (one line tying choice to unit count, path independence, risk, and maxBuilders)
957
+ - **Subagent recipe (if single/parallel builder):** \`<harness>\` -> \`<dispatch surface>\` -> \`<agent-definition path>\` (substitute neutral placeholders; full recipes in \`docs/harnesses.md\`)
958
+ - **Inline recipe (if inline):** TDD loop unit-by-unit with the same RED-before-GREEN, AC traceability, path containment, verification, and managed commit/worktree gates
954
959
 
955
960
  ## Plan Quality Scan
956
961
  <!-- linter-meta -->
@@ -330,8 +330,9 @@ export declare class DispatchOverlapError extends Error {
330
330
  /**
331
331
  * Thrown when the count of active `slice-builder` spans reaches
332
332
  * `MAX_PARALLEL_SLICE_BUILDERS` and a new scheduled row would push it past
333
- * the cap. Cap can be overridden once via `--override-cap=N` on the hook
334
- * flag or globally via `CCLAW_MAX_PARALLEL_SLICE_BUILDERS=<N>` env.
333
+ * the cap. Cap can be configured via `.cclaw/config.yaml::execution.maxBuilders`,
334
+ * overridden once via `--override-cap=N` on the hook flag, or globally via
335
+ * `CCLAW_MAX_PARALLEL_SLICE_BUILDERS=<N>` env.
335
336
  */
336
337
  export declare class DispatchCapError extends Error {
337
338
  readonly cap: number;
@@ -536,7 +537,7 @@ export declare function validateFileOverlap(stamped: DelegationEntry, activeEntr
536
537
  };
537
538
  /**
538
539
  * Enforce the slice-builder fan-out cap. The new scheduled row pushes the
539
- * active count from N to N+1; if that would exceed the cap (default 5,
540
+ * active count from N to N+1; if that would exceed the cap (default/config 5,
540
541
  * env-overridable via `CCLAW_MAX_PARALLEL_SLICE_BUILDERS`), throw
541
542
  * `DispatchCapError`.
542
543
  *
@@ -3,7 +3,7 @@ import path from "node:path";
3
3
  import { execFile } from "node:child_process";
4
4
  import { promisify } from "node:util";
5
5
  import { RUNTIME_ROOT } from "./constants.js";
6
- import { readConfig } from "./config.js";
6
+ import { readConfig, resolveMaxBuilders } from "./config.js";
7
7
  import { exists, withDirectoryLock, writeFileSafe } from "./fs-utils.js";
8
8
  import { HARNESS_ADAPTERS } from "./harness-adapters.js";
9
9
  import { readFlowState } from "./runs.js";
@@ -616,8 +616,9 @@ export class DispatchOverlapError extends Error {
616
616
  /**
617
617
  * Thrown when the count of active `slice-builder` spans reaches
618
618
  * `MAX_PARALLEL_SLICE_BUILDERS` and a new scheduled row would push it past
619
- * the cap. Cap can be overridden once via `--override-cap=N` on the hook
620
- * flag or globally via `CCLAW_MAX_PARALLEL_SLICE_BUILDERS=<N>` env.
619
+ * the cap. Cap can be configured via `.cclaw/config.yaml::execution.maxBuilders`,
620
+ * overridden once via `--override-cap=N` on the hook flag, or globally via
621
+ * `CCLAW_MAX_PARALLEL_SLICE_BUILDERS=<N>` env.
621
622
  */
622
623
  export class DispatchCapError extends Error {
623
624
  cap;
@@ -1111,7 +1112,7 @@ export function validateFileOverlap(stamped, activeEntries) {
1111
1112
  }
1112
1113
  /**
1113
1114
  * Enforce the slice-builder fan-out cap. The new scheduled row pushes the
1114
- * active count from N to N+1; if that would exceed the cap (default 5,
1115
+ * active count from N to N+1; if that would exceed the cap (default/config 5,
1115
1116
  * env-overridable via `CCLAW_MAX_PARALLEL_SLICE_BUILDERS`), throw
1116
1117
  * `DispatchCapError`.
1117
1118
  *
@@ -1126,9 +1127,13 @@ export function validateFanOutCap(stamped, activeEntries, override) {
1126
1127
  return;
1127
1128
  if (stamped.status !== "scheduled")
1128
1129
  return;
1129
- const cap = (override !== null && override !== undefined && Number.isInteger(override) && override >= 1)
1130
- ? override
1131
- : (readMaxParallelOverrideFromEnv() ?? MAX_PARALLEL_SLICE_BUILDERS);
1130
+ const cap = readMaxParallelOverrideFromEnv() ??
1131
+ (override !== null &&
1132
+ override !== undefined &&
1133
+ Number.isInteger(override) &&
1134
+ override >= 1
1135
+ ? override
1136
+ : MAX_PARALLEL_SLICE_BUILDERS);
1132
1137
  const sameLaneActive = activeEntries.filter((entry) => entry.stage === stamped.stage &&
1133
1138
  entry.agent === stamped.agent &&
1134
1139
  entry.spanId !== stamped.spanId);
@@ -1271,7 +1276,8 @@ export async function appendDelegation(projectRoot, entry) {
1271
1276
  if (overlap.autoParallel && stamped.allowParallel !== true) {
1272
1277
  stamped.allowParallel = true;
1273
1278
  }
1274
- validateFanOutCap(stamped, activeForRun);
1279
+ const config = await readConfig(projectRoot).catch(() => null);
1280
+ validateFanOutCap(stamped, activeForRun, resolveMaxBuilders(config));
1275
1281
  if (stamped.allowParallel !== true) {
1276
1282
  const existing = findActiveSpanForPair(stamped.stage, stamped.agent, activeRunId, prior);
1277
1283
  if (existing && existing.spanId && existing.spanId !== stamped.spanId) {
@@ -0,0 +1,36 @@
1
+ import type { ExecutionStrictnessProfile, ExecutionTopology } from "./types.js";
2
+ export interface ExecutionTopologyShape {
3
+ /** Ready implementation units/slices the controller could execute now. */
4
+ unitCount: number;
5
+ /** Ready units with no declared dependency/path conflict against each other. */
6
+ independentUnitCount?: number;
7
+ /** Ready units large enough to justify isolated builder overhead. */
8
+ substantialUnitCount?: number;
9
+ /** True when same-wave path ownership overlaps or is unknown-dangerous. */
10
+ hasPathConflicts?: boolean;
11
+ /** True for migrations, public contracts, security, data loss, or broad API changes. */
12
+ highRisk?: boolean;
13
+ /** True when a plan or controller explicitly requests micro-slice discipline. */
14
+ requiresStrictMicro?: boolean;
15
+ /** True when the controller can safely execute the unit inline in the current harness. */
16
+ inlineSafe?: boolean;
17
+ }
18
+ export interface ExecutionTopologyDecision {
19
+ topology: Exclude<ExecutionTopology, "auto">;
20
+ maxBuilders: number;
21
+ reason: string;
22
+ }
23
+ export interface RouteExecutionTopologyOptions {
24
+ configuredTopology?: ExecutionTopology;
25
+ strictness?: ExecutionStrictnessProfile;
26
+ maxBuilders?: number;
27
+ shape: ExecutionTopologyShape;
28
+ }
29
+ /**
30
+ * Choose the cheapest safe execution topology for a ready TDD surface.
31
+ *
32
+ * Safety invariants are intentionally conservative: explicit strict-micro wins,
33
+ * path conflicts prevent fan-out, and parallel builders require multiple
34
+ * independent substantial units plus a builder cap above one.
35
+ */
36
+ export declare function routeExecutionTopology(options: RouteExecutionTopologyOptions): ExecutionTopologyDecision;
@@ -0,0 +1,73 @@
1
+ const DEFAULT_MAX_BUILDERS = 5;
2
+ function normalizeMaxBuilders(value) {
3
+ return typeof value === "number" && Number.isInteger(value) && value >= 1
4
+ ? value
5
+ : DEFAULT_MAX_BUILDERS;
6
+ }
7
+ /**
8
+ * Choose the cheapest safe execution topology for a ready TDD surface.
9
+ *
10
+ * Safety invariants are intentionally conservative: explicit strict-micro wins,
11
+ * path conflicts prevent fan-out, and parallel builders require multiple
12
+ * independent substantial units plus a builder cap above one.
13
+ */
14
+ export function routeExecutionTopology(options) {
15
+ const configured = options.configuredTopology ?? "auto";
16
+ const strictness = options.strictness ?? "balanced";
17
+ const maxBuilders = normalizeMaxBuilders(options.maxBuilders);
18
+ const shape = options.shape;
19
+ if (configured !== "auto") {
20
+ return {
21
+ topology: configured,
22
+ maxBuilders,
23
+ reason: `configured execution.topology=${configured}`
24
+ };
25
+ }
26
+ if (shape.requiresStrictMicro || strictness === "strict") {
27
+ return {
28
+ topology: "strict-micro",
29
+ maxBuilders,
30
+ reason: shape.requiresStrictMicro
31
+ ? "plan requested strict micro-slice execution"
32
+ : "strict execution profile selected"
33
+ };
34
+ }
35
+ const unitCount = Math.max(0, shape.unitCount);
36
+ if (unitCount === 0) {
37
+ return {
38
+ topology: "inline",
39
+ maxBuilders,
40
+ reason: "no ready units; controller can reconcile inline"
41
+ };
42
+ }
43
+ if (shape.hasPathConflicts) {
44
+ return {
45
+ topology: "single-builder",
46
+ maxBuilders,
47
+ reason: "path conflicts require serialized execution"
48
+ };
49
+ }
50
+ const independent = shape.independentUnitCount ?? unitCount;
51
+ const substantial = shape.substantialUnitCount ?? unitCount;
52
+ if (maxBuilders > 1 && independent >= 2 && substantial >= 2) {
53
+ return {
54
+ topology: "parallel-builders",
55
+ maxBuilders,
56
+ reason: "multiple independent substantial units are ready"
57
+ };
58
+ }
59
+ if (unitCount === 1 && shape.inlineSafe && !shape.highRisk) {
60
+ return {
61
+ topology: "inline",
62
+ maxBuilders,
63
+ reason: "single low-risk inline-safe unit"
64
+ };
65
+ }
66
+ return {
67
+ topology: "single-builder",
68
+ maxBuilders,
69
+ reason: unitCount === 1
70
+ ? "single ready unit keeps builder evidence isolated"
71
+ : "ready units are not safely parallelizable"
72
+ };
73
+ }
@@ -64,8 +64,11 @@ export declare function extractMembersListFromLine(trimmedLine: string): string
64
64
  *
65
65
  * Rules:
66
66
  * - The line must start with `|` (after trimming).
67
- * - Column 1 (after stripping markdown noise) must match `^S-(\d+)$`
68
- * header rows (`| sliceId | …`) and separator rows (`|---|---|…`) are
67
+ * - Column 1 (after stripping markdown noise) may be either a slice id
68
+ * (`S-N`) or an implementation-unit id (`U-N`). Unit ids derive their
69
+ * execution slice as `S-N`, which lets 7.7+ plans schedule feature-atomic
70
+ * units without inventing a tiny `T-NNN` row per dispatch lane. Header rows
71
+ * (`| sliceId | …`, `| unit | …`) and separator rows (`|---|---|…`) are
69
72
  * silently skipped.
70
73
  * - Column 2, when present and non-empty, becomes the `unitId`
71
74
  * verbatim (after stripping whitespace + backticks/quotes/brackets).
@@ -71,8 +71,11 @@ export function extractMembersListFromLine(trimmedLine) {
71
71
  *
72
72
  * Rules:
73
73
  * - The line must start with `|` (after trimming).
74
- * - Column 1 (after stripping markdown noise) must match `^S-(\d+)$`
75
- * header rows (`| sliceId | …`) and separator rows (`|---|---|…`) are
74
+ * - Column 1 (after stripping markdown noise) may be either a slice id
75
+ * (`S-N`) or an implementation-unit id (`U-N`). Unit ids derive their
76
+ * execution slice as `S-N`, which lets 7.7+ plans schedule feature-atomic
77
+ * units without inventing a tiny `T-NNN` row per dispatch lane. Header rows
78
+ * (`| sliceId | …`, `| unit | …`) and separator rows (`|---|---|…`) are
76
79
  * silently skipped.
77
80
  * - Column 2, when present and non-empty, becomes the `unitId`
78
81
  * verbatim (after stripping whitespace + backticks/quotes/brackets).
@@ -94,13 +97,16 @@ export function parseTableRowMember(trimmedLine) {
94
97
  const stripDecorations = (raw) => raw.replace(/^[`"'[\]()]+|[`"'[\]()]+$/gu, "").trim();
95
98
  const col1 = stripDecorations(cells[0]);
96
99
  const parsedSlice = parseSliceId(col1);
97
- if (!parsedSlice)
100
+ const parsedUnit = tokenToSliceAndUnit(col1);
101
+ if (!parsedSlice && !parsedUnit)
98
102
  return null;
99
- const sliceTail = parsedSlice.suffix.length > 0
100
- ? `${parsedSlice.numeric}${parsedSlice.suffix}`
101
- : `${parsedSlice.numeric}`;
102
- const sliceId = parsedSlice.id;
103
- let unitId = `U-${sliceTail}`;
103
+ const sliceTail = parsedSlice
104
+ ? parsedSlice.suffix.length > 0
105
+ ? `${parsedSlice.numeric}${parsedSlice.suffix}`
106
+ : `${parsedSlice.numeric}`
107
+ : "";
108
+ const sliceId = parsedSlice ? parsedSlice.id : parsedUnit.sliceId;
109
+ let unitId = parsedSlice ? `U-${sliceTail}` : parsedUnit.unitId;
104
110
  if (cells.length >= 2) {
105
111
  const col2 = stripDecorations(cells[1]);
106
112
  if (col2.length > 0) {
@@ -1,4 +1,5 @@
1
1
  import type { Writable } from "node:stream";
2
+ import type { ExecutionTopology } from "../types.js";
2
3
  interface InternalIo {
3
4
  stdout: Writable;
4
5
  stderr: Writable;
@@ -17,6 +18,9 @@ export interface WaveStatusNextDispatch {
17
18
  readyToDispatch: string[];
18
19
  pathConflicts: string[];
19
20
  mode: "single-slice" | "wave-fanout" | "blocked" | "none";
21
+ topology: Exclude<ExecutionTopology, "auto"> | "none";
22
+ topologyReason: string;
23
+ maxBuilders: number;
20
24
  }
21
25
  export interface WaveStatusReport {
22
26
  activeRunId: string;