Round 5, two independent reviews. Two findings, one technical and one about
honesty, and the second is the more important.
THE RATIONALE. The round-4 commit and the decision record state as measured fact
that trapping signals made a hook take 30s to die where it took 1s. That came
from a review finding I accepted without re-measuring. It is wrong. Measured A/B:
signal the pid control 4.01s trapped 4.12s
signal the group control 0.002s trapped 0.054s
The stall is bash deferring a fatal signal until its foreground command finishes,
and it happens identically with NO trap — the control stalls too. The trap cost
~0.1s, not 29s. The withdrawal still stands, but on its real grounds: three
silent permissive-direction defects in three rounds for a sub-millisecond rescue
window, and the trapped sink STILL returned rc 0 on SIGINT where the control
returns -2. The record now carries the correction rather than the fabrication,
because a decision record with an invented measurement reads as checked and talks
the next reader out of checking.
The test that was supposed to enforce this was itself vacuous: it signalled the
pid, so both sides took the full sleep and the timing assertion could distinguish
nothing. It signals the process group now — the supervisor shape, and the only
one where the assertion can see anything.
THE LOCALE FIX WAS INERT. `local LC_ALL=C` does not export, so the child sed/tr
never saw it. It read as fixed only because this author's shell sets LANG alone;
with an inherited LC_CTYPE (macOS Terminal, ssh SendEnv, sudo env_keep) LC_CTYPE
outranks the exported LANG=C and the symptom returns in full — a real deny filed
as `output`, records under `unknown-session` with empty event and tool, and
`illegal byte sequence` at the harness. `local -x` now, verified end-to-end
across four locale environments, and the test is parametrised over them because a
single ambient locale tests one row of the matrix.
Also this round:
- Removing the 64KB cap ARMED a latent bug rather than fixing one: a greedy `.*`
over a single-line payload takes the LAST match, so a nested session_id inside
a tool_response outranked the top-level one and filed the whole invocation
under the wrong session. The cap had been accidentally protecting the right
answer. First-match extraction now, bounded at 256KB where the bound is no
longer load-bearing (3 unbounded scans cost 1.5s on a 20MB payload).
- A present-but-empty decision value was laundered to `output`.
- The redirect-order guard excluded operators preceded by a digit, so it was
blind to `exec 0<` — the exact line it was written for. Mutation-checked both
ways now: clean on the real file, red when the original bug is reintroduced
verbatim. Its limits are stated in the docstring rather than implied.
Refs: #776
Decisions-Edit: yes
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>