macOS ships bash 3.2 as /bin/bash, which `#!/usr/bin/env bash` resolves to
when no newer bash is on PATH. Two builtins the repo relies on do not exist
there, and both failed SILENTLY:
- `mapfile` in the three surgical-commit helpers left every array empty, so
the scope guards passed on nothing (fail-OPEN) and the commits degraded to
"nothing pending — no-op" while reporting success. deploy-commit.test.sh
went 4/16; memory and doc commits simply never happened.
- `declare -A` in the session-start hook errored on every session and left
each plugin cost at 0, so the passive-budget warning could never fire.
`_read_lines_into` is the portable equivalent of `mapfile`, space-safe and
resetting its target first — expanding a never-assigned array trips `set -u`
on bash < 4.4, which is how the empty arrays surfaced as "unbound variable".
Plugin costs move to a `case`.
source-scope.sh's header prescribed `mapfile` to its callers; it now shows
the read loop, and its own test plus run-reconcile.sh stop using the builtin.
deploy-commit 16/16, source-scope 34/34, run-reconcile 25 GREEN / 0 RED,
session-start stderr empty.
`${1,,}` is bash 4.0+. macOS ships bash 3.2 as /bin/bash, where it raises
"bad substitution"; the subshell then exited 1 — read as "not local" — so
`url-guard.sh host` returned rc 0 for localhost, 127.x, 10.x, 192.168.x,
172.16-31.x, 169.254.169.254 and metadata.google.internal. The guard failed
OPEN on every Mac, and url-guard.test.sh recorded it as 13 "got[0] want[2]".
`shopt -s nocasematch` (bash 3.1+) keeps both the ASCII-only folding that
LC_ALL=C gives and the no-fork property the lowercase expansion had.
Verified on /bin/bash 3.2: the ten local/private/metadata targets now return
rc 2 (case-folded variants included), legitimate hosts still rc 0.