#!/usr/bin/env bash

# The production change that breaks these cases is accepting an unverified
# download, a wrong signer, or executable/malformed provenance data.
set -euo pipefail

repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
fixtures="$repo_dir/tests/setup/fixtures/provenance"
config="$repo_dir/setup/provenance/installers.conf"
test_tmp="$(mktemp -d)"
host_gnupg="${GNUPGHOME:-$HOME/.gnupg}"
host_rpmdb="/usr/lib/sysimage/rpm/rpmdb.sqlite"
ambient_gnupg="$test_tmp/fresh-ambient-gnupg"

cleanup() {
    rm -rf -- "$test_tmp"
}
trap cleanup EXIT
trap 'exit 130' INT
trap 'exit 143' TERM

fail() {
    printf 'package provenance contract: %s\n' "$*" >&2
    exit 1
}

expect_success() {
    "$@" || fail "expected success: $*"
}

expect_failure() {
    if "$@"; then
        fail "expected failure: $*"
    fi
}

assert_file_bytes() {
    local path="$1" expected="$2"
    [[ "$(<"$path")" == "$expected" ]] || fail "unexpected bytes in $path"
}

snapshot() {
    local path="$1"
    if [[ -e "$path" ]]; then
        stat -c '%i:%s:%Y:%Z' "$path"
    else
        printf 'absent'
    fi
}

snapshot_gpg_state() {
    local path="$1" file relative
    [[ -d "$path" ]] || {
        printf 'absent\n'
        return 0
    }

    {
        printf 'directory\0'
        find "$path" -mindepth 1 -print0 | LC_ALL=C sort -z \
            | while IFS= read -r -d '' file; do
                relative="${file#"$path"/}"
                printf '%s\0' "$relative"
                if [[ -L "$file" ]]; then
                    printf 'symlink\0%s\0' "$(readlink -- "$file")"
                elif [[ -f "$file" ]]; then
                    printf 'file\0%s\0' "$(sha256sum -- "$file" | awk '{ print $1 }')"
                elif [[ -d "$file" ]]; then
                    printf 'directory\0'
                else
                    printf 'other\0%s\0' "$(stat -c '%F:%a:%s:%Y:%Z' "$file")"
                fi
            done
    } | sha256sum | awk '{ print $1 }'
}

snapshot_file_state() {
    local path="$1"
    if [[ -f "$path" ]]; then
        printf 'file:%s:%s\n' "$(stat -c '%a:%s:%Y:%Z' "$path")" \
            "$(sha256sum "$path" | awk '{ print $1 }')"
    elif [[ -L "$path" ]]; then
        printf 'symlink:%s\n' "$(readlink -- "$path")"
    else
        printf 'absent\n'
    fi
}

export GNUPGHOME="$ambient_gnupg"
mkdir -m 700 "$ambient_gnupg"
printf 'baseline-value\n' > "$ambient_gnupg/unexpected-entry"
ambient_before="$(snapshot "$ambient_gnupg")"
ambient_gpg_files_before="$(snapshot_gpg_state "$ambient_gnupg")"
printf 'tampered-value\n' > "$ambient_gnupg/unexpected-entry"
[[ "$ambient_gpg_files_before" != "$(snapshot_gpg_state "$ambient_gnupg")" ]] \
    || fail 'ambient GPG snapshot ignored unexpected file content'
printf 'baseline-value\n' > "$ambient_gnupg/unexpected-entry"
ambient_gpg_files_before="$(snapshot_gpg_state "$ambient_gnupg")"
before_gnupg="$(snapshot "$host_gnupg")"
before_gpg_files="$(snapshot_gpg_state "$host_gnupg")"
before_rpmdb="$(snapshot "$host_rpmdb")"
before_repo_files="$(snapshot_gpg_state /etc/yum.repos.d)"
before_rpm_key_files="$(snapshot_gpg_state /etc/pki/rpm-gpg)"
before_system_flatpak="$(snapshot_file_state /var/lib/flatpak/repo/config)"
before_system_flathub_key="$(snapshot_file_state /var/lib/flatpak/repo/flathub.trustedkeys.gpg)"
before_user_flatpak="$(snapshot_file_state "$HOME/.local/share/flatpak/repo/config")"
before_bashrc="$(snapshot_file_state "$HOME/.bashrc")"

# Runtime and agent installs must consume the reviewed provenance table. Keep
# this scan at the public script boundary because a command hidden elsewhere in
# the installer can bypass every archive-level test below.
installer="$repo_dir/setup/scripts/install-packages"
unsafe_installers=()
for forbidden in \
    'curl[^|]*\|[[:space:]]*bash' \
    'nvm[[:space:]]+install[[:space:]]+--lts' \
    'npm[[:space:]]+install[[:space:]]+-g[[:space:]]+pnpm' \
    'npm[[:space:]]+install[[:space:]]+-g[[:space:]]+@openai/codex' \
    'releases/latest' \
    'api\.github\.com/.*/releases/latest'; do
    while IFS= read -r finding; do
        [[ -n "$finding" ]] && unsafe_installers+=("$finding")
    done < <(grep -nE "$forbidden" "$installer" || true)
done
if (( ${#unsafe_installers[@]} > 0 )); then
    printf 'package provenance contract: moving or piped installer inputs:\n' >&2
    printf '  %s\n' "${unsafe_installers[@]}" >&2
    fail 'replace each finding with a reviewed, verified installation path'
fi

# This must be the only production file sourced by the contract.
# shellcheck source=../../setup/lib/artifact-provenance
source "$repo_dir/setup/lib/artifact-provenance"

fixture_fingerprint='6016FF18CAE298CE3648EE2325E01F765E1EF9FA'
tiny_sha256='291bd319ae85488101e908e37fc0fa1b0da1429ba27e10d2b391cb3f60dd44ea'
base64 --decode "$fixtures/signed-fixture.rpm.base64" > "$test_tmp/signed-fixture.rpm"
base64 --decode "$fixtures/unsigned-fixture.rpm.base64" > "$test_tmp/unsigned-fixture.rpm"
base64 --decode "$fixtures/wrong-signer-fixture.rpm.base64" > "$test_tmp/wrong-signer-fixture.rpm"

[[ "$(wc -l < "$fixtures/SHASUMS256.txt")" -eq 4 ]] || fail 'signed checksum fixture is not four lines'
[[ "$(cmp -l "$fixtures/tiny-artifact" "$fixtures/tiny-artifact-tampered" | wc -l)" -eq 1 ]] \
    || fail 'tampered artifact does not differ by exactly one byte'

expect_success key_fingerprint_matches "$fixtures/fixture-key.asc" "$fixture_fingerprint"
[[ "$ambient_before" == "$(snapshot "$ambient_gnupg")" ]] \
    || fail 'fingerprint inspection created ambient GPG state'
[[ "$ambient_gpg_files_before" == "$(snapshot_gpg_state "$ambient_gnupg")" ]] \
    || fail 'fingerprint inspection created an ambient GPG keybox or trust database'
expect_failure key_fingerprint_matches "$fixtures/fixture-key.asc" '0000000000000000000000000000000000000000'
cat "$fixtures/fixture-key.asc" "$fixtures/wrong-signer-key.asc" > "$test_tmp/combined-key.asc"
expect_failure key_fingerprint_matches "$test_tmp/combined-key.asc" "$fixture_fingerprint"

expect_success verify_detached_signature \
    "$fixtures/fixture-key.asc" "$fixtures/SHASUMS256.txt.asc" "$fixtures/SHASUMS256.txt"
expect_failure verify_detached_signature \
    "$fixtures/fixture-key.asc" "$fixtures/SHASUMS256.txt.asc" "$fixtures/tiny-artifact"
expect_failure verify_detached_signature \
    "$fixtures/fixture-key.asc" "$fixtures/SHASUMS256.txt.asc" "$fixtures/tiny-artifact-tampered"
cp "$fixtures/SHASUMS256.txt.asc" "$test_tmp/bad-signature.asc"
sed -i 's/^=MJqv$/=MJqa/' "$test_tmp/bad-signature.asc"
expect_failure verify_detached_signature \
    "$fixtures/fixture-key.asc" "$test_tmp/bad-signature.asc" "$fixtures/SHASUMS256.txt"
expect_failure verify_detached_signature \
    "$test_tmp/combined-key.asc" "$fixtures/wrong-signer-SHASUMS256.txt.asc" "$fixtures/SHASUMS256.txt"

mkdir "$test_tmp/bin"
cat > "$test_tmp/bin/curl" <<'STUB'
#!/usr/bin/env bash
set -euo pipefail
output=''
connect_timeout=''
max_time=''
max_filesize=''
while (($#)); do
    case "$1" in
        --output) output="$2"; shift 2 ;;
        --connect-timeout) connect_timeout="$2"; shift 2 ;;
        --max-time) max_time="$2"; shift 2 ;;
        --max-filesize) max_filesize="$2"; shift 2 ;;
        *) shift ;;
    esac
done
[[ "$connect_timeout" == 10 && "$max_time" == 600 && "$max_filesize" == "${CURL_EXPECTED_MAX_BYTES:?}" ]] || exit 65
case "${CURL_FIXTURE:?}" in
    good) cp "$CURL_FIXTURE_ROOT/tiny-artifact" "$output" ;;
    oversized) head -c 1025 /dev/zero > "$output" ;;
    interrupted) printf 'partial' > "$output"; exit 42 ;;
    *) exit 64 ;;
esac
STUB
chmod +x "$test_tmp/bin/curl"
PATH="$test_tmp/bin:$PATH"
export PATH CURL_FIXTURE_ROOT="$fixtures" CURL_EXPECTED_MAX_BYTES=1024

destination="$test_tmp/destination"
export CURL_FIXTURE=good
expect_success download_sha256 'https://fixture.invalid/good' "$tiny_sha256" 1024 "$destination"
cmp -s "$fixtures/tiny-artifact" "$destination" || fail 'verified download changed artifact bytes'
[[ ! -e "$destination.part" ]] || fail 'successful download left a part file'

export CURL_FIXTURE=good
expect_failure download_sha256 'https://fixture.invalid/uppercase-digest' \
    '291BD319AE85488101E908E37FC0FA1B0DA1429BA27E10D2B391CB3F60DD44EA' 1024 \
    "$test_tmp/uppercase-destination"

printf 'known-good\n' > "$destination"
export CURL_FIXTURE=good
expect_failure download_sha256 'https://fixture.invalid/bad-digest' \
    '0000000000000000000000000000000000000000000000000000000000000000' 1024 "$destination"
assert_file_bytes "$destination" 'known-good'
[[ ! -e "$destination.part" ]] || fail 'bad digest left a part file'

protected="$test_tmp/protected-known-good"
printf 'known-good\n' > "$protected"
ln -s "$protected" "$destination.part"
expect_failure download_sha256 'https://fixture.invalid/symlink-part' \
    '0000000000000000000000000000000000000000000000000000000000000000' 1024 "$destination"
assert_file_bytes "$protected" 'known-good'
[[ -L "$destination.part" ]] || fail 'symlinked destination part was not preserved'
rm -f -- "$destination.part"

ln "$protected" "$destination.part"
expect_failure download_sha256 'https://fixture.invalid/hard-link-part' \
    '0000000000000000000000000000000000000000000000000000000000000000' 1024 "$destination"
assert_file_bytes "$protected" 'known-good'
[[ "$(stat -c %i "$protected")" == "$(stat -c %i "$destination.part")" ]] \
    || fail 'hard-linked destination part was not preserved'
rm -f -- "$destination.part"

export CURL_FIXTURE=oversized
expect_failure download_sha256 'https://fixture.invalid/oversized' "$tiny_sha256" 1024 "$destination"
assert_file_bytes "$destination" 'known-good'
[[ ! -e "$destination.part" ]] || fail 'oversized download left a part file'

export CURL_FIXTURE=interrupted
expect_failure download_sha256 'https://fixture.invalid/interrupted' "$tiny_sha256" 1024 "$destination"
assert_file_bytes "$destination" 'known-good'
[[ ! -e "$destination.part" ]] || fail 'interrupted download left a part file'

expect_success rpm_signature_matches \
    "$test_tmp/signed-fixture.rpm" "$fixtures/fixture-key.asc" "$fixture_fingerprint"
expect_failure rpm_signature_matches \
    "$test_tmp/unsigned-fixture.rpm" "$fixtures/fixture-key.asc" "$fixture_fingerprint"
expect_failure rpm_signature_matches \
    "$test_tmp/signed-fixture.rpm" "$fixtures/fixture-key.asc" '0000000000000000000000000000000000000000'
expect_failure rpm_signature_matches \
    "$test_tmp/wrong-signer-fixture.rpm" "$fixtures/fixture-key.asc" "$fixture_fingerprint"
expect_failure rpm_signature_matches \
    "$test_tmp/wrong-signer-fixture.rpm" "$test_tmp/combined-key.asc" "$fixture_fingerprint"
expect_success load_installer_provenance "$config"
[[ "${INSTALLER_PROVENANCE[BUN_VERSION]:-}" == '1.4.0' ]] || fail 'valid provenance was not loaded'
for reviewed_value in \
    'NODE_VERSION 24.20.0' \
    'NODE_X86_64_SHA256 2f2c0da162318f0de47665410c7c8c2ed3d36c8f3105de4bbc61176c70a7cbf2' \
    'NODE_AARCH64_SHA256 5f4ddab610c1ab2016b3c227cebdbf6d9495161487e4739c7b90090595f465f7' \
    'BUN_VERSION 1.4.0' \
    'BUN_X86_64_SHA256 2d03fb5fb83ac8b567aca0a281b2ce1a1a19d488f56c2968d88c3f25e92fe452' \
    'BUN_AARCH64_SHA256 4b1a332ee861983eb93bcfe6f770fff94e3e31b2c388bdaea3c8ed35e58eed0e' \
    'CODEX_VERSION 0.150.1' \
    'CODEX_X86_64_SHA256 00aba704f029f6dc0d948be407a756e0c97cc840132fd691353b2c6b0a505b17' \
    'CODEX_AARCH64_SHA256 1ecac3f87823efb98153233b076ea3d6e34a7a8cebe43c5285dc5f79e1514639' \
    'RUSTDESK_VERSION 1.4.9' \
    'RUSTDESK_X86_64_SHA256 eb1b053ac5b2f774f2271f7fbbfd2ea475899f7a55135c5e172bc54b9388f108'; do
    read -r name expected <<<"$reviewed_value"
    [[ "${INSTALLER_PROVENANCE[$name]:-}" == "$expected" ]] \
        || fail "$name does not match the reviewed release"
done
for key_spec in \
    'terra44 TERRA_FINGERPRINT' \
    'claude-code CLAUDE_CODE_FINGERPRINT' \
    'bun BUN_FINGERPRINT' \
    'rpmfusion-free RPMFUSION_FREE_FINGERPRINT' \
    'rpmfusion-nonfree RPMFUSION_NONFREE_FINGERPRINT' \
    'hyprland-copr HYPRLAND_COPR_FINGERPRINT' \
    'flathub FLATHUB_FINGERPRINT' \
    'claude-desktop CLAUDE_DESKTOP_FINGERPRINT'; do
    read -r key_file fingerprint_name <<<"$key_spec"
    expect_success key_fingerprint_matches "$repo_dir/setup/provenance/keys/$key_file.asc" \
        "${INSTALLER_PROVENANCE[$fingerprint_name]}"
done

[[ "$before_gnupg" == "$(snapshot "$host_gnupg")" ]] || fail 'host GPG state changed'
[[ "$before_gpg_files" == "$(snapshot_gpg_state "$host_gnupg")" ]] || fail 'host GPG state changed'
[[ "$before_rpmdb" == "$(snapshot "$host_rpmdb")" ]] || fail 'host RPM database changed'
[[ "$ambient_before" == "$(snapshot "$ambient_gnupg")" ]] || fail 'production helper created ambient GPG state'
[[ "$ambient_gpg_files_before" == "$(snapshot_gpg_state "$ambient_gnupg")" ]] \
    || fail 'production helper created or changed an ambient GPG entry'

parser_fixture="$test_tmp/installers.conf"
cp "$config" "$parser_fixture"
printf 'UNKNOWN_KEY=value\n' >> "$parser_fixture"
expect_failure load_installer_provenance "$parser_fixture"

cp "$config" "$parser_fixture"
printf 'BUN_VERSION=1.4.0\n' >> "$parser_fixture"
expect_failure load_installer_provenance "$parser_fixture"

grep -v '^NODE_VERSION=' "$config" > "$parser_fixture"
expect_failure load_installer_provenance "$parser_fixture"

cp "$config" "$parser_fixture"
sed -i 's/^BUN_VERSION=/ BUN_VERSION=/' "$parser_fixture"
expect_failure load_installer_provenance "$parser_fixture"

cp "$config" "$parser_fixture"
sed -i 's/^BUN_VERSION=.*/BUN_VERSION=$(id -u)/' "$parser_fixture"
expect_failure load_installer_provenance "$parser_fixture"

cp "$config" "$parser_fixture"
printf 'BUN_ARMV7_URL=https://fixture.invalid/bun\n' >> "$parser_fixture"
expect_failure load_installer_provenance "$parser_fixture"

# Repository setup runs from a fixture copy of the installer with every
# external command replaced. A contract failure can therefore inspect exact
# ordering and staged bytes without consulting or changing the host.
installer_fixture="$test_tmp/installer-fixture"
mkdir -p "$installer_fixture/setup/lib" "$installer_fixture/setup/provenance/keys" \
    "$installer_fixture/setup/scripts"
cp "$repo_dir/setup/lib/artifact-provenance" "$repo_dir/setup/lib/extras-catalog" \
    "$repo_dir/setup/lib/machine-role" "$installer_fixture/setup/lib/"
cp "$config" "$installer_fixture/setup/provenance/installers.conf"
cp "$repo_dir"/setup/provenance/keys/*.asc "$installer_fixture/setup/provenance/keys/"
sed '/^# --- The server path/,$d' "$repo_dir/setup/scripts/install-packages" \
    > "$installer_fixture/setup/scripts/install-packages"

artifact_root="$test_tmp/runtime-artifacts"
mkdir -p "$artifact_root/build"
for arch_spec in \
    'x86_64 x64 x64' \
    'aarch64 arm64 aarch64'; do
    read -r machine node_arch bun_arch <<<"$arch_spec"
    node_top="node-v24.20.0-linux-$node_arch"
    mkdir -p "$artifact_root/build/$node_top/bin"
    printf '#!/usr/bin/env bash\nprintf "v24.20.0\\n"\n' \
        > "$artifact_root/build/$node_top/bin/node"
    chmod +x "$artifact_root/build/$node_top/bin/node"
    tar -C "$artifact_root/build" -cJf "$artifact_root/node-$machine.tar.xz" "$node_top"
    rm -rf -- "$artifact_root/build/$node_top"

    bun_top="bun-linux-$bun_arch"
    mkdir -p "$artifact_root/build/$bun_top"
    printf '#!/usr/bin/env bash\nprintf "1.4.0\\n"\n' \
        > "$artifact_root/build/$bun_top/bun"
    chmod +x "$artifact_root/build/$bun_top/bun"
    (cd "$artifact_root/build" && zip -q "$artifact_root/bun-$machine.zip" "$bun_top/bun")
    rm -rf -- "$artifact_root/build/$bun_top"

    codex_name="codex-$machine-unknown-linux-musl"
    printf '#!/usr/bin/env bash\nprintf "codex-cli 0.150.1\\n"\n' \
        > "$artifact_root/build/$codex_name"
    chmod +x "$artifact_root/build/$codex_name"
    tar -C "$artifact_root/build" -czf "$artifact_root/codex-$machine.tar.gz" "$codex_name"
    rm -f -- "$artifact_root/build/$codex_name"
done
mkdir -p "$artifact_root/build/wrong-node/bin" "$artifact_root/build/wrong-codex"
printf '#!/usr/bin/env bash\nprintf "v24.20.0\\n"\n' > "$artifact_root/build/wrong-node/bin/node"
printf '#!/usr/bin/env bash\nprintf "codex-cli 0.150.1\\n"\n' > "$artifact_root/build/wrong-codex/codex"
chmod +x "$artifact_root/build/wrong-node/bin/node" "$artifact_root/build/wrong-codex/codex"
tar -C "$artifact_root/build" -cJf "$artifact_root/node-bad.tar.xz" wrong-node
tar -C "$artifact_root/build" -czf "$artifact_root/codex-bad.tar.gz" wrong-codex/codex
mkdir -p "$artifact_root/build/bun-linux-x64"
printf '#!/usr/bin/env bash\nprintf "1.4.0\\n"\n' > "$artifact_root/build/bun-linux-x64/bun"
printf 'unexpected\n' > "$artifact_root/build/bun-linux-x64/extra"
chmod +x "$artifact_root/build/bun-linux-x64/bun"
(cd "$artifact_root/build" && zip -q "$artifact_root/bun-bad.zip" \
    bun-linux-x64/bun bun-linux-x64/extra)
printf 'reviewed rustdesk fixture\n' > "$artifact_root/rustdesk.rpm"
rm -rf -- "$artifact_root/build"

make_stub_commands() {
    local case_root="$1"
    mkdir -p "$case_root/bin" "$case_root/home" "$case_root/tmp" \
        "$case_root/etc/profile.d" "$case_root/etc/yum.repos.d" \
        "$case_root/etc/pki/rpm-gpg" "$case_root/flatpak-repo"

    cat > "$case_root/etc/profile.d/nvm.sh" <<'STUB'
nvm() {
    printf 'nvm:%s\n' "$*" >> "$COMMAND_LOG"
}
STUB

    cat > "$case_root/bin/uname" <<'STUB'
#!/usr/bin/env bash
printf '%s\n' "${STUB_ARCH:-x86_64}"
STUB

    cat > "$case_root/bin/rpm" <<'STUB'
#!/usr/bin/env bash
set -euo pipefail
if [[ "$*" == '-E %fedora' ]]; then
    printf 'rpm:release\n' >> "$COMMAND_LOG"
    printf '%s\n' "${STUB_FEDORA_RELEASE:-44}"
elif [[ "${1:-}" == -q ]]; then
    package="${!#}"
    printf 'rpm:query:%s\n' "$package" >> "$COMMAND_LOG"
    case "$package" in
        terra-release) [[ "${STUB_TERRA_INSTALLED:-0}" == 1 ]] ;;
        claude-desktop-extra) [[ "${STUB_CLAUDE_DESKTOP_INSTALLED:-0}" == 1 ]] ;;
        rustdesk)
            [[ -n "${STUB_RUSTDESK_VERSION:-}" ]] || exit 1
            [[ "$*" != *--queryformat* ]] || printf '%s' "$STUB_RUSTDESK_VERSION"
            ;;
        *) exit 1 ;;
    esac
else
    exit 64
fi
STUB

    cat > "$case_root/bin/curl" <<'STUB'
#!/usr/bin/env bash
set -euo pipefail
output='' max_filesize='' connect_timeout='' max_time='' url=''
while (($#)); do
    case "$1" in
        --output) output="$2"; shift 2 ;;
        --max-filesize) max_filesize="$2"; shift 2 ;;
        --connect-timeout) connect_timeout="$2"; shift 2 ;;
        --max-time) max_time="$2"; shift 2 ;;
        --fail|--location) shift ;;
        *) url="$1"; shift ;;
    esac
done
[[ -n "$output" && "$connect_timeout" == 10 && "$max_time" == 600 ]] || exit 65
output_name="$(basename "$output")"
output_name="${output_name#.}"
output_name="${output_name%.part.*}"
printf 'curl:%s:max=%s:output=%s\n' "$url" "$max_filesize" "$output_name" >> "$COMMAND_LOG"
if [[ "${STUB_DOWNLOAD_INTERRUPT:-}" == 1 ]]; then
    printf 'partial' > "$output"
    exit 42
fi
case "$url" in
    *rpmfusion-free*) cp "$SIGNED_RPM" "$output" ;;
    *rpmfusion-nonfree*) cp "$SIGNED_RPM" "$output" ;;
    *flathub.flatpakrepo) cp "$FLATHUB_DESCRIPTOR" "$output" ;;
    *node-v24.20.0-linux-x64.tar.xz)
        cp "$ARTIFACT_ROOT/${STUB_BAD_LAYOUT:+node-bad.tar.xz}" "$output" 2>/dev/null \
            || cp "$ARTIFACT_ROOT/node-x86_64.tar.xz" "$output"
        ;;
    *node-v24.20.0-linux-arm64.tar.xz) cp "$ARTIFACT_ROOT/node-aarch64.tar.xz" "$output" ;;
    *bun-linux-x64.zip)
        cp "$ARTIFACT_ROOT/${STUB_BAD_LAYOUT:+bun-bad.zip}" "$output" 2>/dev/null \
            || cp "$ARTIFACT_ROOT/bun-x86_64.zip" "$output"
        ;;
    *bun-linux-aarch64.zip) cp "$ARTIFACT_ROOT/bun-aarch64.zip" "$output" ;;
    *codex-package-x86_64-unknown-linux-musl.tar.gz)
        cp "$ARTIFACT_ROOT/${STUB_BAD_LAYOUT:+codex-bad.tar.gz}" "$output" 2>/dev/null \
            || cp "$ARTIFACT_ROOT/codex-x86_64.tar.gz" "$output"
        ;;
    *codex-package-aarch64-unknown-linux-musl.tar.gz) cp "$ARTIFACT_ROOT/codex-aarch64.tar.gz" "$output" ;;
    *rustdesk-1.4.9-0.x86_64.rpm) cp "$ARTIFACT_ROOT/rustdesk.rpm" "$output" ;;
    *) exit 66 ;;
esac
STUB

    cat > "$case_root/bin/sha256sum" <<'STUB'
#!/usr/bin/env bash
set -euo pipefail
file="${!#}"
if [[ "${STUB_DIGEST_MISMATCH:-}" == 1 ]]; then
    printf '%064d  %s\n' 0 "$file"
    exit 0
fi
for spec in \
    'node-x86_64.tar.xz 2f2c0da162318f0de47665410c7c8c2ed3d36c8f3105de4bbc61176c70a7cbf2' \
    'node-aarch64.tar.xz 5f4ddab610c1ab2016b3c227cebdbf6d9495161487e4739c7b90090595f465f7' \
    'node-bad.tar.xz 2f2c0da162318f0de47665410c7c8c2ed3d36c8f3105de4bbc61176c70a7cbf2' \
    'bun-x86_64.zip 2d03fb5fb83ac8b567aca0a281b2ce1a1a19d488f56c2968d88c3f25e92fe452' \
    'bun-aarch64.zip 4b1a332ee861983eb93bcfe6f770fff94e3e31b2c388bdaea3c8ed35e58eed0e' \
    'bun-bad.zip 2d03fb5fb83ac8b567aca0a281b2ce1a1a19d488f56c2968d88c3f25e92fe452' \
    'codex-x86_64.tar.gz 00aba704f029f6dc0d948be407a756e0c97cc840132fd691353b2c6b0a505b17' \
    'codex-aarch64.tar.gz 1ecac3f87823efb98153233b076ea3d6e34a7a8cebe43c5285dc5f79e1514639' \
    'codex-bad.tar.gz 00aba704f029f6dc0d948be407a756e0c97cc840132fd691353b2c6b0a505b17' \
    'rustdesk.rpm eb1b053ac5b2f774f2271f7fbbfd2ea475899f7a55135c5e172bc54b9388f108'; do
    read -r fixture digest <<<"$spec"
    if cmp -s "$file" "$ARTIFACT_ROOT/$fixture"; then
        printf '%s  %s\n' "$digest" "$file"
        exit 0
    fi
done
/usr/bin/sha256sum "$@"
STUB

    cat > "$case_root/bin/gpg" <<'STUB'
#!/usr/bin/env bash
set -euo pipefail
key="${!#}"
fingerprint=''
for candidate in "$REVIEWED_KEYS"/*.asc; do
    if cmp -s "$key" "$candidate"; then
        case "$(basename "$candidate")" in
            terra44.asc) fingerprint='AE09157A4DE88B497EA1D5D300CDAB43DE226D6F' ;;
            claude-code.asc) fingerprint='31DDDE24DDFAB679F42D7BD2BAA929FF1A7ECACE' ;;
            rpmfusion-free.asc) fingerprint='E9A491A3DE247814E7E067EAE06F8ECDD651FF2E' ;;
            rpmfusion-nonfree.asc) fingerprint='79BDB88F9BBF73910FD4095B6A2AF96194843C65' ;;
            hyprland-copr.asc) fingerprint='97E23476C89635135407C7D5E9BA41342C4B2995' ;;
            flathub.asc) fingerprint='6E5C05D979C76DAF93C081354184DD4D907A7CAE' ;;
            claude-desktop.asc) fingerprint='825A7D15D78BABE45646D5DF382409F597908867' ;;
        esac
        break
    fi
done
[[ -n "$fingerprint" ]] || exit 1
printf 'gpg:fingerprint:%s\n' "$fingerprint" >> "$COMMAND_LOG"
printf 'pub:-:4096:1:0000000000000000:0:0::-:::scESC::::::23::0:\n'
printf 'fpr:::::::::%s:\n' "$fingerprint"
STUB

    cat > "$case_root/bin/rpmkeys" <<'STUB'
#!/usr/bin/env bash
set -euo pipefail
action=''
package=''
while (($#)); do
    case "$1" in
        --dbpath) shift 2 ;;
        --import) action=import; package="$2"; shift 2 ;;
        --checksig) action=checksig; shift; [[ "${1:-}" == --verbose ]] && shift; package="$1"; shift ;;
        *) shift ;;
    esac
done
printf 'rpmkeys:%s:%s\n' "$action" "$(basename "$package")" >> "$COMMAND_LOG"
if [[ "$action" == checksig ]]; then
    [[ "${STUB_RPM_SIGNATURE_FAIL:-}" != "$(basename "$package")" ]] || exit 1
    printf 'Header OpenPGP signature: OK\n'
fi
STUB

    cat > "$case_root/bin/sudo" <<'STUB'
#!/usr/bin/env bash
set -euo pipefail
if [[ "${1:-}" == install ]]; then
    shift
    [[ "${1:-}" == -m && ( "${2:-}" == 0644 || "${2:-}" == 644 ) ]] || exit 67
    source_file="$3"
    destination="$4"
    printf 'sudo:install:%s:%s\n' "$(basename "$source_file")" "$destination" >> "$COMMAND_LOG"
    mapped="$STUB_ETC${destination#/etc}"
    mkdir -p "$(dirname "$mapped")"
    /usr/bin/install -m 0644 "$source_file" "$mapped"
    count=0
    [[ ! -f "$STUB_INSTALL_COUNTER" ]] || read -r count < "$STUB_INSTALL_COUNTER"
    count=$((count + 1))
    printf '%s\n' "$count" > "$STUB_INSTALL_COUNTER"
    if [[ -n "${STUB_INSTALL_FAIL_AT:-}" && "$count" == "$STUB_INSTALL_FAIL_AT" ]]; then
        exit 67
    fi
    exit 0
fi
if [[ "${1:-}" == rm && "${2:-}" == -f && "${3:-}" == -- ]]; then
    destination="$4"
    printf 'sudo:rm:%s\n' "$destination" >> "$COMMAND_LOG"
    rm -f -- "$STUB_ETC${destination#/etc}"
    exit 0
fi
original="$*"
logged=()
for argument in "$@"; do
    if [[ "$argument" == --gpg-import=*/flathub-key.asc ]]; then
        logged+=(--gpg-import=FLATHUB_KEY)
        continue
    fi
    case "$(basename "$argument")" in
        rpmfusion-free-release.rpm) logged+=(RPMFUSION_FREE) ;;
        rpmfusion-nonfree-release.rpm) logged+=(RPMFUSION_NONFREE) ;;
        rustdesk.rpm) logged+=(RUSTDESK_LOCAL) ;;
        flathub-key.asc) logged+=(FLATHUB_KEY) ;;
        *) logged+=("$argument") ;;
    esac
done
printf 'sudo:%s\n' "${logged[*]}" >> "$COMMAND_LOG"
if [[ -n "${STUB_DNF_FAIL_MATCH:-}" && "$original" == *"$STUB_DNF_FAIL_MATCH"* ]]; then
    exit 68
fi
if [[ "${1:-}" == flatpak && "${2:-}" == remote-add ]]; then
    if [[ ! -f "$STUB_FLATPAK_REPO/config" ]] \
        || ! grep -q '^\[remote "flathub"\]$' "$STUB_FLATPAK_REPO/config"; then
        key=''
        url="${!#}"
        for argument in "$@"; do
            [[ "$argument" != --gpg-import=* ]] || key="${argument#--gpg-import=}"
        done
        [[ -n "$key" ]] || exit 69
        printf '[core]\nrepo_version=1\n\n[remote "flathub"]\nurl=%s\ngpg-verify=true\ngpg-verify-summary=true\n' \
            "$url" > "$STUB_FLATPAK_REPO/config"
        cp "$key" "$STUB_FLATPAK_REPO/flathub.trustedkeys.gpg"
        printf 'mutated\n' > "$STUB_FLATPAK_STATE"
    fi
fi
STUB

    cat > "$case_root/bin/dnf" <<'STUB'
#!/usr/bin/env bash
set -euo pipefail
query=''
if [[ "$*" == '--quiet --no-plugins --dump-repo-config=terra*' ]]; then
    query=filtered
    printf 'dnf:dump-terra\n' >> "$COMMAND_LOG"
elif [[ "$*" == '--quiet --no-plugins --dump-repo-config=*' ]]; then
    query=full
    printf 'dnf:dump-all:locale=%s\n' "${LC_ALL:-unset}" >> "$COMMAND_LOG"
fi
if [[ -n "$query" ]]; then
    mode="${STUB_TERRA_EFFECTIVE_MODE:-auto}"
    if [[ "$mode" == auto ]]; then
        case "${STUB_TERRA_REPO_MODE:-absent}" in
            trusted|wrong-key) mode=trusted ;;
            nogpg) mode=legacy ;;
            wrong-url) mode=override-url ;;
        esac
        if [[ "$mode" == auto && -f "$STUB_ETC/yum.repos.d/terra.repo" ]] \
            && grep -q '^baseurl=https://repos.fyralabs.com/terra44$' "$STUB_ETC/yum.repos.d/terra.repo"; then
            mode=trusted
        elif [[ "$mode" == auto ]]; then
            mode=absent
        fi
    fi
    if [[ "$query" == full ]]; then
        printf '======== "fedora" repository configuration: ========\n'
        printf 'baseurl = \nenabled = 1\ngpgcheck = 1\n'
        printf 'gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-44-primary\n'
        printf 'metalink = https://mirrors.fedoraproject.org/metalink\nmirrorlist\n'
        printf 'pkg_gpgcheck = 0\nrepo_gpgcheck = 0\n'
    fi
    case "$mode" in
        absent) exit 0 ;;
        trusted)
            printf '======== "terra" repository configuration: ========\n'
            printf 'baseurl = https://repos.fyralabs.com/terra44\n'
            printf 'enabled = 1\n'
            printf 'gpgcheck = 1\n'
            printf 'gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama\n'
            printf 'metalink = \nmirrorlist = \npkg_gpgcheck = 1\nrepo_gpgcheck = 1\n'
            ;;
        legacy)
            printf '======== "terra" repository configuration: ========\n'
            printf 'baseurl = \nenabled = 1\ngpgcheck = 0\n'
            printf 'gpgkey = https://repos.fyralabs.com/terra44.key\n'
            printf 'metalink = https://tetsudou.fyralabs.com/terra44\nmirrorlist = \n'
            printf 'pkg_gpgcheck = 0\nrepo_gpgcheck = 0\n'
            ;;
        override-url)
            printf '======== "terra" repository configuration: ========\n'
            printf 'baseurl = https://evil.invalid/terra44\nenabled = 1\ngpgcheck = 1\n'
            printf 'gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama\n'
            printf 'metalink = \nmirrorlist = \npkg_gpgcheck = 1\nrepo_gpgcheck = 1\n'
            ;;
        override-gpg)
            printf '======== "terra" repository configuration: ========\n'
            printf 'baseurl = https://repos.fyralabs.com/terra44\nenabled = 1\ngpgcheck = 0\n'
            printf 'gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama\n'
            printf 'metalink = \nmirrorlist = \npkg_gpgcheck = 0\nrepo_gpgcheck = 0\n'
            ;;
        duplicate)
            for id in terra terra; do
                printf '======== "%s" repository configuration: ========\n' "$id"
                printf 'baseurl = https://repos.fyralabs.com/terra44\nenabled = 1\ngpgcheck = 1\n'
                printf 'gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama\n'
                printf 'metalink = \nmirrorlist = \npkg_gpgcheck = 1\nrepo_gpgcheck = 1\n'
            done
            ;;
        alternate)
            for id in terra terra-legacy; do
                printf '======== "%s" repository configuration: ========\n' "$id"
                printf 'baseurl = https://repos.fyralabs.com/terra44\nenabled = 1\ngpgcheck = 1\n'
                printf 'gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama\n'
                printf 'metalink = \nmirrorlist = \npkg_gpgcheck = 1\nrepo_gpgcheck = 1\n'
            done
            ;;
        locale-unsafe)
            if [[ "${LC_ALL:-}" == C ]]; then
                printf '======== "terra" repository configuration: ========\n'
            else
                printf '======== "terra" Repository-Konfiguration: ========\n'
            fi
            printf 'baseurl = \nenabled = 1\ngpgcheck = 0\n'
            printf 'gpgkey = https://repos.fyralabs.com/terra44.key\n'
            printf 'metalink = https://tetsudou.fyralabs.com/terra44\nmirrorlist = \n'
            printf 'pkg_gpgcheck = 0\nrepo_gpgcheck = 0\n'
            ;;
        localized-output)
            printf '======== "terra" Repository-Konfiguration: ========\n'
            printf 'baseurl = \nenabled = 1\ngpgcheck = 0\n'
            ;;
        uppercase|mixed-case)
            [[ "$query" == full ]] || exit 0
            [[ "$mode" == uppercase ]] && id=TERRA || id=TeRrA
            printf '======== "%s" repository configuration: ========\n' "$id"
            printf 'baseurl = https://repos.fyralabs.com/terra44\nenabled = 1\ngpgcheck = 1\n'
            printf 'gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama\n'
            printf 'metalink = \nmirrorlist = \npkg_gpgcheck = 1\nrepo_gpgcheck = 1\n'
            ;;
        mixed-alternate)
            ids=(terra)
            [[ "$query" == filtered ]] || ids+=(TeRrA-legacy)
            for id in "${ids[@]}"; do
                printf '======== "%s" repository configuration: ========\n' "$id"
                printf 'baseurl = https://repos.fyralabs.com/terra44\nenabled = 1\ngpgcheck = 1\n'
                printf 'gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama\n'
                printf 'metalink = \nmirrorlist = \npkg_gpgcheck = 1\nrepo_gpgcheck = 1\n'
            done
            ;;
    esac
    exit 0
fi
exit 69
STUB

    cat > "$case_root/bin/flatpak" <<'STUB'
#!/usr/bin/env bash
exit 69
STUB
    chmod +x "$case_root/bin"/*
}

reset_installer_fixture() {
    cp "$config" "$installer_fixture/setup/provenance/installers.conf"
    cp "$repo_dir"/setup/provenance/keys/*.asc "$installer_fixture/setup/provenance/keys/"
}

write_flathub_descriptor() {
    local destination="$1" key="$2" verify_line="${3:-}" url="${4:-https://dl.flathub.org/repo/}"
    local encoded
    encoded="$(base64 -w 0 "$key")"
    printf '[Flatpak Repo]\nTitle=Flathub\nUrl=%s\nGPGKey=%s\n%s\n' \
        "$url" "$encoded" "$verify_line" > "$destination"
}

run_installer_function() {
    local name="$1" function_name="$2" case_root
    case_root="$test_tmp/cases/$name"
    rm -rf -- "$case_root"
    make_stub_commands "$case_root"
    : > "$case_root/commands.log"
    printf '0\n' > "$case_root/install-counter"
    printf 'preserved\n' > "$case_root/flatpak-state"
    : > "$case_root/softly-failed"
    case "${STUB_SEED_OLD:-}" in
        Node)
            mkdir -p "$case_root/home/.nvm/versions/node/v23.0.0/bin"
            printf '#!/usr/bin/env bash\nprintf "v23.0.0\\n"\n' \
                > "$case_root/home/.nvm/versions/node/v23.0.0/bin/node"
            chmod +x "$case_root/home/.nvm/versions/node/v23.0.0/bin/node"
            ;;
        Bun)
            mkdir -p "$case_root/home/.bun/versions/1.3.0/bin" "$case_root/home/.bun/bin"
            printf '#!/usr/bin/env bash\nprintf "1.3.0\\n"\n' \
                > "$case_root/home/.bun/versions/1.3.0/bin/bun"
            chmod +x "$case_root/home/.bun/versions/1.3.0/bin/bun"
            ln -s "$case_root/home/.bun/versions/1.3.0/bin/bun" "$case_root/home/.bun/bin/bun"
            ;;
        Codex)
            mkdir -p "$case_root/home/.local/lib/panama/codex/0.149.0" "$case_root/home/.local/bin"
            printf '#!/usr/bin/env bash\nprintf "codex-cli 0.149.0\\n"\n' \
                > "$case_root/home/.local/lib/panama/codex/0.149.0/codex"
            chmod +x "$case_root/home/.local/lib/panama/codex/0.149.0/codex"
            ln -s "$case_root/home/.local/lib/panama/codex/0.149.0/codex" \
                "$case_root/home/.local/bin/codex"
            ;;
    esac
    case "${STUB_SEED_EXACT:-}" in
        Node)
            mkdir -p "$case_root/home/.nvm/versions/node/v24.20.0/bin"
            printf '#!/usr/bin/env bash\nprintf "v24.20.0\\n"\n' \
                > "$case_root/home/.nvm/versions/node/v24.20.0/bin/node"
            chmod +x "$case_root/home/.nvm/versions/node/v24.20.0/bin/node"
            ;;
        Bun)
            mkdir -p "$case_root/home/.bun/versions/1.4.0/bin" "$case_root/home/.bun/bin"
            printf '#!/usr/bin/env bash\nprintf "1.4.0\\n"\n' \
                > "$case_root/home/.bun/versions/1.4.0/bin/bun"
            chmod +x "$case_root/home/.bun/versions/1.4.0/bin/bun"
            ln -s "$case_root/home/.bun/versions/1.4.0/bin/bun" "$case_root/home/.bun/bin/bun"
            ;;
        Codex)
            mkdir -p "$case_root/home/.local/lib/panama/codex/0.150.1" "$case_root/home/.local/bin"
            printf '#!/usr/bin/env bash\nprintf "codex-cli 0.150.1\\n"\n' \
                > "$case_root/home/.local/lib/panama/codex/0.150.1/codex"
            chmod +x "$case_root/home/.local/lib/panama/codex/0.150.1/codex"
            ln -s "$case_root/home/.local/lib/panama/codex/0.150.1/codex" \
                "$case_root/home/.local/bin/codex"
            ;;
    esac
    case "${STUB_SEED_COLLISION:-}" in
        Node)
            mkdir -p "$case_root/home/.nvm/versions/node/v24.20.0/bin"
            printf '#!/usr/bin/env bash\nprintf "v0.0.0\\n"\n' \
                > "$case_root/home/.nvm/versions/node/v24.20.0/bin/node"
            chmod +x "$case_root/home/.nvm/versions/node/v24.20.0/bin/node"
            ;;
        Bun)
            mkdir -p "$case_root/home/.bun/versions/1.4.0/bin"
            printf '#!/usr/bin/env bash\nprintf "0.0.0\\n"\n' \
                > "$case_root/home/.bun/versions/1.4.0/bin/bun"
            chmod +x "$case_root/home/.bun/versions/1.4.0/bin/bun"
            ;;
        Codex)
            mkdir -p "$case_root/home/.local/lib/panama/codex/0.150.1"
            printf '#!/usr/bin/env bash\nprintf "codex-cli 10.150.10\\n"\n' \
                > "$case_root/home/.local/lib/panama/codex/0.150.1/codex"
            chmod +x "$case_root/home/.local/lib/panama/codex/0.150.1/codex"
            ;;
    esac
    write_flathub_descriptor "$case_root/flathub.flatpakrepo" \
        "${STUB_FLATHUB_KEY_FILE:-$installer_fixture/setup/provenance/keys/flathub.asc}" \
        "${STUB_FLATHUB_VERIFY_LINE:-}" "${STUB_FLATHUB_URL:-https://dl.flathub.org/repo/}"
    if [[ "${STUB_EXISTING_REPOSITORY:-}" == hyprland \
        || "${STUB_PAIR_PRIOR:-}" == present && "${STUB_PAIR_NAME:-}" == hyprland ]]; then
        printf 'known key\n' > "$case_root/etc/pki/rpm-gpg/RPM-GPG-KEY-panama-hyprland"
        printf 'known repo\n' > "$case_root/etc/yum.repos.d/panama-hyprland.repo"
    fi
    if [[ "${STUB_PAIR_PRIOR:-}" == present && "${STUB_PAIR_NAME:-}" == claude-code ]]; then
        printf 'known key\n' > "$case_root/etc/pki/rpm-gpg/RPM-GPG-KEY-claude-code-panama"
        printf 'known repo\n' > "$case_root/etc/yum.repos.d/claude-code.repo"
    fi
    case "${STUB_TERRA_REPO_MODE:-absent}" in
        trusted)
            cp "$installer_fixture/setup/provenance/keys/terra44.asc" \
                "$case_root/etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama"
            printf '[terra]\nbaseurl=https://repos.fyralabs.com/terra44\nenabled=1\ngpgcheck=1\nrepo_gpgcheck=1\ngpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama\n' \
                > "$case_root/etc/yum.repos.d/terra.repo"
            ;;
        nogpg)
            printf '[terra]\nbaseurl=https://repos.fyralabs.com/terra44\nenabled=1\ngpgcheck=0\nrepo_gpgcheck=0\ngpgkey=https://repos.fyralabs.com/terra44.key\n' \
                > "$case_root/etc/yum.repos.d/terra.repo"
            ;;
        wrong-url)
            cp "$installer_fixture/setup/provenance/keys/terra44.asc" \
                "$case_root/etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama"
            printf '[terra]\nbaseurl=https://evil.invalid/terra44\nenabled=1\ngpgcheck=1\nrepo_gpgcheck=1\ngpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama\n' \
                > "$case_root/etc/yum.repos.d/terra.repo"
            ;;
        wrong-key)
            cp "$installer_fixture/setup/provenance/keys/flathub.asc" \
                "$case_root/etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama"
            printf '[terra]\nbaseurl=https://repos.fyralabs.com/terra44\nenabled=1\ngpgcheck=1\nrepo_gpgcheck=1\ngpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama\n' \
                > "$case_root/etc/yum.repos.d/terra.repo"
            ;;
    esac
    case "${STUB_FLATPAK_REMOTE_MODE:-absent}" in
        trusted)
            printf '[core]\nrepo_version=1\n\n[remote "flathub"]\nurl=https://dl.flathub.org/repo/\ngpg-verify=true\ngpg-verify-summary=true\n' \
                > "$case_root/flatpak-repo/config"
            cp "$installer_fixture/setup/provenance/keys/flathub.asc" \
                "$case_root/flatpak-repo/flathub.trustedkeys.gpg"
            ;;
        wrong-url)
            printf '[core]\nrepo_version=1\n\n[remote "flathub"]\nurl=https://evil.invalid/repo/\ngpg-verify=true\ngpg-verify-summary=true\n' \
                > "$case_root/flatpak-repo/config"
            cp "$installer_fixture/setup/provenance/keys/flathub.asc" \
                "$case_root/flatpak-repo/flathub.trustedkeys.gpg"
            ;;
        wrong-key)
            printf '[core]\nrepo_version=1\n\n[remote "flathub"]\nurl=https://dl.flathub.org/repo/\ngpg-verify=true\ngpg-verify-summary=true\n' \
                > "$case_root/flatpak-repo/config"
            cp "$installer_fixture/setup/provenance/keys/terra44.asc" \
                "$case_root/flatpak-repo/flathub.trustedkeys.gpg"
            ;;
        no-gpg)
            printf '[core]\nrepo_version=1\n\n[remote "flathub"]\nurl=https://dl.flathub.org/repo/\ngpg-verify=false\ngpg-verify-summary=false\n' \
                > "$case_root/flatpak-repo/config"
            cp "$installer_fixture/setup/provenance/keys/flathub.asc" \
                "$case_root/flatpak-repo/flathub.trustedkeys.gpg"
            ;;
        alternate-key)
            printf '[core]\nrepo_version=1\n\n[remote "flathub"]\nurl=https://dl.flathub.org/repo/\ngpg-verify=true\ngpg-verify-summary=true\ngpgkeypath=/unreviewed/keyring.gpg\n' \
                > "$case_root/flatpak-repo/config"
            cp "$installer_fixture/setup/provenance/keys/flathub.asc" \
                "$case_root/flatpak-repo/flathub.trustedkeys.gpg"
            ;;
        empty-alternate-key|duplicate-alternate-key|malformed-alternate-key)
            printf '[core]\nrepo_version=1\n\n[remote "flathub"]\nurl=https://dl.flathub.org/repo/\ngpg-verify=true\ngpg-verify-summary=true\n' \
                > "$case_root/flatpak-repo/config"
            case "$STUB_FLATPAK_REMOTE_MODE" in
                empty-alternate-key) printf 'gpgkeypath=\n' ;;
                duplicate-alternate-key) printf 'gpgkeypath=\ngpgkeypath=/unreviewed/keyring.gpg\n' ;;
                malformed-alternate-key) printf 'gpgkeypath /unreviewed/keyring.gpg\n' ;;
            esac >> "$case_root/flatpak-repo/config"
            cp "$installer_fixture/setup/provenance/keys/flathub.asc" \
                "$case_root/flatpak-repo/flathub.trustedkeys.gpg"
            ;;
    esac
    case "${STUB_CLAUDE_DESKTOP_REPO_MODE:-absent}" in
        trusted)
            cp "$installer_fixture/setup/provenance/keys/claude-desktop.asc" \
                "$case_root/etc/pki/rpm-gpg/claude-desktop-local.asc"
            printf '[claude-desktop]\nbaseurl=https://patrickjaja.github.io/claude-desktop-extra/rpm/\nenabled=1\ngpgcheck=1\nrepo_gpgcheck=1\ngpgkey=file://%s\n' \
                "$case_root/etc/pki/rpm-gpg/claude-desktop-local.asc" \
                > "$case_root/etc/yum.repos.d/claude-desktop.repo"
            ;;
        untrusted)
            cp "$installer_fixture/setup/provenance/keys/claude-desktop.asc" \
                "$case_root/etc/pki/rpm-gpg/claude-desktop-local.asc"
            printf '[claude-desktop]\nbaseurl=https://evil.invalid/rpm/\nenabled=1\ngpgcheck=0\nrepo_gpgcheck=0\ngpgkey=file://%s\n' \
                "$case_root/etc/pki/rpm-gpg/claude-desktop-local.asc" \
                > "$case_root/etc/yum.repos.d/claude-desktop.repo"
            ;;
    esac

    COMMAND_LOG="$case_root/commands.log" \
    SOFT_LOG="$case_root/softly-failed" \
    ARTIFACT_ROOT="$artifact_root" \
    FIXTURE_ROOT="$installer_fixture" \
    REVIEWED_KEYS="$repo_dir/setup/provenance/keys" \
    SIGNED_RPM="$test_tmp/signed-fixture.rpm" \
    FLATHUB_DESCRIPTOR="$case_root/flathub.flatpakrepo" \
    STUB_ETC="$case_root/etc" \
    STUB_FLATPAK_STATE="$case_root/flatpak-state" \
    STUB_FLATPAK_REPO="$case_root/flatpak-repo" \
    STUB_INSTALL_COUNTER="$case_root/install-counter" \
    LC_ALL="${STUB_CALLER_LOCALE:-C}" \
    HOME="$case_root/home" \
    NVM_DIR="$case_root/home/.nvm" \
    TMPDIR="$case_root/tmp" \
    PANAMA_PATH="$installer_fixture" \
    PATH="$case_root/bin:/usr/bin:/bin" \
        bash -c 'source "$PANAMA_PATH/setup/scripts/install-packages"; PANAMA_SYSTEM_ETC="$STUB_ETC"; PANAMA_SYSTEM_FLATPAK_REPO="$STUB_FLATPAK_REPO"; declare -F "$1" >/dev/null; status=0; "$1" || status=$?; (( ${#softly_failed[@]} == 0 )) || printf "%s\n" "${softly_failed[@]}" > "$SOFT_LOG"; exit "$status"' \
        bash "$function_name" > "$case_root/output" 2>&1
}

assert_log() {
    local name="$1" expected="$2" path
    path="$test_tmp/cases/$name/commands.log"
    [[ "$(<"$path")" == "$expected" ]] || {
        printf 'package provenance contract: unexpected %s command log\n' "$name" >&2
        diff -u <(printf '%s\n' "$expected") "$path" >&2 || true
        exit 1
    }
}

assert_soft_failure() {
    local name="$1" component="$2"
    [[ "$(<"$test_tmp/cases/$name/softly-failed")" == "$component" ]] \
        || fail "$name did not record exactly one $component soft failure"
}

assert_no_download() {
    local name="$1"
    [[ "$(<"$test_tmp/cases/$name/commands.log")" != *'curl:'* ]] \
        || fail "$name reached curl"
}

assert_no_runtime_staging() {
    local name="$1"
    [[ -z "$(find "$test_tmp/cases/$name/home" "$test_tmp/cases/$name/tmp" \
        \( -name '*.part.*' -o -name '*.stage.*' -o -name '*.link.*' \) -print -quit)" ]] \
        || fail "$name left private runtime staging behind"
}

assert_old_runtime_preserved() {
    local name="$1" component="$2" home="$test_tmp/cases/$name/home"
    case "$component" in
        Node)
            [[ "$($home/.nvm/versions/node/v23.0.0/bin/node --version)" == v23.0.0 ]] \
                || fail "$name changed the known-good Node"
            ;;
        Bun)
            [[ "$(readlink "$home/.bun/bin/bun")" == \
                "$home/.bun/versions/1.3.0/bin/bun" ]] \
                || fail "$name changed the active Bun link"
            [[ "$($home/.bun/bin/bun --version)" == 1.3.0 ]] \
                || fail "$name changed the known-good Bun"
            ;;
        Codex)
            [[ "$(readlink "$home/.local/bin/codex")" == \
                "$home/.local/lib/panama/codex/0.149.0/codex" ]] \
                || fail "$name changed the active Codex link"
            [[ "$($home/.local/bin/codex --version)" == 'codex-cli 0.149.0' ]] \
                || fail "$name changed the known-good Codex"
            ;;
    esac
}

# Each supported architecture selects its own reviewed URL, digest and archive
# layout. Successful activation leaves no private download or extraction tree.
for runtime_case in \
    'node-x86_64 x86_64 install_node Node https://nodejs.org/dist/v24.20.0/node-v24.20.0-linux-x64.tar.xz 67108864' \
    'node-aarch64 aarch64 install_node Node https://nodejs.org/dist/v24.20.0/node-v24.20.0-linux-arm64.tar.xz 67108864' \
    'bun-x86_64 x86_64 install_bun Bun https://github.com/oven-sh/bun/releases/download/bun-v1.4.0/bun-linux-x64.zip 67108864' \
    'bun-aarch64 aarch64 install_bun Bun https://github.com/oven-sh/bun/releases/download/bun-v1.4.0/bun-linux-aarch64.zip 67108864' \
    'codex-x86_64 x86_64 install_codex Codex https://github.com/openai/codex/releases/download/rust-v0.150.1/codex-package-x86_64-unknown-linux-musl.tar.gz 134217728' \
    'codex-aarch64 aarch64 install_codex Codex https://github.com/openai/codex/releases/download/rust-v0.150.1/codex-package-aarch64-unknown-linux-musl.tar.gz 134217728'; do
    read -r name arch function_name component url max_bytes <<<"$runtime_case"
    reset_installer_fixture
    if ! STUB_ARCH="$arch" run_installer_function "$name" "$function_name"; then
        tail -n 120 "$test_tmp/cases/$name/output" >&2
        fail "expected successful $name activation"
    fi
    grep -qFx "curl:$url:max=$max_bytes:output=artifact" \
        "$test_tmp/cases/$name/commands.log" \
        || { sed -n '1,80p' "$test_tmp/cases/$name/output" >&2; sed -n '1,80p' "$test_tmp/cases/$name/commands.log" >&2; fail "$name did not select its reviewed artifact"; }
    [[ ! -s "$test_tmp/cases/$name/softly-failed" ]] \
        || fail "$name recorded a soft failure after successful activation"
    assert_no_runtime_staging "$name"
done

[[ "$($test_tmp/cases/node-x86_64/home/.nvm/versions/node/v24.20.0/bin/node --version)" \
    == v24.20.0 ]] || fail 'x86_64 Node activation has the wrong version'
grep -qFx 'nvm:alias default 24.20.0' "$test_tmp/cases/node-x86_64/commands.log" \
    || fail 'Node did not set the exact nvm default alias'
[[ "$($test_tmp/cases/bun-x86_64/home/.bun/bin/bun --version)" == 1.4.0 ]] \
    || fail 'x86_64 Bun activation has the wrong version'
[[ "$(readlink "$test_tmp/cases/bun-x86_64/home/.bun/bin/bun")" == \
    "$test_tmp/cases/bun-x86_64/home/.bun/versions/1.4.0/bin/bun" ]] \
    || fail 'Bun did not atomically activate the reviewed version path'
[[ "$($test_tmp/cases/codex-x86_64/home/.local/bin/codex --version)" == \
    'codex-cli 0.150.1' ]] || fail 'x86_64 Codex activation has the wrong version'
[[ "$(readlink "$test_tmp/cases/codex-x86_64/home/.local/bin/codex")" == \
    "$test_tmp/cases/codex-x86_64/home/.local/lib/panama/codex/0.150.1/codex" ]] \
    || fail 'Codex did not atomically activate the reviewed version path'

# Unsupported CPUs stop before curl. RustDesk's reviewed RPM is x86_64-only,
# so aarch64 is also an intentional, recorded soft failure without a download.
for unsupported_case in \
    'node-unsupported install_node Node riscv64' \
    'bun-unsupported install_bun Bun riscv64' \
    'codex-unsupported install_codex Codex riscv64' \
    'rustdesk-unsupported install_rustdesk RustDesk riscv64' \
    'rustdesk-aarch64 install_rustdesk RustDesk aarch64'; do
    read -r name function_name component arch <<<"$unsupported_case"
    reset_installer_fixture
    STUB_ARCH="$arch" expect_failure run_installer_function "$name" "$function_name"
    assert_no_download "$name"
    assert_soft_failure "$name" "$component"
done

# A bad digest or interrupted transfer cannot replace the previously active
# tool and cannot leave reusable bytes behind.
for failure_mode in digest interrupted; do
    for component_spec in \
        'Node install_node' \
        'Bun install_bun' \
        'Codex install_codex'; do
        read -r component function_name <<<"$component_spec"
        name="${component,,}-$failure_mode"
        reset_installer_fixture
        if [[ "$failure_mode" == digest ]]; then
            STUB_SEED_OLD="$component" STUB_DIGEST_MISMATCH=1 \
                expect_failure run_installer_function "$name" "$function_name"
        else
            STUB_SEED_OLD="$component" STUB_DOWNLOAD_INTERRUPT=1 \
                expect_failure run_installer_function "$name" "$function_name"
        fi
        assert_soft_failure "$name" "$component"
        assert_old_runtime_preserved "$name" "$component"
        assert_no_runtime_staging "$name"
    done

    name="rustdesk-$failure_mode"
    reset_installer_fixture
    if [[ "$failure_mode" == digest ]]; then
        STUB_RUSTDESK_VERSION=1.4.8 STUB_DIGEST_MISMATCH=1 \
            expect_failure run_installer_function "$name" install_rustdesk
    else
        STUB_RUSTDESK_VERSION=1.4.8 STUB_DOWNLOAD_INTERRUPT=1 \
            expect_failure run_installer_function "$name" install_rustdesk
    fi
    assert_soft_failure "$name" RustDesk
    [[ "$(<"$test_tmp/cases/$name/commands.log")" != *'sudo:'* ]] \
        || fail "$name reached DNF with an unverified RPM"
    assert_no_runtime_staging "$name"
done

# Successful updates keep the old version directory and switch only the active
# symlink after the replacement binary has passed its version check.
for component_spec in 'Bun install_bun .bun/bin/bun .bun/versions/1.4.0/bin/bun' \
    'Codex install_codex .local/bin/codex .local/lib/panama/codex/0.150.1/codex'; do
    read -r component function_name active_relative target_relative <<<"$component_spec"
    name="${component,,}-atomic-update"
    reset_installer_fixture
    STUB_SEED_OLD="$component" expect_success run_installer_function "$name" "$function_name"
    [[ "$(readlink "$test_tmp/cases/$name/home/$active_relative")" == \
        "$test_tmp/cases/$name/home/$target_relative" ]] \
        || fail "$name did not atomically replace the active symlink"
    if [[ "$component" == Bun ]]; then
        [[ "$($test_tmp/cases/$name/home/.bun/versions/1.3.0/bin/bun --version)" == 1.3.0 ]] \
            || fail "$name removed the prior version directory"
    else
        [[ "$($test_tmp/cases/$name/home/.local/lib/panama/codex/0.149.0/codex --version)" \
            == 'codex-cli 0.149.0' ]] || fail "$name removed the prior version directory"
    fi
done

# A reviewed digest does not excuse a malformed archive. Reject the wrong top
# level or any extra member before a version path or active link appears.
for layout_case in \
    'node-layout install_node Node .nvm/versions/node/v24.20.0' \
    'bun-layout install_bun Bun .bun/versions/1.4.0' \
    'codex-layout install_codex Codex .local/lib/panama/codex/0.150.1'; do
    read -r name function_name component relative_target <<<"$layout_case"
    reset_installer_fixture
    STUB_BAD_LAYOUT=1 expect_failure run_installer_function "$name" "$function_name"
    assert_soft_failure "$name" "$component"
    [[ ! -e "$test_tmp/cases/$name/home/$relative_target" ]] \
        || fail "$name activated an archive with an unexpected layout"
    assert_no_runtime_staging "$name"
done

# A valid collision is a no-download no-op. An invalid collision is preserved
# and reported instead of being deleted and recreated.
for collision_mode in exact collision; do
    for component_spec in \
        'Node install_node' \
        'Bun install_bun' \
        'Codex install_codex'; do
        read -r component function_name <<<"$component_spec"
        name="${component,,}-$collision_mode"
        reset_installer_fixture
        if [[ "$collision_mode" == exact ]]; then
            STUB_SEED_EXACT="$component" expect_success \
                run_installer_function "$name" "$function_name"
            [[ ! -s "$test_tmp/cases/$name/softly-failed" ]] \
                || fail "$name reported a failure for the exact installed version"
        else
            STUB_SEED_COLLISION="$component" expect_failure \
                run_installer_function "$name" "$function_name"
            assert_soft_failure "$name" "$component"
        fi
        assert_no_download "$name"
    done
done

reset_installer_fixture
STUB_ARCH=x86_64 STUB_RUSTDESK_VERSION=1.4.8 \
    expect_success run_installer_function rustdesk-x86_64 install_rustdesk
assert_log rustdesk-x86_64 "$(cat <<'EXPECTED'
rpm:query:rustdesk
curl:https://github.com/rustdesk/rustdesk/releases/download/1.4.9/rustdesk-1.4.9-0.x86_64.rpm:max=134217728:output=rustdesk.rpm
sudo:dnf install -y --setopt=localpkg_gpgcheck=1 RUSTDESK_LOCAL
EXPECTED
)"
assert_no_runtime_staging rustdesk-x86_64

reset_installer_fixture
STUB_ARCH=x86_64 STUB_RUSTDESK_VERSION=1.4.9 \
    expect_success run_installer_function rustdesk-exact install_rustdesk
assert_log rustdesk-exact 'rpm:query:rustdesk'

reset_installer_fixture
expect_success run_installer_function pnpm install_pnpm
assert_log pnpm 'sudo:dnf install -y pnpm'

reset_installer_fixture
STUB_DNF_FAIL_MATCH=pnpm expect_failure run_installer_function pnpm-failure install_pnpm
assert_soft_failure pnpm-failure pnpm

reset_installer_fixture
expect_success run_installer_function rpmfusion install_rpmfusion_repositories
assert_log rpmfusion "$(cat <<'EXPECTED'
rpm:release
curl:https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-44.noarch.rpm:max=4194304:output=rpmfusion-free-release.rpm
gpg:fingerprint:E9A491A3DE247814E7E067EAE06F8ECDD651FF2E
rpmkeys:import:rpmfusion-free.asc
rpmkeys:checksig:rpmfusion-free-release.rpm
curl:https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-44.noarch.rpm:max=4194304:output=rpmfusion-nonfree-release.rpm
gpg:fingerprint:79BDB88F9BBF73910FD4095B6A2AF96194843C65
rpmkeys:import:rpmfusion-nonfree.asc
rpmkeys:checksig:rpmfusion-nonfree-release.rpm
sudo:dnf install -y --setopt=localpkg_gpgcheck=1 RPMFUSION_FREE RPMFUSION_NONFREE
EXPECTED
)"

reset_installer_fixture
expect_success run_installer_function terra install_terra_repository
assert_log terra "$(cat <<'EXPECTED'
rpm:release
dnf:dump-all:locale=C
rpm:query:terra-release
gpg:fingerprint:AE09157A4DE88B497EA1D5D300CDAB43DE226D6F
sudo:install:terra44.asc:/etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama
sudo:dnf install -y --repofrompath terra,https://repos.fyralabs.com/terra44 --setopt=terra.pkg_gpgcheck=1 --setopt=terra.repo_gpgcheck=1 --setopt=terra.gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama terra-release
sudo:install:terra.repo:/etc/yum.repos.d/terra.repo
dnf:dump-all:locale=C
gpg:fingerprint:AE09157A4DE88B497EA1D5D300CDAB43DE226D6F
gpg:fingerprint:AE09157A4DE88B497EA1D5D300CDAB43DE226D6F
EXPECTED
)"
cmp -s "$installer_fixture/setup/provenance/keys/terra44.asc" \
    "$test_tmp/cases/terra/etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama" \
    || fail 'Terra privileged install did not preserve the fully staged reviewed key'
assert_file_bytes "$test_tmp/cases/terra/etc/yum.repos.d/terra.repo" "$(cat <<'EXPECTED'
[terra]
name=Panama reviewed Terra 44
baseurl=https://repos.fyralabs.com/terra44
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama
EXPECTED
)"

reset_installer_fixture
expect_success run_installer_function hyprland configure_hyprland_repository
assert_log hyprland "$(cat <<'EXPECTED'
rpm:release
gpg:fingerprint:97E23476C89635135407C7D5E9BA41342C4B2995
sudo:install:hyprland-copr.asc:/etc/pki/rpm-gpg/RPM-GPG-KEY-panama-hyprland
sudo:install:panama-hyprland.repo:/etc/yum.repos.d/panama-hyprland.repo
EXPECTED
)"
cmp -s "$installer_fixture/setup/provenance/keys/hyprland-copr.asc" \
    "$test_tmp/cases/hyprland/etc/pki/rpm-gpg/RPM-GPG-KEY-panama-hyprland" \
    || fail 'Hyprland privileged install did not preserve the fully staged reviewed key'
assert_file_bytes "$test_tmp/cases/hyprland/etc/yum.repos.d/panama-hyprland.repo" "$(cat <<'EXPECTED'
[panama-hyprland]
name=Panama reviewed Hyprland COPR
baseurl=https://download.copr.fedorainfracloud.org/results/lionheartp/Hyprland/fedora-$releasever-$basearch/
enabled=1
gpgcheck=1
repo_gpgcheck=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-panama-hyprland
EXPECTED
)"

reset_installer_fixture
expect_success run_installer_function flathub ensure_flathub_remote
assert_log flathub "$(cat <<'EXPECTED'
rpm:release
curl:https://flathub.org/repo/flathub.flatpakrepo:max=1048576:output=flathub.flatpakrepo
gpg:fingerprint:6E5C05D979C76DAF93C081354184DD4D907A7CAE
sudo:flatpak remote-add --if-not-exists --gpg-import=FLATHUB_KEY flathub https://dl.flathub.org/repo/
gpg:fingerprint:6E5C05D979C76DAF93C081354184DD4D907A7CAE
EXPECTED
)"

reset_installer_fixture
expect_success run_installer_function claude-code install_claude_code
assert_log claude-code "$(cat <<'EXPECTED'
rpm:release
gpg:fingerprint:31DDDE24DDFAB679F42D7BD2BAA929FF1A7ECACE
sudo:install:claude-code.asc:/etc/pki/rpm-gpg/RPM-GPG-KEY-claude-code-panama
sudo:install:claude-code.repo:/etc/yum.repos.d/claude-code.repo
sudo:dnf install -y claude-code
EXPECTED
)"
cmp -s "$installer_fixture/setup/provenance/keys/claude-code.asc" \
    "$test_tmp/cases/claude-code/etc/pki/rpm-gpg/RPM-GPG-KEY-claude-code-panama" \
    || fail 'Claude Code privileged install did not preserve the fully staged reviewed key'
assert_file_bytes "$test_tmp/cases/claude-code/etc/yum.repos.d/claude-code.repo" "$(cat <<'EXPECTED'
[claude-code]
name=Claude Code
baseurl=https://downloads.claude.ai/claude-code/rpm/stable
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-claude-code-panama
EXPECTED
)"

reset_installer_fixture
expect_success run_installer_function claude-desktop-absent install_claude_desktop_if_trusted
assert_log claude-desktop-absent 'rpm:release'
[[ "$(grep -c 'Claude Desktop is optional; configure its reviewed local-key repository manually' \
    "$test_tmp/cases/claude-desktop-absent/output")" -eq 1 ]] \
    || fail 'absent Claude Desktop repository did not produce exactly one manual message'

reset_installer_fixture
STUB_CLAUDE_DESKTOP_REPO_MODE=trusted \
    expect_success run_installer_function claude-desktop-trusted install_claude_desktop_if_trusted
assert_log claude-desktop-trusted "$(cat <<'EXPECTED'
rpm:release
gpg:fingerprint:825A7D15D78BABE45646D5DF382409F597908867
gpg:fingerprint:825A7D15D78BABE45646D5DF382409F597908867
sudo:dnf install -y claude-desktop-extra
EXPECTED
)"

# Existing repository state is part of the trust boundary. Idempotency is only
# success when the already-active repository matches the reviewed policy.
reset_installer_fixture
STUB_FLATPAK_REMOTE_MODE=trusted \
    expect_success run_installer_function flathub-existing-trusted ensure_flathub_remote
assert_log flathub-existing-trusted "$(cat <<'EXPECTED'
rpm:release
gpg:fingerprint:6E5C05D979C76DAF93C081354184DD4D907A7CAE
EXPECTED
)"
assert_file_bytes "$test_tmp/cases/flathub-existing-trusted/flatpak-state" 'preserved'

for mode in wrong-url wrong-key no-gpg alternate-key empty-alternate-key \
    duplicate-alternate-key malformed-alternate-key; do
    reset_installer_fixture
    name="flathub-existing-$mode"
    STUB_FLATPAK_REMOTE_MODE="$mode" \
        expect_failure run_installer_function "$name" ensure_flathub_remote
    assert_file_bytes "$test_tmp/cases/$name/flatpak-state" 'preserved'
    [[ "$(<"$test_tmp/cases/$name/commands.log")" != *'curl:'* \
        && "$(<"$test_tmp/cases/$name/commands.log")" != *'sudo:'* ]] \
        || fail "untrusted existing Flathub $mode state was changed"
done

reset_installer_fixture
STUB_TERRA_INSTALLED=1 STUB_TERRA_REPO_MODE=trusted \
    expect_success run_installer_function terra-existing-trusted install_terra_repository
assert_log terra-existing-trusted "$(cat <<'EXPECTED'
rpm:release
dnf:dump-all:locale=C
gpg:fingerprint:AE09157A4DE88B497EA1D5D300CDAB43DE226D6F
gpg:fingerprint:AE09157A4DE88B497EA1D5D300CDAB43DE226D6F
EXPECTED
)"

for mode in nogpg wrong-url wrong-key absent; do
    reset_installer_fixture
    name="terra-existing-$mode"
    STUB_TERRA_INSTALLED=1 STUB_TERRA_REPO_MODE="$mode" \
        expect_failure run_installer_function "$name" install_terra_repository
    [[ "$(<"$test_tmp/cases/$name/commands.log")" != *'sudo:'* ]] \
        || fail "untrusted existing Terra $mode state reached a mutation"
done

# An optional security field may be absent, but duplicates are malformed even
# when one copy looks safe. These cases catch the absent/duplicate conflation.
for duplicate_case in \
    $'duplicate-no-gpg NoGPGVerify=false\nNoGPGVerify=true' \
    $'duplicate-gpg-verify GPGVerify=true\nGPGVerify=false' \
    'alternate-gpg-key-path GPGKeyPath=/unreviewed/keyring.gpg' \
    'empty-gpg-key-path GPGKeyPath=' \
    $'duplicate-gpg-key-path GPGKeyPath=\nGPGKeyPath=/unreviewed/keyring.gpg' \
    'malformed-gpg-key-path GPGKeyPath /unreviewed/keyring.gpg'; do
    name="${duplicate_case%% *}"
    lines="${duplicate_case#* }"
    reset_installer_fixture
    STUB_FLATHUB_VERIFY_LINE="$lines" \
        expect_failure run_installer_function "$name" ensure_flathub_remote
    assert_file_bytes "$test_tmp/cases/$name/flatpak-state" 'preserved'
    [[ "$(<"$test_tmp/cases/$name/commands.log")" != *'sudo:'* ]] \
        || fail "$name descriptor reached remote activation"
done

# DNF's non-networking effective configuration dump, rather than any one repo
# file, decides whether Terra is absent, trusted, overridden, or duplicated.
reset_installer_fixture
STUB_TERRA_EFFECTIVE_MODE=absent \
    expect_success run_installer_function terra-effective-absent preflight_terra_trust
assert_log terra-effective-absent 'dnf:dump-all:locale=C'

reset_installer_fixture
STUB_TERRA_EFFECTIVE_MODE=trusted STUB_TERRA_REPO_MODE=trusted \
    expect_success run_installer_function terra-effective-trusted preflight_terra_trust
assert_log terra-effective-trusted "$(cat <<'EXPECTED'
dnf:dump-all:locale=C
gpg:fingerprint:AE09157A4DE88B497EA1D5D300CDAB43DE226D6F
gpg:fingerprint:AE09157A4DE88B497EA1D5D300CDAB43DE226D6F
EXPECTED
)"

for mode in legacy override-url override-gpg duplicate alternate; do
    reset_installer_fixture
    name="terra-effective-$mode"
    status=0
    STUB_TERRA_EFFECTIVE_MODE="$mode" STUB_TERRA_REPO_MODE=trusted \
        run_installer_function "$name" preflight_terra_trust || status=$?
    [[ "$status" -eq 78 ]] \
        || fail "effective Terra $mode returned $status instead of hard trust status 78"
    [[ "$(<"$test_tmp/cases/$name/commands.log")" != *'sudo:'* ]] \
        || fail "effective Terra $mode reached a transaction"
done

# The full effective configuration must reveal case variants and mixed-case
# alternate identities that a lowercase terra* selector omits.
for identity_case in uppercase mixed-case mixed-alternate; do
    reset_installer_fixture
    name="terra-effective-$identity_case"
    status=0
    STUB_TERRA_EFFECTIVE_MODE="$identity_case" STUB_TERRA_REPO_MODE=trusted \
        run_installer_function "$name" preflight_terra_trust || status=$?
    [[ "$status" -eq 78 ]] \
        || fail "effective Terra $identity_case returned $status instead of hard trust status 78"
done

# DNF output must be locale-stable, and nonempty output that does not match the
# machine format is unsafe rather than equivalent to a fresh host.
for locale_case in locale-unsafe localized-output; do
    reset_installer_fixture
    name="terra-effective-$locale_case"
    status=0
    STUB_CALLER_LOCALE=C.UTF-8 STUB_TERRA_EFFECTIVE_MODE="$locale_case" \
        run_installer_function "$name" preflight_terra_trust || status=$?
    [[ "$status" -eq 78 ]] \
        || fail "effective Terra $locale_case returned $status instead of hard trust status 78"
    assert_log "$name" 'dnf:dump-all:locale=C'
done

assert_pair_rollback() {
    local name="$1" pair="$2" prior="$3" key repo
    case "$pair" in
        hyprland)
            key="$test_tmp/cases/$name/etc/pki/rpm-gpg/RPM-GPG-KEY-panama-hyprland"
            repo="$test_tmp/cases/$name/etc/yum.repos.d/panama-hyprland.repo"
            ;;
        claude-code)
            key="$test_tmp/cases/$name/etc/pki/rpm-gpg/RPM-GPG-KEY-claude-code-panama"
            repo="$test_tmp/cases/$name/etc/yum.repos.d/claude-code.repo"
            ;;
    esac
    if [[ "$prior" == present ]]; then
        assert_file_bytes "$key" 'known key'
        assert_file_bytes "$repo" 'known repo'
    else
        [[ ! -e "$key" && ! -e "$repo" ]] \
            || fail "$pair activation failure left part of an absent pair"
    fi
    [[ "$(<"$test_tmp/cases/$name/commands.log")" != *'sudo:dnf'* ]] \
        || fail "$pair activation failure reached DNF"
}

# Both activation writes can fail after changing their target. Each repository
# must restore known-good pairs and return prior-absent pairs to full absence.
for pair_spec in \
    'hyprland configure_hyprland_repository' \
    'claude-code install_claude_code'; do
    read -r pair function_name <<<"$pair_spec"
    for prior in absent present; do
        for fail_at in 1 2; do
            reset_installer_fixture
            name="$pair-$prior-activation-$fail_at"
            STUB_PAIR_NAME="$pair" STUB_PAIR_PRIOR="$prior" STUB_INSTALL_FAIL_AT="$fail_at" \
                expect_failure run_installer_function "$name" "$function_name"
            assert_pair_rollback "$name" "$pair" "$prior"
        done
    done
done

# A Fedora version outside the reviewed policy stops every public transaction
# before curl, sudo, Flatpak, or repository inspection can act.
for function_name in install_rpmfusion_repositories install_terra_repository \
    configure_hyprland_repository ensure_flathub_remote install_claude_code \
    install_claude_desktop_if_trusted; do
    reset_installer_fixture
    name="wrong-fedora-${function_name}"
    STUB_FEDORA_RELEASE=45 expect_failure run_installer_function "$name" "$function_name"
    assert_log "$name" 'rpm:release'
    if [[ "$function_name" == install_claude_code ]]; then
        assert_soft_failure "$name" 'Claude Code'
    fi
done

reset_installer_fixture
sed -i 's#^RPMFUSION_FREE_RELEASE_URL=.*#RPMFUSION_FREE_RELEASE_URL=https://evil.invalid/free.rpm#' \
    "$installer_fixture/setup/provenance/installers.conf"
expect_failure run_installer_function rpmfusion-wrong-url install_rpmfusion_repositories
assert_log rpmfusion-wrong-url 'rpm:release'

for policy_case in \
    'terra-wrong-url TERRA_BASEURL install_terra_repository' \
    'hyprland-wrong-url HYPRLAND_COPR_BASEURL configure_hyprland_repository' \
    'flathub-wrong-url FLATHUB_DESCRIPTOR_URL ensure_flathub_remote' \
    'claude-code-wrong-url CLAUDE_CODE_BASEURL install_claude_code' \
    'claude-desktop-wrong-url CLAUDE_DESKTOP_BASEURL install_claude_desktop_if_trusted'; do
    read -r name config_name function_name <<<"$policy_case"
    reset_installer_fixture
    sed -i "s#^${config_name}=.*#${config_name}=https://evil.invalid/#" \
        "$installer_fixture/setup/provenance/installers.conf"
    expect_failure run_installer_function "$name" "$function_name"
    [[ "$(<"$test_tmp/cases/$name/commands.log")" != *'curl:'* \
        && "$(<"$test_tmp/cases/$name/commands.log")" != *'sudo:'* ]] \
        || fail "$config_name mismatch reached a download or mutation"
done

reset_installer_fixture
cp "$installer_fixture/setup/provenance/keys/terra44.asc" \
    "$installer_fixture/setup/provenance/keys/rpmfusion-free.asc"
expect_failure run_installer_function rpmfusion-wrong-key install_rpmfusion_repositories
assert_log rpmfusion-wrong-key "$(cat <<'EXPECTED'
rpm:release
curl:https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-44.noarch.rpm:max=4194304:output=rpmfusion-free-release.rpm
gpg:fingerprint:AE09157A4DE88B497EA1D5D300CDAB43DE226D6F
EXPECTED
)"

reset_installer_fixture
STUB_RPM_SIGNATURE_FAIL=rpmfusion-free-release.rpm \
    expect_failure run_installer_function rpmfusion-bad-signature install_rpmfusion_repositories
[[ "$(<"$test_tmp/cases/rpmfusion-bad-signature/commands.log")" != *'rpmfusion-nonfree'* ]] \
    || fail 'RPM Fusion signature failure did not stop the dependent download'
[[ "$(<"$test_tmp/cases/rpmfusion-bad-signature/commands.log")" != *'sudo:'* ]] \
    || fail 'RPM Fusion signature failure reached a privileged mutation'

reset_installer_fixture
cp "$installer_fixture/setup/provenance/keys/terra44.asc" \
    "$installer_fixture/setup/provenance/keys/hyprland-copr.asc"
STUB_EXISTING_REPOSITORY=hyprland \
    expect_failure run_installer_function hyprland-wrong-key configure_hyprland_repository
assert_file_bytes "$test_tmp/cases/hyprland-wrong-key/etc/pki/rpm-gpg/RPM-GPG-KEY-panama-hyprland" \
    'known key'
assert_file_bytes "$test_tmp/cases/hyprland-wrong-key/etc/yum.repos.d/panama-hyprland.repo" \
    'known repo'
[[ "$(<"$test_tmp/cases/hyprland-wrong-key/commands.log")" != *'sudo:'* ]] \
    || fail 'Hyprland key mismatch replaced known-good repository files'

reset_installer_fixture
STUB_FLATHUB_VERIFY_LINE='NoGPGVerify=true' \
    expect_failure run_installer_function flathub-no-gpg ensure_flathub_remote
assert_file_bytes "$test_tmp/cases/flathub-no-gpg/flatpak-state" 'preserved'
[[ "$(<"$test_tmp/cases/flathub-no-gpg/commands.log")" != *'sudo:'* ]] \
    || fail 'Flathub disabled-GPG descriptor mutated a remote'

reset_installer_fixture
STUB_FLATHUB_KEY_FILE="$installer_fixture/setup/provenance/keys/terra44.asc" \
    expect_failure run_installer_function flathub-wrong-key ensure_flathub_remote
assert_file_bytes "$test_tmp/cases/flathub-wrong-key/flatpak-state" 'preserved'
[[ "$(<"$test_tmp/cases/flathub-wrong-key/commands.log")" != *'sudo:'* ]] \
    || fail 'Flathub key mismatch mutated an existing remote'

reset_installer_fixture
STUB_FLATHUB_URL='https://evil.invalid/repo/' \
    expect_failure run_installer_function flathub-wrong-repo-url ensure_flathub_remote
assert_file_bytes "$test_tmp/cases/flathub-wrong-repo-url/flatpak-state" 'preserved'
[[ "$(<"$test_tmp/cases/flathub-wrong-repo-url/commands.log")" != *'sudo:'* ]] \
    || fail 'Flathub repository URL mismatch mutated an existing remote'

reset_installer_fixture
STUB_CLAUDE_DESKTOP_REPO_MODE=untrusted \
    expect_success run_installer_function claude-desktop-untrusted install_claude_desktop_if_trusted
assert_log claude-desktop-untrusted 'rpm:release'
[[ "$(grep -c 'Claude Desktop is optional; configure its reviewed local-key repository manually' \
    "$test_tmp/cases/claude-desktop-untrusted/output")" -eq 1 ]] \
    || fail 'untrusted Claude Desktop repository did not produce one manual message'

reset_installer_fixture
STUB_DNF_FAIL_MATCH=terra-release expect_failure run_installer_function terra-dnf-failure install_terra_repository
[[ "$(tail -n 1 "$test_tmp/cases/terra-dnf-failure/commands.log")" == *'terra-release' ]] \
    || fail 'Terra DNF failure ran a later transaction command'
[[ -z "$(find "$test_tmp/cases/terra-dnf-failure/tmp" -mindepth 1 -print -quit)" ]] \
    || fail 'Terra DNF failure left private staging files behind'

[[ "$before_gnupg" == "$(snapshot "$host_gnupg")" ]] || fail 'repository cases changed host GPG state'
[[ "$before_gpg_files" == "$(snapshot_gpg_state "$host_gnupg")" ]] \
    || fail 'repository cases changed host GPG files'
[[ "$before_rpmdb" == "$(snapshot "$host_rpmdb")" ]] || fail 'repository cases changed host RPM database'
[[ "$before_repo_files" == "$(snapshot_gpg_state /etc/yum.repos.d)" ]] \
    || fail 'repository cases changed host repository files'
[[ "$before_rpm_key_files" == "$(snapshot_gpg_state /etc/pki/rpm-gpg)" ]] \
    || fail 'repository cases changed host RPM key files'
[[ "$before_system_flatpak" == "$(snapshot_file_state /var/lib/flatpak/repo/config)" ]] \
    || fail 'repository cases changed the system Flatpak remote'
[[ "$before_system_flathub_key" == "$(snapshot_file_state /var/lib/flatpak/repo/flathub.trustedkeys.gpg)" ]] \
    || fail 'repository cases changed the system Flathub trusted key'
[[ "$before_user_flatpak" == "$(snapshot_file_state "$HOME/.local/share/flatpak/repo/config")" ]] \
    || fail 'repository cases changed the user Flatpak remote'
[[ "$before_bashrc" == "$(snapshot_file_state "$HOME/.bashrc")" ]] \
    || fail 'repository cases changed the protected bashrc'

printf 'package provenance contract: PASS\n'
