fix(cli): close keyring-interrupt race in Ctrl-C signal-abort
Commit

PR #1604 made Ctrl-C break enclosing shell loops by re-raising the caught signal, gating the silent-abort path on a caughtSignal atomic set by the top-level signal handler goroutine. A Ctrl-C during a blocked keyring read could still slip through: the keyring's own signal listener returns a wrapped context.Canceled independently of the root-context cancellation, so the main flow could reach the abort gate and read caughtSignal before the handler goroutine stored it. When that happened the raw "...: context canceled" error printed as a failure and the process exited 1 (not signal-killed), so the loop kept respawning — the exact symptom the PR fixed.
Unify "were we signalled?" behind a single shared source of truth:
- Add internal/procsignal: a tiny package holding the caught terminating signal, importable by both cmd/entire and the tokenstore keyring path (no import cycle).
- cmd/entire/main.go: replace the local caughtSignal atomic with procsignal; the handler and the abort gate both go through it.
- tokenstore keyring: on the interrupt branch, record the signal via procsignal on the same goroutine that unwinds to main's gate (recordInterruptSignal), turning the cross-goroutine race into a same-goroutine happens-before. Timeouts (DeadlineExceeded) are untouched.
Tests:
- procsignal store/load/reset unit tests.
- TestRecordInterruptSignal: a Ctrl-C abort records SIGINT; timeout/success do not.
- TestDieFromSignal_TerminatesBySignal: deterministic regression guard that re-execs the test binary and asserts it dies by the signal (WIFSIGNALED, SIGINT/SIGTERM) rather than exiting normally — the WIFSIGNALED property a "simplify back to os.Exit(130)" would silently regress.
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com Entire-Checkpoint: 72e0907000ba