From 91e8aab38312e27550c9b36db20bc8e8d2f87814 Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Thu, 7 May 2026 08:46:39 +0200 Subject: [PATCH] fix(opencode): require sequential @make dispatches, tighten @test parallelism MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A workflow run dispatched two @make agents in parallel. Both agents write source files, run cargo verification commands, and may both target the same file (e.g. src/lib.rs for a new `pub mod` plus a later registration) — concurrent edits corrupt each other and Cargo's target/ lock serialises the builds anyway, so parallelism only adds risk without giving speedup. Phase 7 now states explicitly that @make dispatches are SEQUENTIAL — never in parallel — and lists the reasons inline. The rule covers all @make invocations: standard mode, TDD mode, the Rust stub-pass and body-pass, and integration-fix dispatches. Stub-pass/body-pass ordering within a task is strict so @test always RED-verifies against a deterministic crate state. Phase 6's parallelism rule splits per language: Python parallel @test is still allowed for disjoint test files, but Rust @test runs sequentially since cargo serialises the build and shared crate-level helper files race. --- config/opencode/commands/workflow.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/config/opencode/commands/workflow.md b/config/opencode/commands/workflow.md index 1e2a8eb..9a10204 100644 --- a/config/opencode/commands/workflow.md +++ b/config/opencode/commands/workflow.md @@ -293,8 +293,11 @@ Rust integration tests live in a separate test crate (`tests/.rs`) that The stub pass and the body pass each produce their own atomic commit (per Phase 9 rules): `feat(): scaffold with todo!() stubs` followed by `feat(): implement ` (or whichever conventional type fits). -**Parallelism:** Independent tasks can have tests written in parallel. -**Constraint:** `@test` must not modify existing conftest.py files (prevents collision during parallel execution). +**Parallelism:** +- **Python:** Independent tasks can have tests written in parallel, *provided* their test files are disjoint and no shared `conftest.py` is being modified. +- **Rust:** Run `@test` dispatches **sequentially**. Cargo serialises the build via the `target/` directory lock, so parallel dispatches give no speedup; they only add risk (a long-running build in one branch starves the other, and any task that touches a shared crate-level fixture/helper file will race). + +**Constraint:** `@test` must not modify existing `conftest.py` files (prevents collision during parallel execution). --- @@ -302,6 +305,13 @@ The stub pass and the body pass each produce their own atomic commit (per Phase Apply **Dispatch Hygiene** to each `@make` spec before sending. Repeated trips on a single task signal a Phase 5 split problem — go back and split. +**`@make` dispatches are SEQUENTIAL — never in parallel.** Run each task to completion (writes, every verification command, and the orchestrator's post-check) before dispatching the next. Reasons: +- `@make` writes source files. Parallel agents picking the same file (e.g. `src/lib.rs` for adding both a new `pub mod` and a registration) corrupt each other. +- Even on disjoint files, Cargo's `target/` lock and uv's venv state serialise the verification builds anyway, so parallelism gives no speedup. +- Stub-pass/body-pass pairs (Rust integration TDD) must be strictly ordered within a task; running stub-pass for task 2 while body-pass for task 1 is still building yields a non-deterministic crate state for `@test` to RED against. + +This applies to **all** `@make` invocations: standard mode, TDD mode, stub-pass, body-pass, and integration-fix dispatches. + Execute each task by dispatching `@make` with: - The task spec (from Phase 5, finalized per Dispatch Hygiene) - Relevant code context (seam-revealing snippets only — see Phase 5 "Code Context — what to include")