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.
- package/README.md +2 -1
- package/dist/artifact-linter/plan.js +98 -25
- package/dist/artifact-linter/tdd.js +2 -2
- package/dist/config.d.ts +15 -1
- package/dist/config.js +152 -2
- package/dist/content/core-agents.d.ts +1 -1
- package/dist/content/core-agents.js +2 -2
- package/dist/content/meta-skill.js +4 -4
- package/dist/content/skills.js +12 -8
- package/dist/content/stage-schema.js +2 -2
- package/dist/content/stages/plan.js +17 -17
- package/dist/content/stages/tdd.js +13 -10
- package/dist/content/start-command.js +3 -3
- package/dist/content/subagent-context-skills.js +2 -2
- package/dist/content/subagents.js +6 -6
- package/dist/content/templates.js +12 -7
- package/dist/delegation.d.ts +4 -3
- package/dist/delegation.js +14 -8
- package/dist/execution-topology.d.ts +36 -0
- package/dist/execution-topology.js +73 -0
- package/dist/internal/plan-split-waves.d.ts +5 -2
- package/dist/internal/plan-split-waves.js +14 -8
- package/dist/internal/wave-status.d.ts +4 -0
- package/dist/internal/wave-status.js +47 -8
- package/dist/types.d.ts +45 -0
- package/package.json +1 -1
|
@@ -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
|
|
14
|
-
purpose: "Create
|
|
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
|
|
47
|
-
"Task Contract — every
|
|
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
|
|
54
|
-
"**Author the FULL Parallel Execution Plan.** Inside the `<!-- parallel-exec-managed-start -->` block, enumerate
|
|
55
|
-
"After authoring/refreshing the managed parallel-exec block, render a Mermaid `flowchart` or `gantt` covering waves (`W-*`) and slice dependencies (`S-*`) so
|
|
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
|
|
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: "
|
|
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
|
|
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
|
-
"
|
|
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: "
|
|
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
|
|
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: "
|
|
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
|
-
"
|
|
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
|
|
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: "
|
|
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
|
|
41
|
-
"**
|
|
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
|
|
44
|
-
"**
|
|
45
|
-
"**
|
|
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
|
|
52
|
-
"Controller
|
|
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
|
-
"
|
|
63
|
-
"
|
|
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
|
|
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 \`
|
|
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\`.
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
180
|
+
2. **For each unit — cheapest 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 \`
|
|
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
|
-
-
|
|
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
|
-
-
|
|
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.
|
|
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
|
-
- **
|
|
951
|
-
- **Why this
|
|
952
|
-
- **Subagent recipe (if
|
|
953
|
-
- **Inline recipe (if
|
|
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 -->
|
package/dist/delegation.d.ts
CHANGED
|
@@ -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
|
|
334
|
-
* flag or globally via
|
|
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
|
*
|
package/dist/delegation.js
CHANGED
|
@@ -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
|
|
620
|
-
* flag or globally via
|
|
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 = (
|
|
1130
|
-
|
|
1131
|
-
|
|
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
|
-
|
|
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)
|
|
68
|
-
*
|
|
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)
|
|
75
|
-
*
|
|
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
|
-
|
|
100
|
+
const parsedUnit = tokenToSliceAndUnit(col1);
|
|
101
|
+
if (!parsedSlice && !parsedUnit)
|
|
98
102
|
return null;
|
|
99
|
-
const sliceTail = parsedSlice
|
|
100
|
-
?
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
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;
|