diff --git a/CHANGELOG.md b/CHANGELOG.md index 57b6483..ac5bd35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,9 @@ Versioning. across the public-authority migration. - Release lifecycle operations invoked from a private control plane now bind their committed implementation proof to its pinned public GDS engine root. +- Device bootstrap verifies the physical seed Go binary with + `GOTOOLCHAIN=local`, so automatic toolchain selection cannot make an already + installed pinned toolchain appear stale on every run. ## [0.1.1] - 2026-08-16 diff --git a/scripts/bootstrap-device.sh b/scripts/bootstrap-device.sh index ab114a3..6d99e40 100755 --- a/scripts/bootstrap-device.sh +++ b/scripts/bootstrap-device.sh @@ -336,7 +336,7 @@ phase_1() { info "Phase 1 — seed Go ${GO_VERSION} + build gds from source" ensure_c_compiler local go_bin="${GO_HOME}/bin/go" - if [ -x "$go_bin" ] && "$go_bin" version 2>/dev/null | grep -q "$GO_VERSION"; then + if [ -x "$go_bin" ] && GOTOOLCHAIN=local "$go_bin" version 2>/dev/null | grep -q "$GO_VERSION"; then ok "Go ${GO_VERSION} already installed at ${GO_HOME}" else [ "$APPLY" -eq 1 ] || { info "PLAN: install Go ${GO_VERSION} to ${GO_HOME}"; return 0; } @@ -352,7 +352,7 @@ phase_1() { mkdir -p "$GO_HOME" tar -xzf "$tmp" -C "$GO_HOME" --strip-components=1 rm -f "$tmp" - "$go_bin" version + GOTOOLCHAIN=local "$go_bin" version ok "Go ${GO_VERSION} installed" fi diff --git a/tests/test_bootstrap_device.py b/tests/test_bootstrap_device.py index fcfa9f2..a3b703e 100644 --- a/tests/test_bootstrap_device.py +++ b/tests/test_bootstrap_device.py @@ -47,6 +47,13 @@ def test_source_build_never_accepts_a_merely_runnable_binary() -> None: assert "if ! source_build_dirty" in script +def test_seed_go_verifies_the_physical_toolchain_without_auto_selection() -> None: + script = BOOTSTRAP.read_text(encoding="utf-8") + + assert 'GOTOOLCHAIN=local "$go_bin" version 2>/dev/null' in script + assert 'GOTOOLCHAIN=local "$go_bin" version' in script + + def test_registration_skip_binds_full_control_plane_locator() -> None: script = BOOTSTRAP.read_text(encoding="utf-8")