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

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions