scripts/check-sigint-deliverable is the single checked-in helper, to the
ABI revision 12 fixed: exit 0 safe with no diagnostic, exit 1 ignored
with the canonical wording, exit 2 error with a distinct one. The inner
probe's `|| exit 24` arms are the load-bearing part --- without them a
FAILED kill also falls through to exit 0 and gets misread as inherited
SIG_IGN, which is the one wrong answer the helper exists to prevent.
R-b: scripts/gate runs it before any stage and stops on a non-zero
status, surfacing the helper's stderr unchanged and adding only that no
stage ran. It does not re-derive the classification or supply its own
wording. Plan/print modes skip it, since they run nothing. No override.
R-d: the target test calls the same helper first and panics with
"precondition failed --- this is NOT a teardown defect" plus the helper's
own stderr, instead of reaching the misleading "child did not exit
within 5s". The Linux-only /proc D1/D2 instrument is removed now that
its evidence is portable, taking the platform dependency with it.
Witnesses:
A1 backgrounded gate stops before stage 1 with the ignored
diagnosis, exit 1.
A2 backgrounded direct test reports the precondition failure, NOT
the 5s deadline.
A3 foreground: both target copies pass in 0.16s and the guard is
silent.
A4 mutations measured, each biting its named row --- removing the
trap bites A3 (fg 0->2), treating inner 0 as safe bites A1/A2 (bg
1->0), collapsing error into ignored bites A6 (forced 2->1).
A5 the full default gate passes all 8 stages foreground, and
--print-plan is byte-identical to HEAD's: no stage added,
removed, reordered or made conditional.
A6 forced probe failure yields exit 2 and the error wording, not
the ignored wording.
A7 exercised on Linux x86_64 only, all three outcomes; no non-Linux
unix was reachable, so A7 stays OPEN there and the portability
argument is labelled contract-level, not measured.
Also records that this session's tool-level background mode leaves
SIGINT deliverable while setsid nohup ... & does not --- so the construct
that caused this lane was never necessary for long runs.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016bqGA6s9tTUFzYpbeW3tai