Skip to content

fix(ci): csp-scan hangs at a terminal instead of printing its usage - #173

Merged
forkwright merged 1 commit into
mainfrom
fix/csp-scan-tty-hang
Aug 17, 2026
Merged

fix(ci): csp-scan hangs at a terminal instead of printing its usage#173
forkwright merged 1 commit into
mainfrom
fix/csp-scan-tty-hang

Conversation

@forkwright

Copy link
Copy Markdown
Owner

Fixes a live regression on main, found by an independent adversarial review of PR #171 after it merged.

The defect

ci/csp-scan.py's stdin fallback — added to keep a large file set from hitting the argv size limit — iterates sys.stdin whenever argv is empty. A closed or piped stdin reaches EOF and falls through to the usage error. A live terminal never does, so a bare interactive invocation blocks forever instead of exiting 2.

Reproduced under an allocated pty: no output, still running.

Why it read as safe

The comment justifying the absence of an isatty() gate said an empty or closed stdin "falls through to an empty paths list either way." That is true for closed stdin and false for a tty — the comment's own account of the mechanism was wrong, which is exactly what made the code look correct. It now states what it actually relies on.

The stdin path is unchanged. It stays, because it is the reason this exists.

Why CI was green on a script that hangs

Nothing in CI ever invokes it from a terminal. Every cheap way to test the empty case — closed stdin, /dev/null, an empty pipe — reaches EOF immediately and passes against the broken code. So the new ci/check-csp-scan-selftest.py allocates a real pty, and pins all three input paths:

  • bare at a tty → exit 2 with usage, within a timeout
  • piped path list → still consumed (the argv-limit path must not be swallowed by the gate)
  • empty pipe → still a usage error

It is discovered automatically by the derived fixture runner from #170; no wiring line.

Verification

Mutation: disabling the gate (elif False:) makes the selftest report did not exit within 10s -- it is blocking on a stdin read instead of printing usage and return 1, rather than hanging the suite. Restored, and the selftest returns 0.

Shape worth noting

This is a fix for an input-handling defect that introduced a new input-handling defect in the same guard path — the "claim does not match runtime behaviour" class that issue #92 was opened to eliminate. Credit to the reviewer who caught it by running the thing under a pty rather than reading the diff.

The stdin fallback added for the argv-size limit iterates sys.stdin whenever argv is
empty. A closed or piped stdin reaches EOF and falls through to the usage error, but a
LIVE terminal never does -- so a bare interactive invocation blocks forever instead of
exiting 2. Reproduced under an allocated pty: no output, still running.

The comment justifying the absence of an isatty gate asserted that an empty stdin falls
through 'either way'. That is true for closed stdin and false for a tty, which is why the
code read as safe. It now states the mechanism it actually relies on.

The stdin path itself is unchanged and still the reason this exists: it is what keeps a
large file set from hitting the argv limit.

ci/check-csp-scan-selftest.py pins all three input paths and is discovered automatically
by the derived fixture runner. It allocates a real pty, because every cheaper stdin --
closed, /dev/null, an empty pipe -- reaches EOF immediately and passes against the broken
code. That is precisely why CI was green on a script that hangs: nothing in CI invokes it
from a terminal. Verified by mutation: disabling the gate makes the selftest report the
block within its timeout rather than hanging the suite.
@forkwright
forkwright merged commit 41b6e76 into main Aug 17, 2026
6 of 8 checks passed
@forkwright
forkwright deleted the fix/csp-scan-tty-hang branch August 17, 2026 16:14
forkwright pushed a commit that referenced this pull request Aug 17, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.4.2](v0.4.1...v0.4.2)
(2026-08-17)


### Bug Fixes

* **bin,ci,schemas,templates:** resolve 16 low-severity correctness and
claim-accuracy defects
([#171](#171))
([77d3146](77d3146)),
closes [#92](#92)
* **ci,typikon-validate:** derive the fixture list; route+accept
journal-entry.html extras
([#170](#170))
([0771a99](0771a99))
* **ci:** csp-scan hangs at a terminal instead of printing its usage
([#173](#173))
([41b6e76](41b6e76))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant