fix(ci): csp-scan hangs at a terminal instead of printing its usage - #173
Merged
Conversation
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
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 — iteratessys.stdinwheneverargvis 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 newci/check-csp-scan-selftest.pyallocates a real pty, and pins all three input paths:It is discovered automatically by the derived fixture runner from #170; no wiring line.
Verification
Mutation: disabling the gate (
elif False:) makes the selftest reportdid not exit within 10s -- it is blocking on a stdin read instead of printing usageand 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.