summaryrefslogtreecommitdiff
path: root/docs/superpowers/specs
diff options
context:
space:
mode:
authorhathach <[email protected]>2026-07-13 18:01:07 +0700
committerhathach <[email protected]>2026-07-13 18:01:07 +0700
commitff69550b3d8d55b5c9d48a3dfe4e87f7690e9455 (patch)
tree93567f5abd365f572282a6c2c63ce39c2f60fd05 /docs/superpowers/specs
parent0557655afbb9e608c26ac0c6cbf95c6e69138c77 (diff)
Fix max-effort review findings in lock protocol, workflows, and docs
Confirmed by a 10-finder / 28-verifier adversarial review pass: board_lock.py — the flock is now the sole authority: drop cmd_hold's pid-liveness pre-gate (a live hil_test.py pool worker's stale record no longer blocks a genuinely free board); cmd_release probes the flock and only signals a verified holder, refuses to kill hil_test.py holders (CI mid-test), handles PermissionError; the holder daemon truncates its lock records on SIGTERM and keeps the success pipe clear of fds 0-2 (closed-stdio hold used to leave an orphan holder while reporting failure); --config default resolves beside the script. hil_test.py — truncate the lock record on per-board release (pool workers outlive their flocks); warn instead of silently failing open when the lock dir is unusable; error out on -b names absent from the config (was a silent zero-test exit 0, readable as a green HIL run); drop an emptied board row in accumulate_report (variant boards left a blank ghost row). workflows — remove the stray positional arg that made the validate size stage exit 2 on every run; wrap JSON.parse(args) in all six scripts; factor pr-babysit's drifted reply recipe into postReplyRecipe and dedup refutation replies across cycles; validate args.pr and maxCycles; driver-review rejects an empty dimensions list; hil-validate drops a dead guard clause and retries diagnostics with -v -r 1. agents/docs — port-dev scopes git clang-format to its own files (concurrent workers reformatted each other in shared checkouts); hil-operator/hil skill wording matches actual fail-fast output; the implementation plan is now a DO-NOT-EXECUTE historical record (banner + checked boxes) so plan-executing agents cannot revert shipped files. Verified: lock storm 1-winner-in-10, stale-record hold, closed-stdio hold, dead-pid cleanup, CI-holder refusal, ghost-row 4-scenario merge, unknown-board exit 1, py_compile + check.sh on all six workflows, pre-commit clean. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Upj4hta5TNoAbidqeC1zZ6
Diffstat (limited to 'docs/superpowers/specs')
-rw-r--r--docs/superpowers/specs/2026-07-09-claude-agents-workflows-design.md25
1 files changed, 16 insertions, 9 deletions
diff --git a/docs/superpowers/specs/2026-07-09-claude-agents-workflows-design.md b/docs/superpowers/specs/2026-07-09-claude-agents-workflows-design.md
index f37929439..63788720c 100644
--- a/docs/superpowers/specs/2026-07-09-claude-agents-workflows-design.md
+++ b/docs/superpowers/specs/2026-07-09-claude-agents-workflows-design.md
@@ -59,24 +59,31 @@ log-heavy).
CI and dev sessions share the rig concurrently; the actions-runner service is
never stopped. Arbitration is per-board kernel flocks in
`/tmp/tinyusb-hil-locks/<board>.lock` — auto-released when the holder process
-dies (stale locks impossible; `/tmp` clears on reboot):
+dies, with holders truncating their lock-file record on release so records
+stay truthful (`/tmp` clears on reboot):
- **`test/hil/board_lock.py`** (new tool): `hold <boards|--all> --reason TEXT`
spawns a background holder process flocking each board file (JSON
- `{pid, reason, since}` written inside for debuggability); `release
- <boards|--all>` kills holders; `status` lists them. `--all` is required
- before rig-wide operations (uhubctl power cycling, pci-rebind — bus
- renumbering affects every board).
+ `{pid, reason, since}` written inside for debuggability); the holder's own
+ LOCK_NB flock is the sole authority — there is deliberately no pid-based
+ pre-check (recorded pids can be stale or recycled). `release <boards|--all>`
+ probes each board's flock: a free lock only gets its stale record cleared;
+ a genuinely held one gets its recorded holder SIGTERMed — unless the holder
+ reason is `hil_test.py` (a CI run mid-test), which release refuses to kill.
+ `status` lists holders. `--all` is required before rig-wide operations
+ (uhubctl power cycling, pci-rebind — bus renumbering affects every board).
- **`hil_test.py` guard** (small patch to the per-board worker): take the
board's flock non-blocking before flashing and hold it for that board's
flash+test; on acquire it writes its own holder info
(`{pid, reason: "hil_test.py", since}`) so conflicts report truthfully in
- both directions. If already held, FAIL the board immediately —
- `FAILED (board locked: <holder info>)` — no flash, no waiting.
+ both directions, and truncates that record on release (the pool worker
+ outlives the per-board flock). If already held, FAIL the board immediately —
+ `Failed: board locked: <holder info>` — no flash, no waiting.
The CI job fails visibly for exactly those boards and `re-run failed`
passes once the lock is released (`build.yml` already retries the HIL step
- once, absorbing short dev sessions). Guard defaults to proceeding if the
- lock dir is absent/odd.
+ once, absorbing short dev sessions). Guard proceeds unlocked — with a
+ printed warning — if the lock dir is unusable, and `-b` names absent from
+ the config are a hard error rather than a silent zero-test green run.
- **Re-entrancy rule:** dev sessions do NOT pre-hold boards they are about to
run `hil_test.py` on (it self-locks; pre-holding deadlocks it).
`board_lock.py hold` is for hardware work outside `hil_test.py` only.