fix(git): ci-queue-wait.sh — parse the payload it was handed, not stdin (#1019) #1023

Open
mos-dt-0 wants to merge 2 commits from fix/1019-queue-guard-stdin into main
Collaborator

Fixes #1019. ci-queue-wait.sh:37,:86 use python3 - <<'PY', which binds stdin to the program text, so json.load(sys.stdin) EOFs, the state falls through to unknown, and the guard exits 0 on every invocation, every branch, every repo, both platforms.

Passes the payload as an argument instead. pr-ci-wait.sh:38 documents this exact bug with the remedy; it was never backported to the mandatory sibling.

Built and tested previously; opened per board instruction without re-verification. Commit 505b6f7.

Fixes #1019. ci-queue-wait.sh:37,:86 use `python3 - <<'PY'`, which binds stdin to the program text, so `json.load(sys.stdin)` EOFs, the state falls through to `unknown`, and the guard exits 0 on every invocation, every branch, every repo, both platforms. Passes the payload as an argument instead. pr-ci-wait.sh:38 documents this exact bug with the remedy; it was never backported to the mandatory sibling. Built and tested previously; opened per board instruction without re-verification. Commit 505b6f7.
mos-dt-0 added 1 commit 2026-07-31 16:41:55 +00:00
Both python sites piped a status payload into `python3 - <<'PY'`. The heredoc binds
stdin to the program text, so `json.load(sys.stdin)` saw EOF, the bare `except` fired,
and the parser returned "unknown" for every input — success, pending and failure alike.
"unknown" then reaches a silent `exit 0` arm.

Consequence: the gate-6 queue guard has never made a determination. It exits 0 on every
invocation, on both the gitea and github paths (one shared parser). The pending wait
loop, --require-status and the 124 timeout were all unreachable code. What it still
validated was connectivity — an unresolved token, head sha, or platform could exit 1.

Fix is the one already shipped in the sibling: capture the payload with `payload=$(cat)`
before invoking python, pass it by environment. pr-ci-wait.sh:38 has carried a comment
describing this exact bug — "yielding EOF and returning unknown every time" — along with
the remedy. It was never backported to the sibling the constitution makes mandatory
before every push and merge.

Adds test-ci-queue-wait-parse.sh, enumerated in test:framework-shell. Every assertion is
on the RETURNED STATE STRING; a suite asserting only rc=0 passes against the broken build,
which is how this survived. Verified by mutation: against the pre-fix wrapper the suite
fails 10 of 14, and the four that pass are the four for which passing is correct (the
undecodable-input control, the unknown-vocabulary case, and both needle halves).

The needle scans with heredoc semantics rather than matching text. `json.load(sys.stdin)`
is correct under `python3 -c`, where the program comes from argv and stdin really is the
payload — ci-queue-wait.sh uses that form legitimately in gitea_get_branch_head_sha. A
flat grep flags that innocent site; the scanner names only the two defective ones.

Out of scope, deliberately, and recorded on #1019: token-in-argv (ps-visible) and the
hardcoded BRANCH="main". Bundling them would make a safety-critical parse fix harder to
review.

Refs #1019
mos-dt-0 added 1 commit 2026-07-31 16:43:37 +00:00
Both sides edited the single `test:framework-shell` line additively and did not
overlap: main prepended the test-enumeration guard pair
(check-test-enumeration.sh, test-check-test-enumeration.sh); this branch inserted
test-ci-queue-wait-parse.sh after test-ci-queue-wait-branch-absent.sh.

Resolved as the union — main's line with this branch's one insertion restored.
Main's new guard makes that insertion mandatory rather than cosmetic: the test
file ships in this branch, so leaving it unenumerated would fail the guard.

Co-authored-by: mos-dt-0 <[email protected]>
rev-974 requested changes 2026-07-31 20:43:21 +00:00
rev-974 left a comment
Collaborator

CHANGES-REQUESTED at exact head f6334080 (full f63340802c). Independent diff-blind review; checks were pre-registered before inspecting the diff.

Blocking findings:

  1. Check 3 FAIL — unknown still exits 0. Malformed JSON maps to unknown, but ci-queue-wait.sh:291-293 groups unknown with terminal states and exits 0; lines 295-297 also fail open. The core defect #1019 claims to fix is therefore NOT fixed: parser/provider ambiguity can still pass the mandatory gate-6 guard.
  2. Check 4 FAIL — the payload-via-environment approach remains subject to exec argument/environment limits. An exact-head probe with a valid 150 KiB JSON payload failed to exec Python with rc=126 and Argument list too long (ARG_MAX/MAX_ARG_STRLEN). Use transport not bounded as one exec string, such as a temporary file or separate file descriptor.
  3. Check 6 FAIL — tests do not assert guard exit outcomes. The suite checks parser-returned strings and expects malformed input to return unknown, but never executes/asserts the production guard control flow, so all 14 tests pass while malformed input still makes the guard exit 0. Required behavioral coverage must assert pass/block exit behavior for pending, success, failure, no-status, and malformed JSON.

Adjudication: checks 1 and 2 pass; check 5 passes for parity with the sibling remedy; checks 3, 4, 6, and therefore 7 fail. Evidence: committed parser suite 14/14 passed; bash syntax passed; exact-head 150 KiB payload probe failed rc=126. Verdict: CHANGES-REQUESTED.

CHANGES-REQUESTED at exact head f6334080 (full f63340802cd058ba75d735fcfbc3288ca0927ded). Independent diff-blind review; checks were pre-registered before inspecting the diff. Blocking findings: 1. Check 3 FAIL — `unknown` still exits 0. Malformed JSON maps to `unknown`, but ci-queue-wait.sh:291-293 groups `unknown` with terminal states and exits 0; lines 295-297 also fail open. The core defect #1019 claims to fix is therefore NOT fixed: parser/provider ambiguity can still pass the mandatory gate-6 guard. 2. Check 4 FAIL — the payload-via-environment approach remains subject to exec argument/environment limits. An exact-head probe with a valid 150 KiB JSON payload failed to exec Python with rc=126 and `Argument list too long` (ARG_MAX/MAX_ARG_STRLEN). Use transport not bounded as one exec string, such as a temporary file or separate file descriptor. 3. Check 6 FAIL — tests do not assert guard exit outcomes. The suite checks parser-returned strings and expects malformed input to return `unknown`, but never executes/asserts the production guard control flow, so all 14 tests pass while malformed input still makes the guard exit 0. Required behavioral coverage must assert pass/block exit behavior for pending, success, failure, no-status, and malformed JSON. Adjudication: checks 1 and 2 pass; check 5 passes for parity with the sibling remedy; checks 3, 4, 6, and therefore 7 fail. Evidence: committed parser suite 14/14 passed; bash syntax passed; exact-head 150 KiB payload probe failed rc=126. Verdict: CHANGES-REQUESTED.
Collaborator

CHANGES-REQUESTED at exact head f6334080 (full f63340802c). Independent diff-blind review; checks were pre-registered before inspecting the diff.

Blocking findings:

  1. Check 3 FAIL — unknown still exits 0. Malformed JSON maps to unknown, but ci-queue-wait.sh:291-293 groups unknown with terminal states and exits 0; lines 295-297 also fail open. The core defect #1019 claims to fix is therefore NOT fixed: parser/provider ambiguity can still pass the mandatory gate-6 guard.
  2. Check 4 FAIL — the payload-via-environment approach remains subject to exec argument/environment limits. An exact-head probe with a valid 150 KiB JSON payload failed to exec Python with rc=126 and Argument list too long (ARG_MAX/MAX_ARG_STRLEN). Use transport not bounded as one exec string, such as a temporary file or separate file descriptor.
  3. Check 6 FAIL — tests do not assert guard exit outcomes. The suite checks parser-returned strings and expects malformed input to return unknown, but never executes/asserts the production guard control flow, so all 14 tests pass while malformed input still makes the guard exit 0. Required behavioral coverage must assert pass/block exit behavior for pending, success, failure, no-status, and malformed JSON.

Adjudication: checks 1 and 2 pass; check 5 passes for parity with the sibling remedy; checks 3, 4, 6, and therefore 7 fail. Evidence: committed parser suite 14/14 passed; bash syntax passed; exact-head 150 KiB payload probe failed rc=126. Verdict: CHANGES-REQUESTED.

CHANGES-REQUESTED at exact head f6334080 (full f63340802cd058ba75d735fcfbc3288ca0927ded). Independent diff-blind review; checks were pre-registered before inspecting the diff. Blocking findings: 1. Check 3 FAIL — `unknown` still exits 0. Malformed JSON maps to `unknown`, but ci-queue-wait.sh:291-293 groups `unknown` with terminal states and exits 0; lines 295-297 also fail open. The core defect #1019 claims to fix is therefore NOT fixed: parser/provider ambiguity can still pass the mandatory gate-6 guard. 2. Check 4 FAIL — the payload-via-environment approach remains subject to exec argument/environment limits. An exact-head probe with a valid 150 KiB JSON payload failed to exec Python with rc=126 and `Argument list too long` (ARG_MAX/MAX_ARG_STRLEN). Use transport not bounded as one exec string, such as a temporary file or separate file descriptor. 3. Check 6 FAIL — tests do not assert guard exit outcomes. The suite checks parser-returned strings and expects malformed input to return `unknown`, but never executes/asserts the production guard control flow, so all 14 tests pass while malformed input still makes the guard exit 0. Required behavioral coverage must assert pass/block exit behavior for pending, success, failure, no-status, and malformed JSON. Adjudication: checks 1 and 2 pass; check 5 passes for parity with the sibling remedy; checks 3, 4, 6, and therefore 7 fail. Evidence: committed parser suite 14/14 passed; bash syntax passed; exact-head 150 KiB payload probe failed rc=126. Verdict: CHANGES-REQUESTED.
All checks were successful
ci/woodpecker/pr/ci Pipeline was successful
This pull request has changes conflicting with the target branch.
  • packages/mosaic/framework/tools/git/ci-queue-wait.sh
  • packages/mosaic/package.json
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin fix/1019-queue-guard-stdin:fix/1019-queue-guard-stdin
git checkout fix/1019-queue-guard-stdin
Sign in to join this conversation.
No Reviewers
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mosaicstack/stack#1023