From 4989bd55f740e3b4a495403f93a3e6dbfb21cf2b Mon Sep 17 00:00:00 2001 From: Edward Langley Date: Wed, 23 Sep 2026 23:14:30 -0700 Subject: [PATCH] checkers-test: run section 5b on the hermetic utilbin PATH Section 5b (the bash 5.1 floor, #237) was written on a branch cut before the NixOS-runner change (af44653f). That change moved section 5 off /usr/bin:/bin, because on NixOS that path holds only env and sh. The two merged with no conflict. On NixOS the runner then dies on `dirname` with exit 1, which turned the KB job red on every PR at 666de199. 5b now uses utilbin too, and utilbin gains head and env for the 5.1 control. Evidence and rivals: context/test-evidence/tooling.md. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze --- context/test-evidence/tooling.md | 30 ++++++++++++++++++++++++++++++ scripts/checkers-test.sh | 7 ++++--- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/context/test-evidence/tooling.md b/context/test-evidence/tooling.md index 32bc4846..cda31503 100644 --- a/context/test-evidence/tooling.md +++ b/context/test-evidence/tooling.md @@ -1048,3 +1048,33 @@ scanned" alone, so the deleted-file case is what stops the fix from over-refusing. The rival ran from an ignored copy inside the worktree. A copy under `/tmp` fails "the real tree does not pass against a silent bd" for a reason unrelated to the rival: there is no repository there. + +### Section 5b runs on a hermetic PATH — `scripts/checkers-test.sh` + +**What broke.** Every PR's "Knowledge base consistency" job went red at +`666de199` with "a bash 5.0 with no nix is exit 3, not 5.x (exit 1, wanted 3)" +and "a bash 5.1 is accepted (exit 1, wanted 0)". Neither PR alone was wrong. The +NixOS-runner change (`af44653f`) found that `/usr/bin:/bin` on NixOS holds only +`env` and `sh`, so the runner dies on `dirname` with exit 1. It fixed section 5 +by moving it to a `utilbin` of linked tools. #237 (`e45a9c42`) added section 5b +on its own branch, with the old `PATH=$work/fakebin:/usr/bin:/bin`. The two +merged with no conflict, and each had passed CI only on its own side. + +**Reproduced** on macOS by running both 5b invocations with `/usr/bin:/bin` +replaced by a directory holding only `env` and `sh`. Both exited 1 on +`dirname: command not found`. Those are the CI exits. + +**Fix.** 5b uses `utilbin` as well. `utilbin` gains `head` and `env`, because +the 5.1 control runs past the version check into `check_shebangs` and +`run_suite`. + +**Rivals**, each run in the suite: +- **`dirname` left out of `utilbin`** fails all three section-5 cases with the + exact CI pair: exit 1 where 3 was wanted, and exit 1 where 0 was wanted. The + NixOS failure now reproduces on any host, because no case reads the host's + `/usr/bin` any more. +- **`env` left out** fails "a bash 5.1 is accepted" alone. +- **`head` left out** fails nothing. `check_shebangs` calls `head` inside + `check_shebangs || rc=1`, where `set -e` is off. A missing `head` makes every + first line empty, and the shebang check then passes without checking + anything. That is a defect in `checkers.sh` and is not fixed here. diff --git a/scripts/checkers-test.sh b/scripts/checkers-test.sh index a3995f55..67a9b846 100755 --- a/scripts/checkers-test.sh +++ b/scripts/checkers-test.sh @@ -136,9 +136,10 @@ chmod +x "$work/fakebin/bash" # utilbin carries only the utilities the runner itself needs, and no nix, so # the fake bash is the only candidate and the nix fallback is absent. Linked # one by one rather than taking /usr/bin:/bin, which on NixOS hold only `env` -# and `sh` -- the runner died on `dirname` there, exit 1 instead of 3. +# and `sh` -- the runner died on `dirname` there, exit 1 instead of 3. `head` +# and `env` are for 5b's 5.1 control, which runs past the version check. mkdir -p "$work/utilbin" -for tool in dirname; do +for tool in dirname head env; do ln -sf "$(command -v "$tool")" "$work/utilbin/$tool" done env PATH="$work/fakebin:$work/utilbin" HOME="$HOME" \ @@ -154,7 +155,7 @@ for v in "5 0:3:a bash 5.0 with no nix is exit 3, not 5.x" \ printf '#!/bin/sh\ncase "$*" in *BASH_VERSINFO*) echo %s; exit 0 ;; esac\nexit 0\n' \ "${v%%:*}" > "$work/fakebin/bash" want="${v#*:}"; name="${want#*:}"; want="${want%%:*}" - env PATH="$work/fakebin:/usr/bin:/bin" HOME="$HOME" \ + env PATH="$work/fakebin:$work/utilbin" HOME="$HOME" \ "${BASH:-bash}" "$d/checkers.sh" any > "$work/out" 2>&1 got=$? [ "$got" = "$want" ] && ok "$name" || bad "$name" "exit $got, wanted $want"