Files
stack/docs/scratchpads/1099-pipefail-sweep.md
T
f10-coderandMos b0f7d26dd9
ci/woodpecker/push/publish Pipeline failed
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/manual/ci-image Pipeline failed
ci/woodpecker/manual/publish Pipeline failed
ci/woodpecker/manual/ci Pipeline was successful
fix(shell): remove test harness pipe hazards (#1106)
Co-authored-by: f10-coder <[email protected]>
2026-08-07 11:12:17 +00:00

2.9 KiB

#1099 — pipefail + early-exit sweep

Scope and decisions

  • Baseline df4c591ab42aa1ae62c12935fdc0e772684864a0, after #1100 removed its 35 sites.
  • Split into review-sized non-closing tranches: runtime/general; tmux/git/quality tests; wake validation/tests.
  • Do not equate class membership with demonstrated risk. Do not use payload size or pipeline stage count as a safety proxy.
  • Preserve the issue's withdrawn findings for qa-hook-stdin.sh and the two fresh-directory pnpm pack lookups. Fix install.sh:312 because malformed multi-root input must reach its named handler.

Tranche 1 TDD

RED-first control: node --test scripts/pipefail-early-exit.test.mjs reported exactly 26 non-accepted runtime/general sites, including install.sh:312, and exited 1. A checked-in fixture generated from immutable baseline df4c591a records all 26 normalized sites; the control passes every fixture entry through the same scanner, asserts exact identity/count/uniqueness, and separately requires zero findings in the current tree. It also inventories accepted sites rather than silently excluding whole files.

Construction choices:

  • here-string/file redirection for scalar grep assertions;
  • full capture then parameter expansion for first-line selection;
  • arrays/mapfile for complete populations;
  • direct jq/awk/grep selection where one tool can express the property;
  • no || true added to a load-bearing assertion.

Site-by-site verdicts: docs/reports/quality/1099-pipefail-sweep.md.

Tranche 2 TDD

Expanded the unconditional scanner over 11 non-wake test harnesses. RED named exactly 22 source lines; a second immutable-baseline fixture now asserts those 22 entries through the same scanner. Rewrites preserve command status by capturing producers before redirected assertions, use parameter expansion for line selection, and use complete mapfile populations where ordering matters. Current-tree finding count is zero for tranches 1 and 2.

Verification so far

  • bash -n on every changed shell script: pass.
  • structural Node control: pass.
  • test-mutate-push-guard.sh: 8/8 pass.
  • test-send-message-verdict.sh: 3/3 pass.
  • test-send-message-socket.sh: pass.
  • Independent review 143 found two semantic regressions: a help-probe || true changed the failure truth table, and an unguarded Git capture changed non-Git data-dir behavior from rc 0 + JSON to silent rc 128. Both received RED-first regressions before correction; help status is now separate and required, and Git status remains condition-guarded.
  • Wake detector/reconcile/digest/preimage suites terminate at their existing fail-closed #973 BASH_LINENO environment probe (exit 97, observed [3 5], expected [3 4]) before subject tests. No bypass or skip was used; canonical CI remains required.
  • ShellCheck reports only pre-existing source-following, unused-variable, and untouched ls | head findings; no new diagnostic was introduced.