fix(merge): round-2 CI failures — pipefail sites, verify:release mirror, format
ci/woodpecker/pr/ci Pipeline failed

Pipeline 2534 (018d96a), two test-step failures plus the format failure
root-caused by rev-code-01 (id 202):

1. pipefail-early-exit.test.mjs: main's window wrote the test but never
   wired scripts/*.test.mjs into its own CI, so its tools/install.sh pipes
   were never executed against it; next's test wiring runs them and flags
   two load-bearing pipes. Both rewritten pipefail-safe via process
   substitution (newest_matching_file ls|head, check_fleet_transport
   sed|head|tr|awk). Test now 7/7 locally.

2. verify-release.test.mjs: merge kept main's 9-command ci.yml sanitization
   but next's 4-command canonical stage. Canonical updated to mirror ci.yml
   exactly (9=9, order verified). upgrade-guard checked equal (4=4).

3. format: docs/reports/quality/1099-pipefail-sweep.md (from main f158be8)
   prettier-formatted under pinned 3.8.1.

Enumeration guard re-verified: population 60, enumerated 45, excluded 16.
This commit is contained in:
2026-08-19 17:27:30 -05:00
parent 018d96a412
commit 2508f0aa99
3 changed files with 82 additions and 64 deletions
+8 -8
View File
@@ -7,7 +7,7 @@ This is a site inventory, not a risk count. `FIXED` means the early-exiting cons
## Tranche 1 — runtime and general scripts
| Baseline site | Verdict | Construction / reason |
| --- | --- | --- |
| ------------------------------------------------------------------- | ------- | ---------------------------------------------------------------------------------------- |
| `tools/matrix-presence-harness/run.sh:38` | FIXED | nullglob array selects the first path; no pipeline |
| `tools/e2e-install-test.sh:139` | FIXED | capture help completely, then grep via redirection |
| `tools/install.sh:312` | FIXED | NUL `mapfile` reads all roots; count != 1 reaches the named malformed-archive diagnostic |
@@ -38,13 +38,13 @@ This is a site inventory, not a risk count. `FIXED` means the early-exiting cons
## Explicit withdrawn / non-load-bearing sites
| Baseline site | Verdict | Reason |
| --- | --- | --- |
| `tools/install.sh:182` | NOT-LOAD-BEARING | `|| true` explicitly discards lookup status |
| ---------------------------------------------------------------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------- | --- | --------------------------------------- |
| `tools/install.sh:182` | NOT-LOAD-BEARING | ` | | true` explicitly discards lookup status |
| `tools/install.sh:356` | UNREACHABLE-AND-WHY | `pnpm pack` writes one matching CLI tarball into a fresh directory immediately before lookup; citation withdrawn in #1099 |
| `tools/install.sh:357` | UNREACHABLE-AND-WHY | same fresh-directory invariant for gateway tarball; citation withdrawn in #1099 |
| `tools/install.sh:627` | NOT-LOAD-BEARING | `|| true` explicitly discards lookup status |
| `scripts/agent/session-start.sh:70` | NOT-LOAD-BEARING | optional scratchpad lookup has `|| true` |
| `packages/mosaic/framework/templates/repo/scripts/agent/session-start.sh:58` | NOT-LOAD-BEARING | optional scratchpad lookup has `|| true` |
| `tools/install.sh:627` | NOT-LOAD-BEARING | ` | | true` explicitly discards lookup status |
| `scripts/agent/session-start.sh:70` | NOT-LOAD-BEARING | optional scratchpad lookup has ` | | true` |
| `packages/mosaic/framework/templates/repo/scripts/agent/session-start.sh:58` | NOT-LOAD-BEARING | optional scratchpad lookup has ` | | true` |
| `packages/mosaic/framework/tools/qa/qa-hook-stdin.sh:25` | UNREACHABLE-AND-WHY | withdrawn in #1099 after designed-input reachability measurement; preserved without re-litigation |
| `packages/mosaic/framework/tools/qa/qa-hook-stdin.sh:27` | UNREACHABLE-AND-WHY | same withdrawn designed-input finding |
| `packages/mosaic/framework/tools/qa/qa-hook-stdin.sh:30` | UNREACHABLE-AND-WHY | same withdrawn designed-input finding |
@@ -56,7 +56,7 @@ This is a site inventory, not a risk count. `FIXED` means the early-exiting cons
All 22 baseline sites below are `FIXED`; the checked-in tranche fixture is passed through the same scanner and asserts all 22 occurrences and 21 normalized identities (the same response-split line occurs twice).
| Baseline site(s) | Verdict | Construction |
| --- | --- | --- |
| ------------------------------------------------------ | ------- | ------------------------------------------------------------- |
| `systemd/user/test-fleet-units.sh:148` | FIXED | capture tmux output, then grep via redirection |
| `git/test-issue-comment-readback.sh:283,302` | FIXED | parameter expansion splits status/body without `head` |
| `git/test-pr-review-gitea-comment.sh:228` | FIXED | parameter expansion splits status/body |
@@ -74,7 +74,7 @@ All 22 baseline sites below are `FIXED`; the checked-in tranche fixture is passe
All 26 baseline occurrences (25 normalized identities; one preimage selector occurs twice) are `FIXED` and mechanically bound through the wake fixture and shared scanner.
| Baseline site(s) | Verdict | Construction |
| --- | --- | --- |
| -------------------------------------------------------------------------------------------- | ------- | -------------------------------------------------------------------------------------------------------------- |
| `wake/test-wake-digest-quarantine.sh:567` | FIXED | complete match populations are captured, then first line selected by parameter expansion |
| `wake/test-wake-preimage.sh:182-183,346-347` | FIXED | jq `first(...)` reads each JSONL file directly |
| `wake/validate-973/microtest-wake-assert.sh:153,170-171,176,204-209,233-234,251-252,286-287` | FIXED | scalar assertions use here-strings; diagnostics use non-early sed ranges; source line captured before matching |
+5
View File
@@ -58,6 +58,11 @@ export const STAGES = [
'bash packages/mosaic/framework/tools/quality/scripts/check-resident-budget.sh --self-test',
'bash packages/mosaic/framework/tools/quality/scripts/check-resident-budget.sh',
'bash packages/mosaic/framework/tools/quality/scripts/check-test-enumeration.sh',
'bash packages/mosaic/framework/tools/quality/scripts/check-tools-index.sh --self-test',
'bash packages/mosaic/framework/tools/quality/scripts/check-tools-index.sh',
'bash packages/mosaic/framework/tools/git/test-issue-close-fail-closed.sh',
'bash packages/mosaic/framework/tools/git/test-wrapper-guard.sh',
'bash packages/mosaic/framework/tools/git/test-mosaic-worktree-large-repo.sh',
],
},
{
+16 -3
View File
@@ -161,7 +161,11 @@ newest_matching_file() {
shopt -u nullglob
[[ "${#matches[@]}" -gt 0 ]] || return 0
# shellcheck disable=SC2012 # Need portable mtime sorting across Linux/macOS.
ls -1t "${matches[@]}" 2>/dev/null | head -1
# pipefail-safe: take the first line via process substitution; piping into
# an early-exiting consumer would inherit ls's exit status under pipefail (#1099).
local newest=""
while IFS= read -r newest; do break; done < <(ls -1t "${matches[@]}" 2>/dev/null)
if [[ -n "$newest" ]]; then printf '%s\n' "$newest"; fi
}
# ─── uninstall path ───────────────────────────────────────────────────────────
@@ -413,10 +417,19 @@ check_fleet_transport() {
local declared=""
if [[ -f "$roster" ]]; then
declared="$(sed -n 's/^[[:space:]]*transport:[[:space:]]*//p' "$roster" | head -1 |
tr -d '"'\''' | tr -d '\r' | awk '{print $1}')"
# pipefail-safe: consume the first match via process substitution, then
# strip quotes/CR and keep the first field without piping into a consumer (#1099).
local first_transport=""
while IFS= read -r first_transport; do break; done < \
<(sed -n 's/^[[:space:]]*transport:[[:space:]]*//p' "$roster")
if [[ -n "$first_transport" ]]; then
declared="${first_transport//\"/}"
declared="${declared//\'/}"
declared="${declared//$'\r'/}"
declared="${declared%%[[:space:]]*}"
[[ -n "$declared" ]] && transport="$declared"
fi
fi
command -v "$transport" &>/dev/null && return 0