review: M3 PASS (live: !testme 12s trigger, re-run, !testmexyz no-trigger, org-auth); close A4 (cap=1 mitigates)
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone Build is passing

This commit is contained in:
2026-05-27 03:14:49 +01:00
parent b477274e67
commit d6f0f67d49
2 changed files with 35 additions and 1 deletions

View File

@ -130,7 +130,17 @@ Two single-writer sections (§6.1): Builder edits only `## Build backlog`; Adver
doesn't need the `.env`. *Re-test:* run install, kill the process mid-deploy, verify the next
run (or janitor) leaves zero residual service/volume/secret. Adversary closes after re-test.
- [ ] **[adversary] A4 — Concurrent same-recipe runs collide on the shared recipe checkout.**
- [x] **[adversary] A4 — Concurrent same-recipe runs collide on the shared recipe checkout.**
**CLOSED @2026-05-27T03:13Z — mitigated by the runtime concurrency cap.** The Builder's
resource-safety change sets `DRONE_RUNNER_CAPACITY=1` (verified live: runner logs `capacity=1`)
+ the recipe-CI pipeline has `concurrency:limit:1`, so recipe-CI builds **serialize** — two
runs never overlap, hence the shared `~/.abra/recipes/<recipe>` checkout collision cannot
occur via the production trigger path. The §6 "two concurrent runs don't collide" guarantee
holds by serialization (an explicitly endorsed design per plan §4.2). **Latent caveat:** the
checkout is still *not* per-run isolated, so raising `DRONE_RUNNER_CAPACITY`>1 (the module
comments allow it) would reintroduce the collision — fix the per-run abra home/checkout before
ever doing so. (A positive "two triggers serialize & both complete" check folds into the M10
concurrency verification.)
Found by review (M6 verify); to confirm empirically. Per-run isolation is correct for the app
**domain/volume/secret** (hashed `<recipe[:4]>-<6hex(recipe|pr|ref)>`), but the recipe *source
checkout* is a single shared path `~/.abra/recipes/<recipe>`: `run_recipe_ci.fetch_recipe`