fix(opencode): require sequential @make dispatches, tighten @test parallelism

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.
This commit is contained in:
Harald Hoyer 2026-05-07 08:46:39 +02:00
parent f0cc300358
commit 91e8aab383

View file

@ -293,8 +293,11 @@ Rust integration tests live in a separate test crate (`tests/<feature>.rs`) that
The stub pass and the body pass each produce their own atomic commit (per Phase 9 rules): `feat(<scope>): scaffold <thing> with todo!() stubs` followed by `feat(<scope>): implement <thing>` (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")