← board

What is measured

$ sed -n 24p tools/gate.sh
LOGDIR="${TMPDIR:-/tmp}/pxx-gate-$$"
$ ls -d /tmp/pxx-gate-* | wc -l      -> 78
$ du -shc /tmp/pxx-gate-* | tail -1  -> 5.3G
$ oldest                             -> 2026-09-10

No trap, no reaper, one directory per gate run, and gate.sh quick is advertised as OPTIONAL PER FIX — so the rate scales with how well seats follow the advice to gate often.

Why the obvious fix is wrong, and this is the whole point of the ticket

trap 'rm -rf "$LOGDIR"' EXIT is what CLAUDE.md's own cleanup guidance suggests for exactly this shape ("if cleanup genuinely matters, it belongs in a committed script with a trap ... EXIT"). Here it would break the tool.

What it probably wants instead

An age-based reap (delete pxx-gate-* older than N hours at gate START, not at exit) or keep-on-red (reap only when every row passed). Both are design calls with trade-offs — how long is long enough to diagnose, and does a green run's log ever get read — which is why this is filed rather than fixed. /etc/tmpfiles.d/tmp.conf is at 6h, so plexus already reaps these eventually; the accrual above says it is not keeping up, and seven's /tmp is a tmpfs where the binding limit is INODES and not bytes.

The trap caveat is frankZ's, who reached for the trap first and caught it.

What reaping does NOT fix, and quietly makes harder to notice

frankZ, 2026-09-11, and it cuts against this ticket's own fix. Reading another session's gate dir is an established practice and an established mistake: L=$(ls -td /tmp/pxx-gate-* | head -1); cat "$L/summary.log" is in debugging-playbook.md:12418 under "The two wrong ways, both of which look careful", measured 2026-09-05 with three gates running, where ls -td returned a different session's directory.

Reaping shrinks the population of stale dirs, so ls -td | head -1 returns the caller's own dir more often. The known-broken method therefore becomes more reliable, which means it gets CERTIFIED more often and corrected less — the passing-arrangement failure the fixture clause in CLAUDE.md describes, arriving through a cleanup change nobody would connect to it.

This is not an argument against reaping. It is a statement that must be in the ticket so no later reader takes "we reaped the dirs" as having addressed the ls -td hazard. It does not. The two are independent and the reap makes the second one quieter.

Why age-based-at-start rather than keep-on-red

Keep-on-red has to read the verdict that lives inside the directory it is judging, and be right about it. Invert that test once and it deletes exactly the reds — a reaper whose failure mode is losing the only evidence anyone needed. Age-based never reads a verdict: it needs a clock, and it degrades to "you waited too long" rather than to "the evidence is gone".

At START, never at exit, so a run can never delete its own output.

Plus one syscall to remove the clock coupling (frankZ): a purely time-keyed reap can delete a CONCURRENTLY RUNNING gate's directory if the threshold is ever tuned below a long run's duration — a full gate is not a 30-second quick one, and whoever tunes it later will not be thinking about that. The directory name IS the pid, so kill -0 "${dir##*-}" skips any live producer and removes the coupling rather than relying on the threshold staying generous.

Checking this ticket's own claims

grep -n 'trap' tools/gate.sh returns a hit — line 89, matching bootstrap inside a comment. So the fast check of "is there a trap" answers YES and the truth is NO. The word-boundary form is honest: grep -nE '(^|[^a-z])trap[[:space:]]' tools/gate.sh returns nothing.