Skip to content

[finding] Sibling copies of the wrong-pipe-shape exit-code advisory survive #12979: five more banners name | tail and leave | head — the shape that defeats PIPESTATUS/pipefail — unnamed #13429

Description

@zhuangjianguo

Filed unassigned by the #12979 dev, session session_01EXxTW8mvPBhoHxmyPZ63de, while fixing that card (PR #13427). Out of scope there: the 2026-08-28 grading on #12979 permitted exactly one cross-domain half (scripts/check-i18n-bundles.mjs); these are the remaining copies of the same wrong fact. #12979 is not addressed here beyond that pointer, and PR #13427 does not touch these files.

Census (git grep on 9f1652c, the #12979 fix branch head; line numbers from that tree)

Exact copies of the corrected banner's old text, still claiming | tail -4 "reads green either way":

  • scripts/import-prerequisite.mjs:409 — HIGH LEVERAGE: this is the shared prerequisite-banner module; every gate script that imports it inherits the wrong advisory line verbatim (the printed text interpolates the calling gate's name via scripts/${gate}.mjs).
  • scripts/check-i18n-coverage.mjs:1137, :1192, :1221
  • scripts/pm/check-half-states.mjs:7597
  • scripts/pm/ci-failure.mjs:1540, :2424 (phrased "Piping reports the PIPE's status, so backticked dot-dot-dot pipe tail reads green either way")
  • scripts/check-test-completeness.mjs:481-483 — half-corrected variant: it already says capture the exit code BEFORE any pipe (good), but still names only | tail -4 as the lying shape and leaves | head unnamed.

Not a copy, do not touch: docs/qa/platform-checklist/areas/attachments-storage.json:359 uses the phrase "reads green either way" about a fixture clause, unrelated to pipes.

Why these mislead (measured, #12979 and re-measured on 94efa2a)

  • For a reader using bare $? after the pipe, the claim is literally true — $? is the pipe's status.
  • For a reader following the os-dev discipline (now: redirect-then-capture; formerly PIPESTATUS[0]), | tail -4 forwards the TRUE status (measured: 1 on a refusing gate) — so the advisory names the safe shape as the dangerous one.
  • The shape that actually lies to every reader, | head -N, is unnamed in all of these: head closes the read end early, the producer takes EPIPE/SIGPIPE and exits 0, so even PIPESTATUS[0] and set -o pipefail read green (measured: 0 on the same refusing gate). An agent steered away from tail toward head gets the only false green there is.

Suggested shape

Same fix the #12979 grading prescribed and PR #13427 applied to check-i18n-bundles.mjs: name the true hazard (| head -N, with the EPIPE mechanism), name the safe capture (redirect-then-capture, exit code taken before any pipe), and do not reduce it to "do not pipe". Fixing scripts/import-prerequisite.mjs:409 corrects every importer in one edit; the literal copies in the other four files need their own lines. Each of those gate scripts has a self-test (--self-test) that must stay green, and none of the edits may change exit codes.

Severity not judged; the banners only mislead humans and agents reading refusal output — no gate verdict is computed from them.

Metadata

Metadata

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions