From 5bcb3222830da6cc06e9423e8991b148ca7354df Mon Sep 17 00:00:00 2001 From: Drew T <50529377+Druthulu@users.noreply.github.com> Date: Mon, 31 Aug 2026 14:55:39 -0600 Subject: [PATCH] =?UTF-8?q?docs:=20gating=20is=20fully=20parallel=20?= =?UTF-8?q?=E2=80=94=20no=20serial=20lane;=20jtbl=20unlocked=20via=20isola?= =?UTF-8?q?te=5Fasm;=20launch=20detached=20with=20setsid?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/SETUP.md | 7 +++++++ docs/wave-playbook.md | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/docs/SETUP.md b/docs/SETUP.md index 8ee1831405..c13a261300 100644 --- a/docs/SETUP.md +++ b/docs/SETUP.md @@ -617,6 +617,13 @@ Full how-to in `docs/matching-cookbook.md` §11. Command crib: ## §6.9 Running a matching wave — see `docs/wave-playbook.md` +**GATING IS FULLY PARALLEL AS OF P31 S67 — there is no serial lane.** `tools/parallel_gate.py` +handles jtbl carves too (`isolate_asm()` gives a carving worker a writable copy of the ONE binary's +3.6-5 MB asm subtree instead of symlinking all 448 MB). Measured: 13 fns/13 binaries in 139 s and +19 fns/14 jtbl binaries in 188 s, against 58 minutes for a single jtbl binary serially. +**Always `make -j$(nproc) build`** — a per-binary build is ~35 objects and was single-threaded +(7.18 s -> 1.18 s, byte-identical); every tool that shells `make build` now passes `-j`. + The start-to-finish operational sequence (draw → cards → packs → validate → draft → split-gate → twin_sweep → harvest → R22 → checkpoint), with the measured failure that justifies each guard. The tooling-inventory rows below are the per-tool REFERENCE; the playbook is the PROCEDURE. diff --git a/docs/wave-playbook.md b/docs/wave-playbook.md index 3901d2be72..0b1e00a119 100644 --- a/docs/wave-playbook.md +++ b/docs/wave-playbook.md @@ -100,7 +100,32 @@ still open **at draw time**. Streaming **burns the 5-hour window faster** (it removes the idle gaps), so slots are the budget dial. Model routing: ≤50 ins Sonnet · 51–120 Sonnet · >120 Opus. Never Haiku→Opus directly. -## 6. Gate — split on jtbl, run both lanes at once +## 6. Gate — EVERYTHING PARALLEL. There is no serial lane. + +``` +python3 tools/parallel_gate.py --plan plan.json --workers 12 --commit + # plan.json: [{"binary": "...", "drafts": "/abs/path"}, ...] +``` + +**MEASURED S67, and this is the bar:** + +| lane | result | +|---|---| +| non-jtbl | **13 banked / 13 binaries / 139 s** (12 workers) | +| jtbl | **19 banked / 14 binaries / 188 s** (8 workers), 0 refusals | +| the same jtbl work, serially, earlier that day | **58 minutes for ONE binary** | + +**jtbl used to be serial-only** because `harvest_verify`'s carve runs `make extract` and a worktree's +`asm/` is a symlink to the main tree — a carving worker would rewrite shared asm. `isolate_asm()` +fixes it: `asm/` is 448 MB but ONE binary's subtree is **3.6-5.0 MB**, so a carving job gets +per-binary symlinks plus a real copy of the single binary it carves (~5 MB/worker). It is applied +PER JOB because worker slots are reused, and gated by the same jtbl predicate `harvest_verify` +carves on. + +**If you are writing `for b in binaries: gate_stage ...`, STOP.** That loop is the hour-long mistake +this section exists to prevent. + +### 6b. (historical) split on jtbl, run both lanes at once ``` python3 tools/gate_wave.py --drafts