Fix: Adopt a Terra the machine already trusts

The repository audit made any Terra that is not Panama's own pinned form a
trust-root failure, and status 78 then stopped every stage before it ran. A
machine that installed Terra the way Terra documents it -- terra-release's own
repo file, a metalink, the key at its stock path -- was classified hostile and
had no way back, because install_terra_repository refused to touch a machine
terra-release had already reached. A gate with no door.

The trust root is the signing key, and that key is byte-for-byte the
fingerprint this repository reviewed and pinned, with every signature check
already on. So verify the fingerprint and adopt the configuration into the
pinned form instead of refusing it. Adoption needs no network and no DNF, it
runs before any other transaction in the stage, and it is repeatable, which it
has to be: terra-release owns that file and restores it on update.

Adoption stays narrow. The pinned fingerprint must match both the reviewed key
and the key the machine actually verifies against, the gpgkey must be a local
file under the system trust directory, and the endpoint must be one Terra
itself serves -- so the reviewed baseurl or the reviewed metalink host, now
pinned as TERRA_METALINK_BASEURL. An unknown key, a redirected baseurl, a
second enabled Terra, or a disabled signature check is still a hard refusal.

A refusal also stops less than it did. It suppresses the stages that open DNF
and the migrations, which may run a transaction of their own, and the run still
exits 78. It no longer stops link-dotfiles, link-skills or link-user, which
read no repository and install no package. Exiting before them is what left
this laptop with a stale ~/.claude/skills and no shipped skill reachable.

Also stub ensure_flathub_remote in the extras contract, which has been failing
since that call was added to install_extra_category without one.

Claude-Session: https://claude.ai/code/session_01PeTrG9dGY89UWuhGm4Pr1s
This commit is contained in:
Gabriel Brown
2026-08-28 14:53:48 -04:00
parent b5832fc94a
commit fa8b14e05e
7 changed files with 323 additions and 46 deletions
+35 -11
View File
@@ -360,30 +360,48 @@ fi
grep -qx 'link-dotfiles' "$tmp/c/ran" \
|| note 'an ordinary package-stage failure no longer allows later safe stages'
# An invalid enabled Terra root is not an ordinary package failure. It must
# stop before the installer's bootstrap DNF and before every stage.
# An untrusted Terra root is not an ordinary package failure, and it is not a
# reason to abandon the machine either. It suppresses the stages that open DNF
# and the migrations, which are free to run a transaction of their own. Every
# stage that only links configuration still runs, and the status stays 78.
SAFE_STAGES=(link-dotfiles link-skills link-user link-vicinae-scripts)
DNF_SUPPRESSED=(install-packages change-settings install-hardware)
assert_trust_refusal() {
local root="$1" label="$2" suppressed safe
for suppressed in "${DNF_SUPPRESSED[@]}"; do
grep -qx "$suppressed" "$root/ran" \
&& note "$label still ran $suppressed"
done
grep -q '^migrate ' "$root/ran" \
&& note "$label still ran migrations, which may open a DNF transaction"
for safe in "${SAFE_STAGES[@]}"; do
grep -qx "$safe" "$root/ran" \
|| note "$label suppressed $safe, which touches no repository"
done
}
build_fixture "$tmp/terra-preflight-hard" 0 78
install_status=0
run_install "$tmp/terra-preflight-hard" >/dev/null || install_status=$?
[[ "$install_status" -eq 78 ]] \
|| note "initial Terra trust failure returned $install_status instead of 78"
asserted_preflight="$(<"$tmp/terra-preflight-hard/ran")"
[[ "$asserted_preflight" == trust-preflight ]] \
|| note "initial Terra trust failure allowed later work: ${asserted_preflight//$'\n'/,}"
grep -qx 'trust-preflight' "$tmp/terra-preflight-hard/ran" \
|| note 'initial Terra trust fixture never reached the preflight'
assert_trust_refusal "$tmp/terra-preflight-hard" 'initial Terra trust failure'
# The trust verifier is itself mandatory. Losing its executable adapter must
# fail closed before interview, bootstrap, or stage work.
# The trust verifier is itself mandatory. Losing its executable adapter refuses
# package work exactly as a failing verdict does, rather than being ignored.
build_fixture "$tmp/terra-preflight-missing"
rm "$tmp/terra-preflight-missing/setup/scripts/install-packages"
install_status=0
run_install "$tmp/terra-preflight-missing" >/dev/null || install_status=$?
[[ "$install_status" -eq 78 ]] \
|| note "missing Terra trust verifier returned $install_status instead of 78"
[[ ! -s "$tmp/terra-preflight-missing/ran" ]] \
|| note 'missing Terra trust verifier allowed later work'
assert_trust_refusal "$tmp/terra-preflight-missing" 'missing Terra trust verifier'
# The package stage repeats the preflight to close a configuration-change race.
# Its hard status must also stop link stages and install-hardware immediately.
# Its hard status suppresses the DNF stages that would have followed it.
build_fixture "$tmp/terra-stage-hard" 78 0
install_status=0
run_install "$tmp/terra-stage-hard" >/dev/null || install_status=$?
@@ -391,10 +409,16 @@ run_install "$tmp/terra-stage-hard" >/dev/null || install_status=$?
|| note "stage-time Terra trust failure returned $install_status instead of 78"
grep -qx 'install-packages' "$tmp/terra-stage-hard/ran" \
|| note 'stage-time Terra trust fixture never reached install-packages'
for suppressed in link-dotfiles link-skills link-user change-settings install-hardware dnf-transaction; do
for suppressed in change-settings install-hardware; do
grep -qx "$suppressed" "$tmp/terra-stage-hard/ran" \
&& note "stage-time Terra trust failure still ran $suppressed"
done
grep -q '^migrate ' "$tmp/terra-stage-hard/ran" \
&& note 'stage-time Terra trust failure still ran migrations'
for safe in "${SAFE_STAGES[@]}"; do
grep -qx "$safe" "$tmp/terra-stage-hard/ran" \
|| note "stage-time Terra trust failure suppressed $safe"
done
# A full install always runs the stage, whatever any recorded hash says.
build_fixture "$tmp/d"