fix(scripts): make the three host-dependent scripts/__tests__ files run on a stock macOS host - #8511
Conversation
… run on a stock macOS host
Three files in `scripts/__tests__` passed on Linux CI and failed on a stock
macOS host on byte-identical bytes. None of the four assertions was about the
tree; each read a host command or a host behaviour.
check-bash32-floor `--self-test` — the sharpest of the three, and fixed in the
GATE rather than in the test that runs it. Every probe, harness and `bash -n`
leg drives a bash-4+ construct through the host's own bash, and the host this
gate exists for is macOS: bash 3.2.57, where `coproc`/`|&`/`&>>` are syntax
errors, `mapfile` is not a builtin there is anything to disable, and `[[ -v ]]`
is a conditional operator `bash -n` also refuses. A floor gate whose battery
cannot run on the floor it declares is a gate asserting something it has never
demonstrated. The self-test now states that premise, detects it by CAPABILITY
(a bash-4 operator and a bash-4 builtin, never a platform name), and narrows
exactly those cases where the host cannot judge them — counted, printed per
case, and carried in the verdict line, because a narrowing is a real coverage
loss. The SCAN is untouched and is not narrowed: it is pure JS and judges a 3.2
host exactly as it judges CI.
check-control-bytes — `expect(declined.stdout).toBe('')` asserted one userland's
way of reporting a refusal rather than the refusal. GNU grep >= 3.5 writes
`grep: <f>: binary file matches` to stderr and leaves stdout empty; BSD grep
writes `Binary file <f> matches` to stdout. Both refuse and both print no line
of the file, which is the search outage the case is about, so the assertion is
now written against matching lines. A shim first on PATH pins the BSD reading
here on Linux.
ensure-chromium-ready.sh — a bare `timeout` is GNU coreutils, and a stock macOS
host has neither it nor Homebrew's `gtimeout`. The bound did not merely go
missing there: the call failed at 127 before `install-deps` ran, so the recovery
path could not recover. `run_bounded` resolves `timeout`, then `gtimeout`, then
bounds the call from bash itself (bash 3.2 clean, as this repo's floor requires)
and reports the same 124 either way. Two cases run under a PATH where both
binaries are genuinely absent, with a control that proves they are.
⛔ Nothing is skipped, disabled or quarantined, and no assertion is weakened to
accommodate a host: the GNU paths are still measured by the same cases on the
same run.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhBNJcLRZLe8M87VcUgpKr
|
Dequeued 04:48:06Z on a failure this diff cannot reach; re-queued 06:31:07Z — the one re-queue this PR gets.
⛔ Not this PR's, settled structurally rather than by countingThis diff is ⭐ objectui#8493 has now dequeued three PRs whose diffs cannot reach it: #8462 (two comment blocks), #8486 (a What happens next, stated in advance so it is not a judgement call laterRe-queued once, at 06:31:07Z. ⛔ If it is dequeued a second time on the same case, this PR stops there — no third attempt. This seat will say so on objectui#8493 rather than keep re-queueing, because a required check that dequeues on a case no diff can reach is that card's problem to fix, not something to out-wait. ⛔ Nothing about this branch changes meanwhile: no rebase, no force-push, no edit. The head that was green on 28 checks is the head that is queued. Generated by Claude Code |
|
Dequeued a second time on the same case ⇒ this PR stops here, exactly as committed above. The reading, from the job logs rather than from the field
Both logs read Why this is not this PR's failure, argued structurally⭐ The case failed at 2026-09-08T01:09:52Z on PR #8462 — a diff of two comment blocks — before this branch was ever queued. A defect that predates a diff cannot have been introduced by it. That row alone settles it; the supporting reading is that this PR's four files are all under ⇒ Attribution here is structural — whether the diff can reach the failing code — ⛔ not a count of failures. What this seat did, and did not do
What unblocks itobjectui#8493 landing its repair — the patch shape is already written there (wait on the rows each arm asserts about, ⛔ without collapsing the negative arm into a tautology). That work is Generated by Claude Code |
|
The blocker was repaired on What changed, measured on a re-fetched
|
|
LANDED — ⭐ The re-queue decision is now measured, not argued. This PR was dequeued twice on a defect its diff cannot reach; the third attempt, on a base carrying Landing probe, on a re-fetched
|
| probe | expect | read |
|---|---|---|
HOST_PROBES in scripts/check-bash32-floor.mjs |
> 0 | 6 |
SELF_TEST_BATTERY_FLOOR in the same file |
> 0 | 3 |
run_bounded in scripts/ensure-chromium-ready.sh |
> 0 | 3 |
there is no fourth branch — the fence forbidding an unbounded fallback |
> 0 | 1 |
⭐ firing control — bash in the same shell script, same command shape |
> 0 | 8 |
⭐ nonsense control — zzq-not-a-real-token-8404 |
0 | 0 |
⇒ The zero is a reading: the same command returns 8 on a term that is certainly there.
What is now on main
The three host-dependent scripts/__tests__ files run on a stock macOS host, and — the part that matters more than the portability — the gate was fixed rather than the test. Capability is detected by probing the host (echo a |& cat for the grammar, mapfile -t x < /dev/null for the builtin) instead of by platform name, the narrowing is pinned in both directions, and run_bounded resolves timeout → gtimeout → a bash-only bound with the fence "there is no fourth branch that runs the command unbounded" written into the file.
Generated by Claude Code
Fixes #8404
Three files under
scripts/__tests__passed on Linux CI and failed on a stock macOS host on byte-identical bytes. None of the four assertions was about the tree; each read a host command or a host behaviour. All three are repaired at the end that is actually wrong, and none is skipped, disabled, quarantined or weakened.Re-derivation before the fix
origin/main(f08d1a86a): blobsd8e51c6c0,9624b91d6,a52bec87dmatchorigin/mainexactly. The card's measured head21b1bf51fis no longer an object in this repository, so the comparison is againstorigin/mainas it stands.check-bash32-floor.mjs --self-test. Its⭐ and the probes are real shellbattery runsbash -nover every row ofCONSTRUCTS, and every row is by declaration a construct above the bash 3.2 floor this gate declares. The card's three syntax errors — a brace, an ampersand, a redirect — line up one-for-one and with nothing left over against the three parse-level4.0rows:coproc CO { cat; },echo a |& cat,echo hi &>> /dev/null. Two further legs have the same premise and are named in the diff: the[[ -v ]]parse case (this file already records thatbash -njudges[[operators) and themapfilesimulated-3.2 harness, which needs a host that HASmapfileto remove.expect(declined.stdout).toBe('')is the only host-dependent line. The discriminator is not the platform, it is which stream grep writes its refusal to, so a grep that writes the BSD spelling to stdout reproduces it exactly. Demonstrated here on Linux with a shim first on PATH.timeoutis GNU coreutils. Demonstrated on Linux under a PATH wheretimeoutandgtimeoutare genuinely absent, againstorigin/main's own script: exit 1, the dependency-install marker never created,install-depsnever reached. That is a defect in the script, not only in its test — the bound did not go missing, the call failed at 127 before the recovery could recover.What changed
scripts/check-bash32-floor.mjs— the gate, not the test that runs it. A floor gate whose battery cannot run on the floor it declares is a gate asserting something it has never demonstrated.--self-testnow states that premise, detects it by capability (one bash-4 operator and one bash-4 builtin — never a platform name), and narrows exactly the cases a host below the floor cannot judge. A narrowing is a real coverage loss, so it is printed per case, counted, and carried in the verdict line. ⛔ The scan is untouched and never narrowed: it is pure JS and judges a 3.2 host exactly as it judges CI. A new battery pins the mechanism in both directions, refuses a platform-name branch on any code line, and requires the two capability probes to be constructs this gate's own table declares above the floor.scripts/__tests__/check-control-bytes.test.ts. The search outage is "grep printed no line of the file", and the refusal itself is already pinned byrefusedAsBinarybeside it. The assertion is now written against matching lines rather than against an empty stdout, and a shim standing in for BSD grep pins the other userland here, on Linux, on every run.scripts/ensure-chromium-ready.sh.run_boundedresolvestimeout, thengtimeout, then bounds the call from bash itself and reports the same124either way. ⛔ There is no fourth branch that runs the command unbounded. The fallback is bash 3.2 clean, as this repo's own floor gate requires, andcheck:bash32-flooris green on it.Non-vacuity — four ablations, each proved on disk and restored by state
Every leg mutated one file, proved the mutation reached disk by blob hash and marker count before reading any result, ran under an
EXIT INT TERMtrap with absolute paths, and was restored withgit checkout HEAD -- PATH, proven bygit diff HEADbeing empty. Full logs are in the run.CONSTRUCTSprobe made unparseable (coproc CO { cat; }tocoproc CO { cat; ;}), blob539666d3ctoe711fca4a✗ coproc: the probe is shell a bash-4 parser accepts— the preserved leg still fails when broken539666d3ctodb03ee0e7136 cases pass, 24 NARROWED; the wiring test is green (9 passed) — the macOS branch, end to endtoBe(''), blobd04cc4775toff3b125f71 failed / 37 passed) — the macOS failure, reproduced on Linuxrun_boundedreverted to a baretimeout, blobf235f5377to432e35b902 failed / 7 passed), the GNU cases stay greenPaired control, same stimulus on both trees. Three probes made unparseable — which is what a bash 3.2 host does to them: on
origin/main's gate, self-test exit 1, 3 failing cases of 155. On this branch's gate with the same three plus the capability probe a floor host also refuses, self-test exit 0,136 cases pass, 24 NARROWED, 0 failing.Verification
pnpm exec vitest run scripts/__tests__/Test Files 121 passed (121)·Tests 3634 passed (3634)(the card's own population; 52 to 56 tests across the three files, +4 new)node scripts/check-bash32-floor.mjs --self-test✓ check-bash32-floor self-test: 160 cases pass.(155 before; +5 new cases)node scripts/check-bash32-floor.mjs✓ ... 12 tracked shell file(s) ... name no bash 4+ constructnode scripts/check-control-bytes.mjs✅ check-control-bytes: OK (scanned 6724 tracked text file(s); skipped 85 binary)node scripts/check-changeset-presence.mjs✅ No source or published contract of a released package changed in this range, so no changeset is owed.— run, not guessed; no changeset is addednode scripts/check-governed-queue-guard.mjs --test(4 paths)✅ NOT GOVERNED — 4 path(s) checked against 5 governed surface(s); none matched.pnpm exec tsc -p tsconfig.scripts.jsonpnpm lint:root✖ 32 problems (0 errors, 32 warnings)— full root scope, no narrowing; none of the 32 is in a changed filegrep -naPcontrol-byte self-scan over the four changed filesHeavy runs went through the shared verify lock and the wrapper's own
VERDICT command-exitline was read, never a bare$?.Limits, stated rather than discovered later
ftp.gnu.organd cross-owner GitHub repositories, so no bash 3.2 could be obtained or built here. Ablation B simulates a floor host by making the capability probe unparseable, which is exactly what a 3.2 parser does to it, but it is a simulation.EPOCHSECONDSlegs are left un-narrowed on reasoning, not measurement. On bash 3.2 the variable is genuinely absent, sounsetplusset -ushould produce the same unbound failure those two cases assert. If a macOS seat still sees them red, that is the one remaining leg and it narrows the same way in one line.git grep -Ehas no\bon macOS (BSD regex), so all five assertions go red locally while CI is green #8361 was not touched. Triage drew that boundary explicitly: same class, different package, its own card.🤖 Generated with Claude Code
Generated by Claude Code