fix(setup): preserve exact bootstrap pin values

Read quoted lock fields directly instead of stripping delimiters with
an empty-matching expression. Bound target selection to the uv row so
missing targets cannot select unrelated artifacts. Preserve registry
arguments in Git Bash when detecting Windows ARM64.

Real cold-script tests intercept only the download boundary. They
verify the exact native pin and refuse a missing target before download.
A deliberate digest mismatch stops before any downloaded tool executes.
No full dependency installation or user-state change was performed.
This commit is contained in:
ethernet
2026-09-09 19:39:52 -04:00
parent 14669e7c19
commit 4f4f28c552
2 changed files with 69 additions and 10 deletions

View File

@@ -52,7 +52,7 @@ esac
if [ "$os" = win32 ]; then
# PROCESSOR_ARCHITECTURE lies under an emulated shell (x64 msys on a
# WoA box reports AMD64); the registry carries the machine's truth.
winarch="$(reg.exe query 'HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment' /v PROCESSOR_ARCHITECTURE 2>/dev/null | tr -d '\r' | awk '/PROCESSOR_ARCHITECTURE/ {print $NF}')"
winarch="$(MSYS2_ARG_CONV_EXCL='*' reg.exe query 'HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment' /v PROCESSOR_ARCHITECTURE 2>/dev/null | tr -d '\r' | awk '/PROCESSOR_ARCHITECTURE/ {print $NF}')"
case "${winarch:-${PROCESSOR_ARCHITECTURE:-}}" in
ARM64) arch=arm64 ;;
*) arch=x64 ;;
@@ -69,19 +69,20 @@ target="$os-$arch"
# lock.json is machine-written (sorted keys, 2-space indent): read the uv
# pin's version + this target's url/sha256 with awk — no python yet.
pin() { # $1 = field (url | sha256)
awk -v target="$target" -v field="$1" '
awk -F '"' -v target="$target" -v field="$1" '
/^ "uv": \{/ { in_uv = 1 }
in_uv && $0 ~ "^ \"" target "\": \\{" { in_t = 1 }
in_t && $0 ~ "^ \"" field "\":" {
gsub(/.*: "|,?$/, ""); print; exit
}' "$lock"
in_uv && /^ }/ { exit }
in_uv && /^ "/ { in_t = ($2 == target) }
in_t && $2 == field { print $4; exit }' "$lock"
}
uv_version="$(awk '
uv_version="$(awk -F '"' '
/^ "uv": \{/ { in_uv = 1 }
in_uv && /^ "version":/ { gsub(/.*: "|,?$/, ""); print; exit }' "$lock")"
py_version="$(awk '
in_uv && /^ }/ { exit }
in_uv && $2 == "version" { print $4; exit }' "$lock")"
py_version="$(awk -F '"' '
/^ "python": \{/ { in_py = 1 }
in_py && /^ "version":/ { gsub(/.*: "|"$|",$/, ""); print; exit }' "$lock" \
in_py && /^ }/ { exit }
in_py && $2 == "version" { print $4; exit }' "$lock" \
| cut -d+ -f1 | cut -d. -f1,2)"
[ -n "$uv_version" ] || { echo -e "${RED}✗${NC} no uv pin in pm/lock.json" >&2; exit 1; }

View File

@@ -0,0 +1,58 @@
"""Cold setup consumes lock values before executing any downloaded tool."""
import json
import os
from pathlib import Path
import shutil
import subprocess
import pytest
from pm.store import current_target
ROOT = Path(__file__).resolve().parents[2]
@pytest.mark.platforms("windows", "posix")
@pytest.mark.parametrize("missing_target", [False, True])
def test_cold_setup_uses_exact_lock_values(tmp_path, missing_target):
checkout = tmp_path / "checkout"
(checkout / "pm").mkdir(parents=True)
shutil.copy2(ROOT / "setup-hermes.sh", checkout / "setup-hermes.sh")
lock = json.loads((ROOT / "pm" / "lock.json").read_text(encoding="utf-8"))
target = current_target()
uv_pin = lock["packages"]["uv"]
artifact = uv_pin["artifacts"][target]
if missing_target:
del uv_pin["artifacts"][target]
(checkout / "pm" / "lock.json").write_text(json.dumps(lock, indent=2, sort_keys=True) + "\n", encoding="utf-8")
corrupt = tmp_path / "corrupt-download"
corrupt.write_bytes(b"intentional digest mismatch; this must never be executed\n")
args = tmp_path / "curl-args"
hook = tmp_path / "transport.sh"
hook.write_text('''curl() {
printf '%s\\n' "$@" > "$PROBE_ARGS"
while [ "$#" -gt 0 ]; do
if [ "$1" = -o ]; then
cp "$PROBE_DOWNLOAD" "$2"
return
fi
shift
done
return 37
}
''', encoding="utf-8")
env = dict(os.environ, HOME=tmp_path.as_posix(), HERMES_HOME=(tmp_path / "home").as_posix(),
HERMES_RUNTIME_DIR=(tmp_path / "tools").as_posix(), BASH_ENV=hook.as_posix(),
PROBE_ARGS=args.as_posix(), PROBE_DOWNLOAD=corrupt.as_posix())
result = subprocess.run(["bash", str(checkout / "setup-hermes.sh")], cwd=tmp_path,
env=env, capture_output=True, text=True, encoding="utf-8", timeout=30)
assert result.returncode != 0, result.stdout + result.stderr
if missing_target:
assert not args.exists(), "a missing target must not select a sibling artifact"
assert f"no uv artifact for {target}" in result.stderr
else:
assert args.read_text(encoding="utf-8").splitlines()[-1] == artifact["url"]
assert f"pinned uv {uv_pin['version']} ({target})" in result.stdout
assert f"pinned {artifact['sha256']})" in result.stderr
assert not (checkout / ".env").exists()