#!/usr/bin/env bash

set -euo pipefail

# Defer process-group interrupts until the active scoped transaction has run
# its own rollback and cleanup traps, then leave this package stage unchanged.
trap 'exit 130' INT
trap 'exit 143' TERM

# --- Helper functions ---
log() { echo -e "\033[1;34m[INFO]\033[0m $*"; }
exists() { command -v "$1" >/dev/null 2>&1; }

# The package names in a list, without the comments that explain them.
#
# The lists are annotated -- which package exists for which settings page, why
# an exception was made -- and those annotations are for whoever reads the file
# next. dnf is not so forgiving: it does not ignore an argument it cannot
# match, it reports "No match for argument: #" and exits 1, and with `set -e`
# above that ends this stage on the first annotated list it reaches.
#
# It could not be seen from here. On a machine that already has everything, a
# re-run matches every real name and fails only on the comments; and every
# contract that reads these lists strips comments before comparing, so the
# tests were reading a file this script was not.
packages_in() {
	sed 's/#.*//' "$1" | tr "\n" " "
}

# Names a list asked for that still are not installed, so --skip-unavailable
# above can never silently shrink a list: a skipped font is a warning somebody
# reads, not an absence somebody debugs a month later.
report_missing() {
	local file="$1" name missing=()
	for name in $(packages_in "$file"); do
		# Three ways a list entry can be satisfied: it is a package name
		# (rpm -q), a capability another package provides (--whatprovides,
		# e.g. wget -> wget2-wget), or a bare command name provided as a file
		# path (command -v, e.g. awk -> /usr/bin/awk from gawk, which
		# --whatprovides misses because the provide is the path, not the word).
		rpm -q --whatprovides "$name" >/dev/null 2>&1 && continue
		command -v "$name" >/dev/null 2>&1 && continue
		missing+=("$name")
	done
	(( ${#missing[@]} > 0 )) && log "WARNING: not available on this machine: ${missing[*]}"
	return 0
}

# Runs something whose failure must not cost you the desktop.
#
# `set -e` above is right for the packages Panama cannot work without and wrong
# for everything else. A codec swap that finds nothing to swap, a group update
# renamed upstream, a third-party host that is down -- each of those used to end
# this stage wherever it happened to sit, and the desktop was installed near the
# bottom, so any one of them meant a machine with no Hyprland on it and a single
# line of dnf output to explain why.
#
# So the ordering rule for this file: anything that can fail for a reason
# outside this repository goes below the desktop, and goes through here.
# stdout only. Swallowing stderr here would hide the one line that says WHY a
# step was stepped over -- and worse, every one of these runs under sudo, whose
# password prompt is the thing you would be hiding on a machine that asks for
# one.
soft() {
	local what="$1"; shift
	"$@" >/dev/null || { log "$what did not complete; continuing"; softly_failed+=("$what"); }
}
softly_failed=()

# --- Defined Paths ---
# The default, not an assignment: ./install and link-dotfiles honor an exported
# PANAMA_PATH, and clobbering it here made a clone anywhere else source the
# extras catalog from a path that does not exist.
PANAMA_PATH="${PANAMA_PATH:-$HOME/.local/share/Panama}"
# Kept as a named path so the hermetic contract can redirect reads after
# sourcing this file. Normal installer execution always resets it to /etc.
PANAMA_SYSTEM_ETC=/etc
PANAMA_SYSTEM_FLATPAK_REPO=/var/lib/flatpak/repo
PRIVILEGED_TMPDIR=/var/tmp

BASE_REPO_ARGS=(--repo=fedora --repo=updates)
RPMFUSION_REPO_ARGS=(
	"${BASE_REPO_ARGS[@]}"
	--repo=rpmfusion-free --repo=rpmfusion-free-updates
	--repo=rpmfusion-nonfree --repo=rpmfusion-nonfree-updates
)
RPMFUSION_FROM_REPOS='fedora,updates,rpmfusion-free,rpmfusion-free-updates,rpmfusion-nonfree,rpmfusion-nonfree-updates'
PACKAGE_REPO_ARGS=(
	"${BASE_REPO_ARGS[@]}" --from-repo=fedora,updates
)

_root_snapshot_directory_is_safe() {
	local directory="$1"
	[[ "$(dirname -- "$directory")" == "$PRIVILEGED_TMPDIR" \
		&& "$(basename -- "$directory")" =~ ^panama-install\.[[:alnum:]]+$ ]]
}

_remove_root_snapshot() {
	local snapshot="$1" directory identity
	directory="$(dirname -- "$snapshot")"
	_root_snapshot_directory_is_safe "$directory" || return 1
	sudo test -d "$directory" || return 1
	sudo test ! -L "$directory" || return 1
	identity="$(sudo stat -c '%u:%a' -- "$directory")" || return 1
	[[ "$identity" == '0:700' || "$identity" == '0:711' ]] || return 1
	if [[ "$identity" == '0:711' ]]; then
		sudo chmod 0700 "$directory" || return 1
		identity="$(sudo stat -c '%u:%a' -- "$directory")" || return 1
		[[ "$identity" == '0:700' ]] || return 1
	fi
	if ! sudo rm -rf -- "$directory"; then
		printf 'Installer staging cleanup failed. Retained artifact: %s\n' \
			"$directory" >&2
		return 1
	fi
}

_root_owned_regular_file_is_safe() {
	local file="$1" identity owner mode
	[[ -f "$file" && ! -L "$file" ]] || return 1
	identity="$(stat -c '%u:%a' -- "$file")" || return 1
	IFS=: read -r owner mode <<<"$identity"
	[[ "$owner" == 0 && "$mode" =~ ^[0-7]{3,4}$ ]] || return 1
	(( (8#$mode & 0022) == 0 ))
}

_stable_file_digest() {
	local file="$1" output_name="$2" before after
	[[ -f "$file" && ! -L "$file" ]] || return 1
	before="$(sha256sum -- "$file" | awk '{ print $1 }')" || return 1
	after="$(sha256sum -- "$file" | awk '{ print $1 }')" || return 1
	[[ "$before" =~ ^[0-9a-f]{64}$ && "$before" == "$after" ]] || return 1
	printf -v "$output_name" '%s' "$before"
}

_make_private_directory() {
	local output_name="$1" template="$2" candidate
	printf -v "$output_name" '%s' ''
	candidate="$(mktemp -u -d "$template")" || return 1
	printf -v "$output_name" '%s' "$candidate"
	if ! mkdir -m 700 -- "$candidate"; then
		printf -v "$output_name" '%s' ''
		return 1
	fi
}

# Copy a digest-attested user file into a private root-owned directory, then
# have the privileged adapter hash the exact immutable copy it will reopen.
# The caller owns the random candidate before privileged creation starts. Its
# already-armed transaction trap can therefore remove a directory even when a
# signal interrupts mkdir, without a command-substitution handoff window.
_stage_root_snapshot() {
	local source="$1" expected="$2" name="$3" output_name="$4"
	local directory="" snapshot actual identity
	printf -v "$output_name" '%s' ''
	[[ -f "$source" && ! -L "$source" && "$expected" =~ ^[0-9a-f]{64}$ \
		&& "$name" =~ ^[[:alnum:]_.-]+$ ]] || return 1
	directory="$(mktemp -u "$PRIVILEGED_TMPDIR/panama-install.XXXXXX")" || return 1
	_root_snapshot_directory_is_safe "$directory" || return 1
	snapshot="$directory/$name"
	printf -v "$output_name" '%s' "$snapshot"
	if ! sudo mkdir -m 0700 -- "$directory" \
		|| ! sudo test -d "$directory" \
		|| ! sudo test ! -L "$directory" \
		|| ! identity="$(sudo stat -c '%u:%a' -- "$directory")" \
		|| [[ "$identity" != '0:700' ]] \
		|| ! sudo chmod 0700 "$directory" \
		|| ! sudo install -m 0444 "$source" "$snapshot" \
		|| ! actual="$(sudo sha256sum -- "$snapshot" | awk '{ print $1 }')" \
		|| [[ "$actual" != "$expected" ]]; then
		if _remove_root_snapshot "$snapshot" >/dev/null 2>&1; then
			printf -v "$output_name" '%s' ''
		fi
		return 1
	fi
}

# Signed installer inputs are public, so their root-owned snapshot can be made
# traversable just long enough for unprivileged GPG/rpmkeys to read it. The
# file itself remains root-owned and read-only; after verification the random
# directory is private again before any privileged consumer reopens it.
_review_root_snapshots() {
	local snapshot status=0 hide_status=0
	local -a snapshots=()
	while (( $# > 0 )) && [[ "$1" != -- ]]; do
		snapshots+=("$1")
		shift
	done
	(( ${#snapshots[@]} > 0 && $# > 1 )) || return 1
	shift
	for snapshot in "${snapshots[@]}"; do
		_root_snapshot_directory_is_safe "$(dirname -- "$snapshot")" \
			&& sudo chmod 0711 "$(dirname -- "$snapshot")" || { status=1; break; }
	done
	if (( status == 0 )); then
		"$@" || status=$?
	fi
	for snapshot in "${snapshots[@]}"; do
		_root_snapshot_directory_is_safe "$(dirname -- "$snapshot")" || continue
		sudo chmod 0700 "$(dirname -- "$snapshot")" || hide_status=$?
	done
	(( hide_status == 0 )) || return 1
	return "$status"
}

# Reviewed installer data and verification primitives. The config parser treats
# every value as inert data and rejects unknown, duplicate, or missing fields.
# shellcheck source=../lib/artifact-provenance
source "$PANAMA_PATH/setup/lib/artifact-provenance"
load_installer_provenance "$PANAMA_PATH/setup/provenance/installers.conf"

# Reading the extras catalog, shared with `panama apps` so the two front doors
# cannot disagree about what a category contains.
# shellcheck source=../lib/extras-catalog
source "$PANAMA_PATH/setup/lib/extras-catalog"

# Which machine this is. A server takes the short path below: core tools,
# node, the agents -- no third-party repos, no desktop, no flatpaks.
# shellcheck source=../lib/machine-role
source "$PANAMA_PATH/setup/lib/machine-role"
ROLE="$(panama_role)"

# One list, installed the way every list is installed: --skip-unavailable so a
# single rotted name cannot cost the transaction, then report_missing so a
# skipped name is a warning somebody reads.
install_list() {
	local file="$PANAMA_PATH/setup/packages/$1" label="$2" packages
	if [[ -f "$file" ]]; then
		packages=$(packages_in "$file")
		log "Installing $label Packages"
		echo -e "Includes the following packages:"
		echo -e "$(<"$file")"
		sudo dnf install -y "${PACKAGE_REPO_ARGS[@]}" \
			--skip-unavailable $packages > /dev/null
		report_missing "$file"
		log "$label packages installed!"
	else
		log "Package list was not in specified path: $file"
	fi
}

# --- Reviewed language runtimes and agent tools ------------------------------

_record_installer_failure() {
	local component="$1"
	log "$component install did not complete; continuing"
	softly_failed+=("$component")
	return 1
}

_set_artifact_arch() {
	local machine_arch
	machine_arch="$(uname -m)" || return 1
	case "$machine_arch" in
		x86_64) artifact_arch=X86_64 ;;
		aarch64) artifact_arch=AARCH64 ;;
		*) log "Unsupported architecture: $machine_arch"; return 1 ;;
	esac
}

_archive_path_is_safe() {
	local member="$1"
	[[ -n "$member" && "$member" != /* && "$member" != *'//'*
		&& ! "$member" =~ (^|/)\.\.?(/|$) ]]
}

_archive_member_is_safe() {
	local member="$1" expected_top="$2"
	_archive_path_is_safe "$member"
	[[ "$member" == "$expected_top" || "$member" == "$expected_top/" \
		|| "$member" == "$expected_top/"* ]]
}

_bun_zip_entry_types_match() {
	local archive="$1" archive_top="$2" details entry_types
	details="$(unzip -Z -s "$archive")" || return 1
	entry_types="$(awk -v directory="$archive_top/" -v binary="$archive_top/bun" '
		$NF == directory || $NF == binary { print substr($1, 1, 1), $NF }
	' <<<"$details")" || return 1
	[[ "$entry_types" == "d $archive_top/"$'\n'"- $archive_top/bun" ]]
}

_tree_links_stay_inside() {
	local root="$1" link resolved scan_fd scan_pid scan_status=0 invalid=0
	# Retain and wait for find's PID: a loop fed directly by process substitution
	# cannot otherwise distinguish an empty tree from a failed traversal.
	exec {scan_fd}< <(find "$root" -type l -print0)
	scan_pid=$!
	while IFS= read -r -d '' link <&"$scan_fd"; do
		resolved="$(realpath -m -- "$link")" || { invalid=1; continue; }
		[[ "$resolved" == "$root" || "$resolved" == "$root/"* ]] || invalid=1
	done
	exec {scan_fd}<&-
	wait "$scan_pid" || scan_status=$?
	(( scan_status == 0 && invalid == 0 ))
}

_tree_hardlinks_stay_inside() {
	local root="$1" device inode link_count key scan_fd scan_pid scan_status=0
	local invalid=0
	local -A names_in_tree=() inode_links=()
	exec {scan_fd}< <(find "$root" -type f -printf '%D %i %n\n')
	scan_pid=$!
	while read -r device inode link_count <&"$scan_fd"; do
		key="$device:$inode"
		names_in_tree["$key"]=$(( ${names_in_tree[$key]:-0} + 1 ))
		inode_links["$key"]="$link_count"
	done
	exec {scan_fd}<&-
	wait "$scan_pid" || scan_status=$?
	(( scan_status == 0 )) || return 1
	for key in "${!names_in_tree[@]}"; do
		[[ "${names_in_tree[$key]}" == "${inode_links[$key]}" ]] || invalid=1
	done
	(( invalid == 0 ))
}

_atomic_symlink() (
	local target="$1" destination="$2" directory temporary=""
	trap '[[ -z "$temporary" ]] || rm -f -- "$temporary"' EXIT
	trap 'exit 130' INT
	trap 'exit 143' TERM
	directory="$(dirname -- "$destination")"
	mkdir -p -- "$directory" || return 1
	temporary="$(mktemp -u "$directory/.$(basename -- "$destination").link.XXXXXX")" \
		|| return 1
	umask 077
	if ! (set -o noclobber; : >"$temporary") 2>/dev/null; then
		temporary=""
		return 1
	fi
	rm -f -- "$temporary" || return 1
	ln -s -- "$target" "$temporary" || return 1
	if ! mv -Tf -- "$temporary" "$destination"; then
		return 1
	fi
)

_activate_directory_no_replace() {
	local staged="$1" destination="$2"
	mv -Tn -- "$staged" "$destination" || return 1
	[[ ! -e "$staged" && ! -L "$staged" && -d "$destination" && ! -L "$destination" ]]
}

_write_runtime_receipt() {
	local directory="$1" artifact_digest="$2" binary_digest="$3"
	local receipt="$directory/.panama-provenance"
	[[ -d "$directory" && ! -L "$directory" && ! -e "$receipt" && ! -L "$receipt" ]] \
		|| return 1
	( umask 077 && printf 'schema=1\nartifact_sha256=%s\nbinary_sha256=%s\n' \
		"$artifact_digest" "$binary_digest" > "$receipt" )
}

_runtime_receipt_matches() {
	local directory="$1" binary="$2" artifact_digest="$3" binary_digest="$4"
	local receipt="$directory/.panama-provenance" actual
	[[ -d "$directory" && ! -L "$directory"
		&& -f "$receipt" && ! -L "$receipt"
		&& -f "$binary" && ! -L "$binary" ]] || return 1
	cmp -s "$receipt" <(printf 'schema=1\nartifact_sha256=%s\nbinary_sha256=%s\n' \
		"$artifact_digest" "$binary_digest") || return 1
	actual="$(sha256sum "$binary" | awk '{ print $1 }')" || return 1
	[[ "$actual" == "$binary_digest" ]]
}

_load_nvm() {
	local nvm_script="$PANAMA_SYSTEM_ETC/profile.d/nvm.sh"
	[[ -s "$nvm_script" ]] || return 1
	set +u
	# shellcheck source=/dev/null
	source "$nvm_script"
	set -u
	declare -F nvm >/dev/null
}

_install_node() (
	local artifact_arch machine_arch archive_top parent target stage archive extract listing member
	local artifact_digest binary_digest staged_binary
	stage=""
	trap '[[ -z "$stage" ]] || rm -rf -- "$stage"' EXIT
	trap 'exit 130' INT
	trap 'exit 143' TERM
	_set_artifact_arch || return 1
	_load_nvm || return 1
	case "$artifact_arch" in
		X86_64) machine_arch=x64 ;;
		AARCH64) machine_arch=arm64 ;;
	esac
	archive_top="node-v${INSTALLER_PROVENANCE[NODE_VERSION]}-linux-$machine_arch"
	parent="${NVM_DIR:-$HOME/.nvm}/versions/node"
	target="$parent/v${INSTALLER_PROVENANCE[NODE_VERSION]}"
	artifact_digest="${INSTALLER_PROVENANCE[NODE_${artifact_arch}_SHA256]}"
	binary_digest="${INSTALLER_PROVENANCE[NODE_${artifact_arch}_BINARY_SHA256]}"
	if [[ -e "$target" || -L "$target" ]]; then
		_runtime_receipt_matches "$target" "$target/bin/node" \
			"$artifact_digest" "$binary_digest" || return 1
		[[ -x "$target/bin/node"
			&& "$($target/bin/node --version 2>/dev/null)" == "v${INSTALLER_PROVENANCE[NODE_VERSION]}" ]] \
			|| return 1
		nvm alias default "${INSTALLER_PROVENANCE[NODE_VERSION]}" >/dev/null 2>&1 || return 1
		return 0
	fi
	mkdir -p -- "$parent" || return 1
	_make_private_directory stage \
		"$parent/.v${INSTALLER_PROVENANCE[NODE_VERSION]}.stage.XXXXXX" || return 1
	archive="$stage/artifact"
	extract="$stage/extract"
	mkdir -m 0700 "$extract" || { rm -rf -- "$stage"; return 1; }
	if ! download_sha256 "${INSTALLER_PROVENANCE[NODE_${artifact_arch}_URL]}" \
		"${INSTALLER_PROVENANCE[NODE_${artifact_arch}_SHA256]}" \
		"${INSTALLER_PROVENANCE[NODE_${artifact_arch}_MAX_BYTES]}" "$archive"; then
		rm -rf -- "$stage"
		return 1
	fi
	listing="$(tar -tJf "$archive")" || { rm -rf -- "$stage"; return 1; }
	[[ -n "$listing" ]] || { rm -rf -- "$stage"; return 1; }
	while IFS= read -r member; do
		_archive_member_is_safe "$member" "$archive_top" \
			|| { rm -rf -- "$stage"; return 1; }
	done <<<"$listing"
	tar -xJf "$archive" --no-same-owner --no-same-permissions -C "$extract" \
		|| { rm -rf -- "$stage"; return 1; }
	_tree_links_stay_inside "$extract/$archive_top" \
		|| { rm -rf -- "$stage"; return 1; }
	_tree_hardlinks_stay_inside "$extract/$archive_top" \
		|| { rm -rf -- "$stage"; return 1; }
	staged_binary="$extract/$archive_top/bin/node"
	[[ "$(sha256sum "$staged_binary" | awk '{ print $1 }')" == "$binary_digest" ]] \
		|| { rm -rf -- "$stage"; return 1; }
	[[ -d "$extract/$archive_top" && ! -L "$extract/$archive_top"
		&& -x "$staged_binary"
		&& "$($staged_binary --version 2>/dev/null)" \
			== "v${INSTALLER_PROVENANCE[NODE_VERSION]}" ]] \
		|| { rm -rf -- "$stage"; return 1; }
	_write_runtime_receipt "$extract/$archive_top" "$artifact_digest" "$binary_digest" \
		|| { rm -rf -- "$stage"; return 1; }
	_activate_directory_no_replace "$extract/$archive_top" "$target" \
		|| { rm -rf -- "$stage"; return 1; }
	_runtime_receipt_matches "$target" "$target/bin/node" \
		"$artifact_digest" "$binary_digest" || { rm -rf -- "$stage"; return 1; }
	[[ -x "$target/bin/node"
		&& "$($target/bin/node --version 2>/dev/null)" \
			== "v${INSTALLER_PROVENANCE[NODE_VERSION]}" ]] \
		|| { rm -rf -- "$stage"; return 1; }
	_tree_links_stay_inside "$target" || { rm -rf -- "$stage"; return 1; }
	_tree_hardlinks_stay_inside "$target" || { rm -rf -- "$stage"; return 1; }
	rm -rf -- "$stage"
	stage=""
	nvm alias default "${INSTALLER_PROVENANCE[NODE_VERSION]}" >/dev/null 2>&1
)

install_node() {
	_install_node || _record_installer_failure Node
}

# Kept as the call-site name used by the desktop-first ordering contract.
setup_node() {
	install_node
}

install_pnpm() {
	if require_reviewed_fedora_release \
		&& sudo dnf install -y --repo=fedora --repo=updates \
			--from-repo=fedora,updates pnpm >/dev/null; then
		return 0
	fi
	_record_installer_failure pnpm
}

_install_bun() (
	local artifact_arch archive_top target bin_link parent stage archive listing
	local staged_binary version_dir artifact_digest binary_digest
	stage=""
	trap '[[ -z "$stage" ]] || rm -rf -- "$stage"' EXIT
	trap 'exit 130' INT
	trap 'exit 143' TERM
	_set_artifact_arch || return 1
	case "$artifact_arch" in
		X86_64) archive_top=bun-linux-x64 ;;
		AARCH64) archive_top=bun-linux-aarch64 ;;
	esac
	version_dir="$HOME/.bun/versions/${INSTALLER_PROVENANCE[BUN_VERSION]}"
	target="$version_dir/bin/bun"
	bin_link="$HOME/.bun/bin/bun"
	artifact_digest="${INSTALLER_PROVENANCE[BUN_${artifact_arch}_SHA256]}"
	binary_digest="${INSTALLER_PROVENANCE[BUN_${artifact_arch}_BINARY_SHA256]}"
	if [[ -e "$version_dir" || -L "$version_dir" ]]; then
		_runtime_receipt_matches "$version_dir" "$target" \
			"$artifact_digest" "$binary_digest" || return 1
		[[ -x "$target"
			&& "$($target --version 2>/dev/null)" == "${INSTALLER_PROVENANCE[BUN_VERSION]}" ]] \
			|| return 1
		[[ -L "$bin_link" && "$(readlink -- "$bin_link")" == "$target" ]] \
			|| _atomic_symlink "$target" "$bin_link"
		return
	fi
	parent="$HOME/.bun/versions"
	mkdir -p -- "$parent" || return 1
	_make_private_directory stage \
		"$parent/.${INSTALLER_PROVENANCE[BUN_VERSION]}.stage.XXXXXX" || return 1
	archive="$stage/artifact"
	if ! download_sha256 "${INSTALLER_PROVENANCE[BUN_${artifact_arch}_URL]}" \
		"${INSTALLER_PROVENANCE[BUN_${artifact_arch}_SHA256]}" \
		"${INSTALLER_PROVENANCE[BUN_${artifact_arch}_MAX_BYTES]}" "$archive"; then
		rm -rf -- "$stage"
		return 1
	fi
	listing="$(unzip -Z1 "$archive")" || { rm -rf -- "$stage"; return 1; }
	[[ "$listing" == "$archive_top/"$'\n'"$archive_top/bun" ]] \
		|| { rm -rf -- "$stage"; return 1; }
	_bun_zip_entry_types_match "$archive" "$archive_top" \
		|| { rm -rf -- "$stage"; return 1; }
	while IFS= read -r member; do
		_archive_member_is_safe "$member" "$archive_top" \
			|| { rm -rf -- "$stage"; return 1; }
	done <<<"$listing"
	mkdir -m 0700 "$stage/extract" "$stage/version" "$stage/version/bin" \
		|| { rm -rf -- "$stage"; return 1; }
	unzip -q "$archive" -d "$stage/extract" || { rm -rf -- "$stage"; return 1; }
	staged_binary="$stage/extract/$archive_top/bun"
	[[ -f "$staged_binary" && ! -L "$staged_binary" && -x "$staged_binary"
		&& "$(sha256sum "$staged_binary" | awk '{ print $1 }')" == "$binary_digest"
		&& "$($staged_binary --version 2>/dev/null)" == "${INSTALLER_PROVENANCE[BUN_VERSION]}" ]] \
		|| { rm -rf -- "$stage"; return 1; }
	mv -- "$staged_binary" "$stage/version/bin/bun" \
		|| { rm -rf -- "$stage"; return 1; }
	_write_runtime_receipt "$stage/version" "$artifact_digest" "$binary_digest" \
		|| { rm -rf -- "$stage"; return 1; }
	_activate_directory_no_replace "$stage/version" "$version_dir" \
		|| { rm -rf -- "$stage"; return 1; }
	_runtime_receipt_matches "$version_dir" "$target" \
		"$artifact_digest" "$binary_digest" || { rm -rf -- "$stage"; return 1; }
	[[ -x "$target" && "$($target --version 2>/dev/null)" \
		== "${INSTALLER_PROVENANCE[BUN_VERSION]}" ]] \
		|| { rm -rf -- "$stage"; return 1; }
	rm -rf -- "$stage"
	stage=""
	_atomic_symlink "$target" "$bin_link"
)

install_bun() {
	_install_bun || _record_installer_failure Bun
}

_codex_version_matches() {
	local binary="$1" output version_pattern
	output="$($binary --version 2>/dev/null)" || return 1
	version_pattern="${INSTALLER_PROVENANCE[CODEX_VERSION]//./\\.}"
	[[ "$output" =~ (^|[^0-9])${version_pattern}([^0-9]|$) ]]
}

_install_codex() (
	local artifact_arch version_dir target bin_link parent expected_listing member
	local stage archive listing staged_binary artifact_digest binary_digest
	stage=""
	trap '[[ -z "$stage" ]] || rm -rf -- "$stage"' EXIT
	trap 'exit 130' INT
	trap 'exit 143' TERM
	_set_artifact_arch || return 1
	version_dir="$HOME/.local/lib/panama/codex/${INSTALLER_PROVENANCE[CODEX_VERSION]}"
	target="$version_dir/codex"
	bin_link="$HOME/.local/bin/codex"
	artifact_digest="${INSTALLER_PROVENANCE[CODEX_${artifact_arch}_SHA256]}"
	binary_digest="${INSTALLER_PROVENANCE[CODEX_${artifact_arch}_BINARY_SHA256]}"
	if [[ -e "$version_dir" || -L "$version_dir" ]]; then
		_runtime_receipt_matches "$version_dir" "$target" \
			"$artifact_digest" "$binary_digest" || return 1
		[[ -x "$target" ]] || return 1
		_codex_version_matches "$target" || return 1
		[[ -L "$bin_link" && "$(readlink -- "$bin_link")" == "$target" ]] \
			|| _atomic_symlink "$target" "$bin_link"
		return
	fi
	parent="$HOME/.local/lib/panama/codex"
	mkdir -p -- "$parent" || return 1
	_make_private_directory stage \
		"$parent/.${INSTALLER_PROVENANCE[CODEX_VERSION]}.stage.XXXXXX" || return 1
	archive="$stage/artifact"
	if ! download_sha256 "${INSTALLER_PROVENANCE[CODEX_${artifact_arch}_URL]}" \
		"${INSTALLER_PROVENANCE[CODEX_${artifact_arch}_SHA256]}" \
		"${INSTALLER_PROVENANCE[CODEX_${artifact_arch}_MAX_BYTES]}" "$archive"; then
		rm -rf -- "$stage"
		return 1
	fi
	listing="$(tar -tzf "$archive")" || { rm -rf -- "$stage"; return 1; }
	expected_listing=$'bin/\nbin/codex\nbin/codex-code-mode-host\ncodex-package.json\ncodex-path/\ncodex-path/rg\ncodex-resources/\ncodex-resources/bwrap\ncodex-resources/zsh/\ncodex-resources/zsh/bin/\ncodex-resources/zsh/bin/zsh'
	[[ "$listing" == "$expected_listing" ]] || { rm -rf -- "$stage"; return 1; }
	while IFS= read -r member; do
		_archive_path_is_safe "$member" || { rm -rf -- "$stage"; return 1; }
	done <<<"$listing"
	mkdir -m 0700 "$stage/extract" "$stage/version" \
		|| { rm -rf -- "$stage"; return 1; }
	tar -xzf "$archive" --no-same-owner --no-same-permissions -C "$stage/extract" \
		|| { rm -rf -- "$stage"; return 1; }
	_tree_links_stay_inside "$stage/extract" || { rm -rf -- "$stage"; return 1; }
	_tree_hardlinks_stay_inside "$stage/extract" || { rm -rf -- "$stage"; return 1; }
	staged_binary="$stage/extract/bin/codex"
	[[ -f "$staged_binary" && ! -L "$staged_binary" && -x "$staged_binary"
		&& "$(sha256sum "$staged_binary" | awk '{ print $1 }')" == "$binary_digest" ]] \
		|| { rm -rf -- "$stage"; return 1; }
	_codex_version_matches "$staged_binary" \
		|| { rm -rf -- "$stage"; return 1; }
	mv -- "$staged_binary" "$stage/version/codex" \
		|| { rm -rf -- "$stage"; return 1; }
	_write_runtime_receipt "$stage/version" "$artifact_digest" "$binary_digest" \
		|| { rm -rf -- "$stage"; return 1; }
	_activate_directory_no_replace "$stage/version" "$version_dir" \
		|| { rm -rf -- "$stage"; return 1; }
	_runtime_receipt_matches "$version_dir" "$target" \
		"$artifact_digest" "$binary_digest" || { rm -rf -- "$stage"; return 1; }
	_codex_version_matches "$target" || { rm -rf -- "$stage"; return 1; }
	rm -rf -- "$stage"
	stage=""
	_atomic_symlink "$target" "$bin_link"
)

install_codex() {
	_install_codex || _record_installer_failure Codex
}

_install_rustdesk() (
	local artifact_arch installed_version="" work rpm_path root_rpm="" status=0
	work=""
	cleanup_rustdesk() {
		[[ -z "$root_rpm" ]] || _remove_root_snapshot "$root_rpm" || true
		[[ -z "$work" ]] || rm -rf -- "$work"
	}
	trap cleanup_rustdesk EXIT
	trap 'exit 130' INT
	trap 'exit 143' TERM
	_set_artifact_arch || return 1
	if [[ "$artifact_arch" == AARCH64 ]]; then
		log "RustDesk ${INSTALLER_PROVENANCE[RUSTDESK_VERSION]} has no reviewed aarch64 RPM"
		return 1
	fi
	installed_version="$(rpm -q --queryformat '%{VERSION}' rustdesk 2>/dev/null)" || true
	if [[ "$installed_version" == "${INSTALLER_PROVENANCE[RUSTDESK_VERSION]}" ]]; then
		return 0
	fi
	_make_private_directory work "${TMPDIR:-/tmp}/panama-rustdesk.XXXXXX" || return 1
	rpm_path="$work/rustdesk.rpm"
	if ! download_sha256 "${INSTALLER_PROVENANCE[RUSTDESK_X86_64_URL]}" \
		"${INSTALLER_PROVENANCE[RUSTDESK_X86_64_SHA256]}" \
		"${INSTALLER_PROVENANCE[RUSTDESK_X86_64_MAX_BYTES]}" "$rpm_path"; then
		rm -rf -- "$work"
		return 1
	fi
	# RustDesk 1.4.9's reviewed RPM is unsigned. Its exact SHA-256 is the trust
	# assertion. Root rechecks a private snapshot against that reviewed digest,
	# and DNF receives only the snapshot rather than reopening user-owned bytes.
	if ! _stage_root_snapshot "$rpm_path" \
		"${INSTALLER_PROVENANCE[RUSTDESK_X86_64_SHA256]}" rustdesk.rpm root_rpm; then
		return 1
	fi
	sudo dnf install -y --repo=fedora --repo=updates \
		--setopt=localpkg_gpgcheck=0 "$root_rpm" >/dev/null || status=$?
	if _remove_root_snapshot "$root_rpm"; then
		root_rpm=""
	else
		status=1
	fi
	rm -rf -- "$work"
	work=""
	return "$status"
)

install_rustdesk() {
	_install_rustdesk || _record_installer_failure RustDesk
}

# --- What was stepped over ---------------------------------------------------
#
# Tolerating a failure is only better than aborting on it if somebody is told.
# The whole point of surviving a soft failure is that the rest gets installed
# anyway -- but a machine missing something should say so once, here, rather
# than be discovered a week later.
report_soft_failures() {
	if (( ${#softly_failed[@]} > 0 )); then
		log "Installed, but these were stepped over:"
		printf '         - %s\n' "${softly_failed[@]}"
		log "None of them stops the machine, but this run is not recorded as"
		log "complete, so the next 'panama update' tries them again."
		# A step that did not complete has not happened. Exiting non-zero is what
		# keeps ./install from stamping the packages hash over the gaps -- stamped,
		# they would never be retried (the hash-skip would say nothing changed).
		exit 1
	fi
}

# --- Reviewed third-party repositories -------------------------------------

_require_policy_value() {
	local name="$1" expected="$2"
	[[ "${INSTALLER_PROVENANCE[$name]:-}" == "$expected" ]] || {
		log "Installer provenance for $name does not match Panama's reviewed policy"
		return 1
	}
}

require_reviewed_fedora_release() {
	local current
	_require_policy_value FEDORA_RELEASE 44 || return 1
	current="$(rpm -E %fedora)" || return 1
	[[ "$current" == "${INSTALLER_PROVENANCE[FEDORA_RELEASE]}" ]] || {
		log "Fedora $current is not reviewed for third-party repositories; expected ${INSTALLER_PROVENANCE[FEDORA_RELEASE]}"
		return 1
	}
}

# RPM repository bootstrap packages and Flatpak descriptors are authenticated
# after download rather than by a SHA-256 pin. Keep their untrusted bytes in a
# private file, enforce the reviewed size limit, and publish the file only after
# curl has completed successfully.
_download_bounded() {
	local url="$1" max_bytes="$2" destination="$3" directory filename
	directory="$(dirname -- "$destination")"
	filename="$(basename -- "$destination")"
	(
		local part=""
		trap '[[ -z "$part" ]] || rm -f -- "$part"' EXIT
		trap 'exit 130' INT
		trap 'exit 143' TERM
		[[ "$max_bytes" =~ ^[1-9][0-9]*$ && -d "$directory" ]] || exit 1
		umask 077
		part="$(mktemp -u "$directory/.${filename}.part.XXXXXX")" || exit 1
		if ! (set -o noclobber; : >"$part") 2>/dev/null; then
			part=""
			exit 1
		fi
		curl --fail --location --connect-timeout 10 --max-time 600 \
			--max-filesize "$max_bytes" --output "$part" "$url" || exit 1
		[[ -f "$part" && "$(stat -c %s "$part")" -le "$max_bytes" ]] || exit 1
		mv -f -- "$part" "$destination"
	)
}

_stage_reviewed_key() {
	local source_key="$1" staged_key="$2" fingerprint_name="$3" expected="$4"
	local root_output_name="$5" digest_output_name="$6"
	local source_digest root_snapshot
	_require_policy_value "$fingerprint_name" "$expected" || return 1
	cp -- "$source_key" "$staged_key" || return 1
	chmod 0600 "$staged_key" || return 1
	_stable_file_digest "$staged_key" source_digest || return 1
	_stage_root_snapshot "$staged_key" "$source_digest" \
		"$(basename -- "$staged_key")" "$root_output_name" || return 1
	root_snapshot="${!root_output_name}"
	printf -v "$digest_output_name" '%s' "$source_digest"
	if ! _review_root_snapshots "$root_snapshot" -- key_fingerprint_matches \
		"$root_snapshot" "${INSTALLER_PROVENANCE[$fingerprint_name]}"; then
		if _remove_root_snapshot "$root_snapshot" >/dev/null 2>&1; then
			printf -v "$root_output_name" '%s' ''
		fi
		return 1
	fi
}

_stage_signed_rpm() {
	local package="$1" key="$2" fingerprint="$3" package_name="$4"
	local package_output_name="$5" key_output_name="$6"
	local package_digest key_digest staged_key root_package="" root_key=""
	staged_key="$(dirname -- "$package")/$(basename -- "$key")"
	cp -- "$key" "$staged_key" || return 1
	chmod 0600 "$staged_key" || return 1
	_stable_file_digest "$package" package_digest || return 1
	_stable_file_digest "$staged_key" key_digest || return 1
	_stage_root_snapshot "$package" "$package_digest" "$package_name" \
		"$package_output_name" || return 1
	root_package="${!package_output_name}"
	_stage_root_snapshot "$staged_key" "$key_digest" \
		"$(basename -- "$staged_key")" "$key_output_name" || {
		if _remove_root_snapshot "$root_package" >/dev/null 2>&1; then
			printf -v "$package_output_name" '%s' ''
		fi
		return 1
	}
	root_key="${!key_output_name}"
	if ! _review_root_snapshots "$root_package" "$root_key" -- \
		rpm_signature_matches "$root_package" "$root_key" "$fingerprint"; then
		if _remove_root_snapshot "$root_package" >/dev/null 2>&1; then
			printf -v "$package_output_name" '%s' ''
		fi
		if _remove_root_snapshot "$root_key" >/dev/null 2>&1; then
			printf -v "$key_output_name" '%s' ''
		fi
		return 1
	fi
}

# Use a fresh repository identity and command-line trust settings so an
# ambient file or DNF override for the installed convenience repo cannot
# redirect the package transaction. The key DNF consumes is the same reviewed
# root snapshot verified immediately before this call.
_install_bound_repo_packages() (
	local repo_id="$1" baseurl_name="$2" expected_baseurl="$3" source_key="$4"
	local fingerprint_name="$5" expected_fingerprint="$6" repo_gpgcheck="$7"
	local work="" staged_key root_key="" key_digest status=0
	local -a options=()
	shift 7
	while (( $# > 0 )) && [[ "$1" != -- ]]; do
		options+=("$1")
		shift
	done
	(( $# > 1 )) || return 1
	shift
	[[ "$repo_id" =~ ^panama-bound-[a-z0-9-]+$ \
		&& "$repo_gpgcheck" =~ ^[01]$ ]] || return 1
	_require_policy_value "$baseurl_name" "$expected_baseurl" || return 1
	trap '[[ -z "$root_key" ]] || _remove_root_snapshot "$root_key" || true; [[ -z "$work" ]] || rm -rf -- "$work"' EXIT
	trap 'exit 130' INT
	trap 'exit 143' TERM
	_make_private_directory work "${TMPDIR:-/tmp}/panama-repo-install.XXXXXX" \
		|| return 1
	staged_key="$work/$repo_id.asc"
	_stage_reviewed_key "$source_key" "$staged_key" "$fingerprint_name" \
		"$expected_fingerprint" root_key key_digest || return 1
	sudo dnf install -y \
		--repofrompath "$repo_id,${INSTALLER_PROVENANCE[$baseurl_name]}" \
		--repo="$repo_id" --repo=fedora --repo=updates --from-repo="$repo_id" \
		--setopt="$repo_id.gpgcheck=1" \
		--setopt="$repo_id.repo_gpgcheck=$repo_gpgcheck" \
		--setopt="$repo_id.gpgkey=file://$root_key" \
		"${options[@]}" "$@" || status=$?
	if _remove_root_snapshot "$root_key"; then
		root_key=""
	else
		status=1
	fi
	rm -rf -- "$work"
	work=""
	return "$status"
)

# Repository text is authored by this script. Hash the same argument stream
# independently of the user-owned pathname so a swap before root staging
# cannot redefine the bytes that privileged publication expects.
_write_private_text_digest() {
	local destination="$1" output_name="$2" digest
	shift 2
	printf '%s\n' "$@" > "$destination" || return 1
	digest="$(printf '%s\n' "$@" | sha256sum | awk '{ print $1 }')" || return 1
	[[ "$digest" =~ ^[0-9a-f]{64}$ ]] || return 1
	chmod 0600 "$destination" || return 1
	printf -v "$output_name" '%s' "$digest"
}

_ini_value() {
	local file="$1" wanted_section="$2" wanted_key="$3"
	local -a values=()
	mapfile -t values < <(awk -v wanted_section="$wanted_section" -v wanted_key="$wanted_key" '
		function trim(value) {
			sub(/^[[:space:]]+/, "", value)
			sub(/[[:space:]]+$/, "", value)
			return value
		}
		{
			sub(/\r$/, "")
			line = trim($0)
			if (line == "" || line ~ /^[#;]/) next
			if (line ~ /^\[[^]]+\]$/) {
				section = substr(line, 2, length(line) - 2)
				next
			}
			equals = index(line, "=")
			if (tolower(section) == tolower(wanted_section) && equals > 1) {
				key = trim(substr(line, 1, equals - 1))
				if (tolower(key) == tolower(wanted_key)) print trim(substr(line, equals + 1))
			}
		}
	' "$file")
	(( ${#values[@]} > 0 )) || return 1
	[[ ${#values[@]} -eq 1 && -n "${values[0]}" ]] || return 2
	printf '%s\n' "${values[0]}"
}

_ini_section_count() {
	local file="$1" wanted_section="$2"
	awk -v wanted_section="$wanted_section" '
		function trim(value) {
			sub(/^[[:space:]]+/, "", value)
			sub(/[[:space:]]+$/, "", value)
			return value
		}
		{
			sub(/\r$/, "")
			line = trim($0)
			if (line ~ /^\[[^]]+\]$/) {
				section = substr(line, 2, length(line) - 2)
				if (tolower(section) == tolower(wanted_section)) count++
			}
		}
		END { print count + 0 }
	' "$file"
}

_ini_key_occurrence_count() {
	local file="$1" wanted_section="$2" wanted_key="$3"
	awk -v wanted_section="$wanted_section" -v wanted_key="$wanted_key" '
		function trim(value) {
			sub(/^[[:space:]]+/, "", value)
			sub(/[[:space:]]+$/, "", value)
			return value
		}
		{
			sub(/\r$/, "")
			line = trim($0)
			if (line == "" || line ~ /^[#;]/) next
			if (line ~ /^\[[^]]+\]$/) {
				section = substr(line, 2, length(line) - 2)
				next
			}
			if (tolower(section) != tolower(wanted_section)) next
			equals = index(line, "=")
			if (equals > 0) {
				key = trim(substr(line, 1, equals - 1))
			} else {
				split(line, words, /[[:space:]]+/)
				key = words[1]
			}
			if (tolower(key) == tolower(wanted_key)) count++
		}
		END { print count + 0 }
	' "$file"
}

_restore_repository_file() {
	local existed="$1" backup="$2" mode="$3" destination="$4"
	if (( existed )); then
		sudo install -m "$mode" "$backup" "$destination"
	else
		sudo rm -f -- "$destination"
	fi
}

_root_backup_repository_file() {
	local source="$1" backup="$2" before after
	before="$(sudo sha256sum -- "$source" | awk '{ print $1 }')" || return 1
	[[ "$before" =~ ^[0-9a-f]{64}$ ]] || return 1
	sudo install -m 0600 "$source" "$backup" || return 1
	after="$(sudo sha256sum -- "$backup" | awk '{ print $1 }')" || return 1
	[[ "$before" == "$after" ]]
}

_finish_repository_transaction() {
	local original_status=$? rollback_status=0 cleanup_status=0
	# Once rollback starts, a repeated Ctrl-C/TERM must not interrupt restoration
	# between the two files. Ignored dispositions are inherited by the restore
	# commands, then disappear with this transactional subshell.
	trap '' INT TERM
	if (( mutation_started && ! transaction_committed )); then
		_restore_repository_file "$repo_existed" "$repo_backup" "$repo_mode" \
			"$repo_destination" || rollback_status=$?
		_restore_repository_file "$key_existed" "$key_backup" "$key_mode" \
			"$key_destination" || rollback_status=$?
	fi
	if (( rollback_status != 0 )); then
		log "Repository rollback failed; recovery evidence retained at $(dirname -- "$root_key") and $(dirname -- "$root_repo")"
		original_status="$TERRA_TRUST_FAILURE_STATUS"
	else
		[[ -z "$root_key" ]] || _remove_root_snapshot "$root_key" || cleanup_status=$?
		[[ -z "$root_repo" ]] || _remove_root_snapshot "$root_repo" || cleanup_status=$?
		(( cleanup_status == 0 )) || original_status=1
	fi
	trap - EXIT
	exit "$original_status"
}

# A key and its repository file form one trust root. If either activation
# write fails after touching its target, restore both prior files or return both
# targets to absence before reporting failure.
_publish_repository_pair() (
	local root_key="$1" key_destination="$2" staged_repo="$3" repo_destination="$4"
	local key_digest="$5" repo_digest="$6"
	local before_repo_hook="${7:-:}" after_repo_hook="${8:-:}"
	local root_repo="" backup_dir key_backup repo_backup actual_key_digest
	local key_mode=0644 repo_mode=0644
	local key_current repo_current
	local key_existed=0 repo_existed=0 status=0
	local mutation_started=0 transaction_committed=0
	trap _finish_repository_transaction EXIT
	trap 'exit 130' INT
	trap 'exit 143' TERM

	[[ "$key_destination" == /etc/* && "$repo_destination" == /etc/* \
		&& "$key_digest" =~ ^[0-9a-f]{64}$ \
		&& "$repo_digest" =~ ^[0-9a-f]{64}$ ]] || return 1
	_root_snapshot_directory_is_safe "$(dirname -- "$root_key")" || return 1
	actual_key_digest="$(sudo sha256sum -- "$root_key" | awk '{ print $1 }')" \
		|| return 1
	[[ "$actual_key_digest" == "$key_digest" ]] || return 1
	_stage_root_snapshot "$staged_repo" "$repo_digest" \
		"$(basename -- "$staged_repo")" root_repo || return 1
	key_current="$PANAMA_SYSTEM_ETC${key_destination#/etc}"
	repo_current="$PANAMA_SYSTEM_ETC${repo_destination#/etc}"
	[[ ! -L "$key_current" && ! -L "$repo_current" ]] || return 1
	backup_dir="$(dirname -- "$root_key")"
	key_backup="$backup_dir/prior-key"
	repo_backup="$backup_dir/prior-repo"
	if [[ -e "$key_current" ]]; then
		[[ -f "$key_current" ]] || return 1
		key_mode="$(stat -c %a "$key_current")" || return 1
		_root_backup_repository_file "$key_destination" "$key_backup" || return 1
		key_existed=1
	fi
	if [[ -e "$repo_current" ]]; then
		[[ -f "$repo_current" ]] || return 1
		repo_mode="$(stat -c %a "$repo_current")" || return 1
		_root_backup_repository_file "$repo_destination" "$repo_backup" || return 1
		repo_existed=1
	fi

	mutation_started=1
	sudo install -m 0644 "$root_key" "$key_destination" || status=$?
	if (( status == 0 )); then
		"$before_repo_hook" || status=$?
	fi
	if (( status == 0 )); then
		sudo install -m 0644 "$root_repo" "$repo_destination" || status=$?
	fi
	if (( status == 0 )); then
		"$after_repo_hook" || status=$?
	fi
	(( status == 0 )) || return "$status"
	transaction_committed=1
)

_effective_terra_key() {
	awk -v reviewed_baseurl="${INSTALLER_PROVENANCE[TERRA_BASEURL]}" '
		function reset_block() {
			delete values
			delete seen
			in_block = 0
			id = ""
			terra_like = 0
		}
		function finish_block( key) {
			if (!in_block || !terra_like) return
			if (seen["enabled"] != 1) {
				bad = 1
				return
			}
			if (values["enabled"] != "1") return
			enabled_count++
			if (id != "terra") bad = 1
			for (key in required) {
				if (seen[key] != 1) bad = 1
			}
			if (values["baseurl"] != reviewed_baseurl || values["metalink"] != "" \
				|| values["mirrorlist"] != "" || values["gpgcheck"] != "1" \
				|| values["pkg_gpgcheck"] != "1" || values["repo_gpgcheck"] != "1" \
				|| values["gpgkey"] != "file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama") bad = 1
			trusted_key = values["gpgkey"]
		}
		BEGIN {
			split("enabled baseurl metalink mirrorlist gpgcheck pkg_gpgcheck repo_gpgcheck gpgkey", fields)
			for (field_index in fields) required[fields[field_index]] = 1
			reset_block()
		}
		/^======== ".*" repository configuration: ========$/ {
			finish_block()
			reset_block()
			saw_nonempty = 1
			header_count++
			id = $0
			sub(/^======== "/, "", id)
			sub(/" repository configuration: ========$/, "", id)
			if (id == "") bad = 1
			terra_like = (tolower(id) ~ /^terra/)
			in_block = 1
			next
		}
		{
			if ($0 == "") next
			saw_nonempty = 1
			if (!in_block || $0 ~ /^========/) {
				bad = 1
				next
			}
			separator = index($0, " = ")
			if (separator > 0) {
				key = substr($0, 1, separator - 1)
				value = substr($0, separator + 3)
			} else if ($0 ~ /^[[:alnum:]_.-]+$/) {
				key = $0
				value = ""
			} else {
				bad = 1
				next
			}
			if (key !~ /^[[:alnum:]_.-]+$/) {
				bad = 1
				next
			}
			if (terra_like && key in required) {
				seen[key]++
				values[key] = value
			}
		}
		END {
			finish_block()
			if (saw_nonempty && header_count == 0) bad = 1
			if (bad || enabled_count > 1) exit 2
			if (enabled_count == 0) exit 1
			print trusted_key
		}
	'
}

# Status 0 is one trusted effective Terra identity, 1 is no enabled Terra
# identity, and 2 is an unsafe, duplicated, or unreadable effective state.
_terra_effective_status() {
	local dump gpgkey parse_status=0 local_key repo_file
	dump="$(LC_ALL=C dnf --quiet --no-plugins --dump-repo-config='*')" || return 2
	gpgkey="$(printf '%s\n' "$dump" | _effective_terra_key)" || parse_status=$?
	(( parse_status == 0 )) || return "$parse_status"
	[[ "$gpgkey" == 'file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama' ]] || return 2
	local_key="$PANAMA_SYSTEM_ETC/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama"
	repo_file="$PANAMA_SYSTEM_ETC/yum.repos.d/terra.repo"
	_root_owned_regular_file_is_safe "$repo_file" || return 2
	_root_owned_regular_file_is_safe "$local_key" || return 2
	key_fingerprint_matches "$PANAMA_PATH/setup/provenance/keys/terra44.asc" \
		"${INSTALLER_PROVENANCE[TERRA_FINGERPRINT]}" \
		&& key_fingerprint_matches "$local_key" \
			"${INSTALLER_PROVENANCE[TERRA_FINGERPRINT]}" \
		|| return 2
}

TERRA_TRUST_FAILURE_STATUS=78

preflight_terra_trust() {
	local status=0
	_require_policy_value TERRA_BASEURL 'https://repos.fyralabs.com/terra44' \
		|| return "$TERRA_TRUST_FAILURE_STATUS"
	_require_policy_value TERRA_FINGERPRINT AE09157A4DE88B497EA1D5D300CDAB43DE226D6F \
		|| return "$TERRA_TRUST_FAILURE_STATUS"
	_terra_effective_status || status=$?
	if (( status == 0 || status == 1 )); then
		return 0
	fi
	log "Effective Terra repository configuration is not trusted; refusing all package work"
	return "$TERRA_TRUST_FAILURE_STATUS"
}

# Status 0 is trusted, 1 is absent, and 2 is present but untrusted or malformed.
_flathub_remote_status() {
	local config section_count url gpg_verify summary_verify disabled disabled_status
	local alternate_key_count
	config="$PANAMA_SYSTEM_FLATPAK_REPO/config"
	[[ -e "$config" || -L "$config" ]] || return 1
	_root_owned_regular_file_is_safe "$config" || return 2
	section_count="$(_ini_section_count "$config" 'remote "flathub"')" || return 2
	(( section_count > 0 )) || return 1
	(( section_count == 1 )) || return 2
	url="$(_ini_value "$config" 'remote "flathub"' url)" || return 2
	gpg_verify="$(_ini_value "$config" 'remote "flathub"' gpg-verify)" || return 2
	summary_verify="$(_ini_value "$config" 'remote "flathub"' gpg-verify-summary)" || return 2
	[[ "$url" == 'https://dl.flathub.org/repo/' ]] || return 2
	case "${gpg_verify,,}" in true|yes|1) ;; *) return 2 ;; esac
	case "${summary_verify,,}" in true|yes|1) ;; *) return 2 ;; esac
	disabled_status=0
	disabled="$(_ini_value "$config" 'remote "flathub"' xa.disable)" || disabled_status=$?
	if (( disabled_status == 0 )); then
		case "${disabled,,}" in true|yes|1) return 2 ;; esac
	elif (( disabled_status != 1 )); then
		return 2
	fi
	alternate_key_count="$(_ini_key_occurrence_count "$config" 'remote "flathub"' gpgkeypath)" \
		|| return 2
	# The reviewed default keyring is the only permitted trust source. Empty,
	# duplicate, malformed, and nonempty alternate paths all fail closed.
	(( alternate_key_count == 0 )) || return 2
	_root_owned_regular_file_is_safe \
		"$PANAMA_SYSTEM_FLATPAK_REPO/flathub.trustedkeys.gpg" || return 2
	key_fingerprint_matches "$PANAMA_SYSTEM_FLATPAK_REPO/flathub.trustedkeys.gpg" \
		"${INSTALLER_PROVENANCE[FLATHUB_FINGERPRINT]}" || return 2
}

install_rpmfusion_repositories() (
	local work="" free_rpm nonfree_rpm
	local root_free="" root_nonfree="" root_free_key="" root_nonfree_key="" status=0
	cleanup_rpmfusion() {
		[[ -z "$root_free" ]] || _remove_root_snapshot "$root_free" || true
		[[ -z "$root_nonfree" ]] || _remove_root_snapshot "$root_nonfree" || true
		[[ -z "$root_free_key" ]] || _remove_root_snapshot "$root_free_key" || true
		[[ -z "$root_nonfree_key" ]] || _remove_root_snapshot "$root_nonfree_key" || true
		[[ -z "$work" ]] || rm -rf -- "$work"
	}
	trap cleanup_rpmfusion EXIT
	trap 'exit 130' INT
	trap 'exit 143' TERM
	require_reviewed_fedora_release || return 1
	_require_policy_value RPMFUSION_FREE_RELEASE_URL \
		'https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-44.noarch.rpm' || return 1
	_require_policy_value RPMFUSION_FREE_RELEASE_MAX_BYTES 4194304 || return 1
	_require_policy_value RPMFUSION_NONFREE_RELEASE_URL \
		'https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-44.noarch.rpm' || return 1
	_require_policy_value RPMFUSION_NONFREE_RELEASE_MAX_BYTES 4194304 || return 1
	_require_policy_value RPMFUSION_FREE_FINGERPRINT E9A491A3DE247814E7E067EAE06F8ECDD651FF2E || return 1
	_require_policy_value RPMFUSION_NONFREE_FINGERPRINT 79BDB88F9BBF73910FD4095B6A2AF96194843C65 || return 1

	_make_private_directory work "${TMPDIR:-/tmp}/panama-rpmfusion.XXXXXX" || return 1
	free_rpm="$work/rpmfusion-free-release.rpm"
	nonfree_rpm="$work/rpmfusion-nonfree-release.rpm"
	if ! _download_bounded "${INSTALLER_PROVENANCE[RPMFUSION_FREE_RELEASE_URL]}" \
		"${INSTALLER_PROVENANCE[RPMFUSION_FREE_RELEASE_MAX_BYTES]}" "$free_rpm"; then
		rm -rf -- "$work"
		work=""
		return 1
	fi
	_stage_signed_rpm "$free_rpm" \
		"$PANAMA_PATH/setup/provenance/keys/rpmfusion-free.asc" \
		"${INSTALLER_PROVENANCE[RPMFUSION_FREE_FINGERPRINT]}" \
		rpmfusion-free-release.rpm root_free root_free_key || return 1
	if ! _download_bounded "${INSTALLER_PROVENANCE[RPMFUSION_NONFREE_RELEASE_URL]}" \
		"${INSTALLER_PROVENANCE[RPMFUSION_NONFREE_RELEASE_MAX_BYTES]}" "$nonfree_rpm"; then
		return 1
	fi
	_stage_signed_rpm "$nonfree_rpm" \
		"$PANAMA_PATH/setup/provenance/keys/rpmfusion-nonfree.asc" \
		"${INSTALLER_PROVENANCE[RPMFUSION_NONFREE_FINGERPRINT]}" \
		rpmfusion-nonfree-release.rpm root_nonfree root_nonfree_key || return 1
	# DNF verifies local RPMs with the system RPM keyring. A fresh Fedora host
	# does not have the RPM Fusion keys until these release RPMs install, so
	# import the already fingerprint-verified root snapshots before asking DNF
	# to repeat the signature check.
	sudo rpm --import "$root_free_key" || status=$?
	if (( status == 0 )); then
		sudo rpm --import "$root_nonfree_key" || status=$?
	fi
	if (( status == 0 )); then
		sudo dnf install -y --repo=fedora --repo=updates --setopt=localpkg_gpgcheck=1 \
			"$root_free" "$root_nonfree" || status=$?
	fi
	if _remove_root_snapshot "$root_free"; then root_free=""; else status=1; fi
	if _remove_root_snapshot "$root_nonfree"; then root_nonfree=""; else status=1; fi
	if _remove_root_snapshot "$root_free_key"; then root_free_key=""; else status=1; fi
	if _remove_root_snapshot "$root_nonfree_key"; then root_nonfree_key=""; else status=1; fi
	rm -rf -- "$work"
	work=""
	return "$status"
)

_verify_reviewed_terra_repository() {
	local status=0
	_terra_effective_status || status=$?
	(( status == 0 ))
}

install_terra_repository() (
	local work="" root_key="" staged_key staged_repo key_digest repo_digest status effective_status=0
	trap '[[ -z "$root_key" ]] || _remove_root_snapshot "$root_key" || true; [[ -z "$work" ]] || rm -rf -- "$work"' EXIT
	trap 'exit 130' INT
	trap 'exit 143' TERM
	require_reviewed_fedora_release || return 1
	_require_policy_value TERRA_BASEURL 'https://repos.fyralabs.com/terra44' || return 1
	_require_policy_value TERRA_FINGERPRINT AE09157A4DE88B497EA1D5D300CDAB43DE226D6F || return 1
	_terra_effective_status || effective_status=$?
	if (( effective_status == 0 )); then
		log "Terra repository already configured and verified"
		return 0
	elif (( effective_status != 1 )); then
		log "Effective Terra repository configuration is not trusted"
		return "$TERRA_TRUST_FAILURE_STATUS"
	fi
	_make_private_directory work "${TMPDIR:-/tmp}/panama-terra.XXXXXX" || return 1
	staged_key="$work/terra44.asc"
	staged_repo="$work/terra.repo"
	if ! _stage_reviewed_key \
		"$PANAMA_PATH/setup/provenance/keys/terra44.asc" "$staged_key" \
		TERRA_FINGERPRINT AE09157A4DE88B497EA1D5D300CDAB43DE226D6F \
		root_key key_digest; then
		rm -rf -- "$work"
		return 1
	fi
	_write_private_text_digest "$staged_repo" repo_digest \
		'[terra]' \
		'name=Panama reviewed Terra 44' \
		"baseurl=${INSTALLER_PROVENANCE[TERRA_BASEURL]}" \
		'enabled=1' \
		'gpgcheck=1' \
		'repo_gpgcheck=1' \
		'gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama' || return 1
	status=0
	_publish_repository_pair \
		"$root_key" /etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama \
		"$staged_repo" /etc/yum.repos.d/terra.repo \
		"$key_digest" "$repo_digest" \
		: _verify_reviewed_terra_repository || status=$?
	rm -rf -- "$work"
	work=""
	(( status == 0 )) || return "$TERRA_TRUST_FAILURE_STATUS"
)

configure_hyprland_repository() (
    local work="" root_key="" staged_key staged_repo key_digest repo_digest status
    trap '[[ -z "$root_key" ]] || _remove_root_snapshot "$root_key" || true; [[ -z "$work" ]] || rm -rf -- "$work"' EXIT
    trap 'exit 130' INT
    trap 'exit 143' TERM
    require_reviewed_fedora_release || return 1
	_require_policy_value HYPRLAND_COPR_BASEURL \
		'https://download.copr.fedorainfracloud.org/results/lionheartp/Hyprland/fedora-$releasever-$basearch/' \
		|| return 1
	_make_private_directory work "${TMPDIR:-/tmp}/panama-hyprland.XXXXXX" || return 1
	staged_key="$work/hyprland-copr.asc"
	staged_repo="$work/panama-hyprland.repo"
	if ! _stage_reviewed_key \
		"$PANAMA_PATH/setup/provenance/keys/hyprland-copr.asc" "$staged_key" \
		HYPRLAND_COPR_FINGERPRINT 97E23476C89635135407C7D5E9BA41342C4B2995 \
		root_key key_digest; then
		rm -rf -- "$work"
		return 1
	fi
	_write_private_text_digest "$staged_repo" repo_digest \
		'[panama-hyprland]' \
		'name=Panama reviewed Hyprland COPR' \
		"baseurl=${INSTALLER_PROVENANCE[HYPRLAND_COPR_BASEURL]}" \
		'enabled=1' \
		'gpgcheck=1' \
		'repo_gpgcheck=0' \
		'gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-panama-hyprland' || return 1
	status=0
	_publish_repository_pair \
		"$root_key" /etc/pki/rpm-gpg/RPM-GPG-KEY-panama-hyprland \
		"$staged_repo" /etc/yum.repos.d/panama-hyprland.repo \
		"$key_digest" "$repo_digest" || status=$?
	rm -rf -- "$work"
	work=""
	return "$status"
)

ensure_flathub_remote() (
	local work descriptor encoded key_file url no_gpg_verify gpg_verify
	local alternate_key_count status remote_status no_gpg_status gpg_status
	local key_digest root_key=""
	work=""
	cleanup_flathub() {
		[[ -z "$root_key" ]] || _remove_root_snapshot "$root_key" || true
		[[ -z "$work" ]] || rm -rf -- "$work"
	}
	trap cleanup_flathub EXIT
	trap 'exit 130' INT
	trap 'exit 143' TERM
	require_reviewed_fedora_release || return 1
	_require_policy_value FLATHUB_DESCRIPTOR_URL 'https://flathub.org/repo/flathub.flatpakrepo' || return 1
	_require_policy_value FLATHUB_DESCRIPTOR_MAX_BYTES 1048576 || return 1
	_require_policy_value FLATHUB_FINGERPRINT 6E5C05D979C76DAF93C081354184DD4D907A7CAE || return 1
	remote_status=0
	_flathub_remote_status || remote_status=$?
	if (( remote_status == 0 )); then
		return 0
	elif (( remote_status != 1 )); then
		log "Existing Flathub remote does not match Panama's reviewed trust policy"
		return 1
	fi
	_make_private_directory work "${TMPDIR:-/tmp}/panama-flathub.XXXXXX" || return 1
	descriptor="$work/flathub.flatpakrepo"
	key_file="$work/flathub-key.asc"
	if ! _download_bounded "${INSTALLER_PROVENANCE[FLATHUB_DESCRIPTOR_URL]}" \
		"${INSTALLER_PROVENANCE[FLATHUB_DESCRIPTOR_MAX_BYTES]}" "$descriptor" \
		|| ! url="$(_ini_value "$descriptor" 'Flatpak Repo' Url)" \
		|| [[ "$url" != 'https://dl.flathub.org/repo/' ]] \
		|| ! encoded="$(_ini_value "$descriptor" 'Flatpak Repo' GPGKey)" \
		|| ! printf '%s' "$encoded" | base64 --decode > "$key_file"; then
		rm -rf -- "$work"
		return 1
	fi
	no_gpg_status=0
	no_gpg_verify="$(_ini_value "$descriptor" 'Flatpak Repo' NoGPGVerify)" \
		|| no_gpg_status=$?
	if (( no_gpg_status == 0 )); then
		case "${no_gpg_verify,,}" in true|yes|1) rm -rf -- "$work"; return 1 ;; esac
	elif (( no_gpg_status != 1 )); then
		rm -rf -- "$work"
		return 1
	fi
	gpg_status=0
	gpg_verify="$(_ini_value "$descriptor" 'Flatpak Repo' GPGVerify)" || gpg_status=$?
	if (( gpg_status == 0 )); then
		case "${gpg_verify,,}" in false|no|0) rm -rf -- "$work"; return 1 ;; esac
	elif (( gpg_status != 1 )); then
		rm -rf -- "$work"
		return 1
	fi
	alternate_key_count="$(_ini_key_occurrence_count "$descriptor" 'Flatpak Repo' GPGKeyPath)" \
		|| alternate_key_count=1
	if (( alternate_key_count != 0 )); then
		rm -rf -- "$work"
		return 1
	fi
	if ! _stable_file_digest "$key_file" key_digest \
		|| ! _stage_root_snapshot "$key_file" "$key_digest" flathub-key.asc root_key \
		|| ! _review_root_snapshots "$root_key" -- key_fingerprint_matches \
			"$root_key" "${INSTALLER_PROVENANCE[FLATHUB_FINGERPRINT]}"; then
		rm -rf -- "$work"
		work=""
		return 1
	fi
	status=0
	sudo flatpak remote-add --if-not-exists --gpg-import="$root_key" flathub "$url" \
		|| status=$?
	if (( status == 0 )); then
		_flathub_remote_status || status=$?
	fi
	if _remove_root_snapshot "$root_key"; then
		root_key=""
	else
		status=1
	fi
	rm -rf -- "$work"
	work=""
	return "$status"
)

_install_claude_code() (
	local work="" root_key="" staged_key staged_repo key_digest repo_digest status
	trap '[[ -z "$root_key" ]] || _remove_root_snapshot "$root_key" || true; [[ -z "$work" ]] || rm -rf -- "$work"' EXIT
	trap 'exit 130' INT
	trap 'exit 143' TERM
	if command -v claude >/dev/null 2>&1; then
		log "Claude Code already installed at \"$(command -v claude)\""
		return 0
	fi
	require_reviewed_fedora_release || return 1
	_require_policy_value CLAUDE_CODE_BASEURL 'https://downloads.claude.ai/claude-code/rpm/stable' || return 1
	_make_private_directory work "${TMPDIR:-/tmp}/panama-claude-code.XXXXXX" || return 1
	staged_key="$work/claude-code.asc"
	staged_repo="$work/claude-code.repo"
	if ! _stage_reviewed_key \
		"$PANAMA_PATH/setup/provenance/keys/claude-code.asc" "$staged_key" \
		CLAUDE_CODE_FINGERPRINT 31DDDE24DDFAB679F42D7BD2BAA929FF1A7ECACE \
		root_key key_digest; then
		rm -rf -- "$work"
		return 1
	fi
	_write_private_text_digest "$staged_repo" repo_digest \
		'[claude-code]' \
		'name=Claude Code' \
		"baseurl=${INSTALLER_PROVENANCE[CLAUDE_CODE_BASEURL]}" \
		'enabled=1' \
		'gpgcheck=1' \
		'repo_gpgcheck=1' \
		'gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-claude-code-panama' || return 1
	status=0
	_publish_repository_pair \
		"$root_key" /etc/pki/rpm-gpg/RPM-GPG-KEY-claude-code-panama \
		"$staged_repo" /etc/yum.repos.d/claude-code.repo \
		"$key_digest" "$repo_digest" || status=$?
	if (( status == 0 )); then
		_install_bound_repo_packages panama-bound-claude-code \
			CLAUDE_CODE_BASEURL 'https://downloads.claude.ai/claude-code/rpm/stable' \
			"$PANAMA_PATH/setup/provenance/keys/claude-code.asc" \
			CLAUDE_CODE_FINGERPRINT 31DDDE24DDFAB679F42D7BD2BAA929FF1A7ECACE \
			1 -- claude-code || status=$?
	fi
	rm -rf -- "$work"
	work=""
	return "$status"
)

install_claude_code() {
	local status=0
	_install_claude_code || status=$?
	(( status == 0 )) && return 0
	(( status != TERRA_TRUST_FAILURE_STATUS )) \
		|| return "$TERRA_TRUST_FAILURE_STATUS"
	_record_installer_failure "Claude Code"
}

_claude_desktop_manual() {
	log "Claude Desktop is optional; configure its reviewed local-key repository manually to install it"
}

install_claude_desktop_if_trusted() (
	local repo_file baseurl enabled gpgcheck repo_gpgcheck gpgkey local_key
	local work="" staged_key root_key="" key_digest status=0
	cleanup_claude_desktop() {
		[[ -z "$root_key" ]] || _remove_root_snapshot "$root_key" || true
		[[ -z "$work" ]] || rm -rf -- "$work"
	}
	trap cleanup_claude_desktop EXIT
	trap 'exit 130' INT
	trap 'exit 143' TERM
	require_reviewed_fedora_release || return 1
	_require_policy_value CLAUDE_DESKTOP_BASEURL \
		'https://patrickjaja.github.io/claude-desktop-extra/rpm/' || return 1
	_require_policy_value CLAUDE_DESKTOP_FINGERPRINT 825A7D15D78BABE45646D5DF382409F597908867 || return 1
	repo_file="$PANAMA_SYSTEM_ETC/yum.repos.d/claude-desktop.repo"
	local_key="$PANAMA_SYSTEM_ETC/pki/rpm-gpg/RPM-GPG-KEY-claude-desktop-panama"
	if ! _root_owned_regular_file_is_safe "$repo_file" \
		|| ! _root_owned_regular_file_is_safe "$local_key" \
		|| [[ "$(_ini_section_count "$repo_file" claude-desktop)" != 1 ]] \
		|| ! baseurl="$(_ini_value "$repo_file" claude-desktop baseurl)" \
		|| [[ "$baseurl" != "${INSTALLER_PROVENANCE[CLAUDE_DESKTOP_BASEURL]}" ]] \
		|| ! enabled="$(_ini_value "$repo_file" claude-desktop enabled)" \
		|| [[ "$enabled" != 1 ]] \
		|| ! gpgcheck="$(_ini_value "$repo_file" claude-desktop gpgcheck)" \
		|| [[ "$gpgcheck" != 1 ]] \
		|| ! repo_gpgcheck="$(_ini_value "$repo_file" claude-desktop repo_gpgcheck)" \
		|| [[ "$repo_gpgcheck" != 1 ]] \
		|| ! gpgkey="$(_ini_value "$repo_file" claude-desktop gpgkey)" \
		|| [[ "$gpgkey" != 'file:///etc/pki/rpm-gpg/RPM-GPG-KEY-claude-desktop-panama' ]] \
		|| [[ "$(_ini_key_occurrence_count "$repo_file" claude-desktop metalink)" != 0 ]] \
		|| [[ "$(_ini_key_occurrence_count "$repo_file" claude-desktop mirrorlist)" != 0 ]] \
		|| ! key_fingerprint_matches "$local_key" \
			"${INSTALLER_PROVENANCE[CLAUDE_DESKTOP_FINGERPRINT]}"; then
		_claude_desktop_manual
		return 0
	fi
	_make_private_directory work "${TMPDIR:-/tmp}/panama-claude-desktop.XXXXXX" \
		|| return 1
	staged_key="$work/claude-desktop.asc"
	_stage_reviewed_key \
		"$PANAMA_PATH/setup/provenance/keys/claude-desktop.asc" "$staged_key" \
		CLAUDE_DESKTOP_FINGERPRINT 825A7D15D78BABE45646D5DF382409F597908867 \
		root_key key_digest || return 1
	sudo dnf install -y \
		--repofrompath "panama-claude-desktop,${INSTALLER_PROVENANCE[CLAUDE_DESKTOP_BASEURL]}" \
		--repo=panama-claude-desktop --repo=fedora --repo=updates \
		--from-repo=panama-claude-desktop \
		--setopt=panama-claude-desktop.gpgcheck=1 \
		--setopt=panama-claude-desktop.repo_gpgcheck=1 \
		--setopt="panama-claude-desktop.gpgkey=file://$root_key" \
		claude-desktop-extra || status=$?
	if _remove_root_snapshot "$root_key"; then
		root_key=""
	else
		status=1
	fi
	rm -rf -- "$work"
	work=""
	return "$status"
)

# Agent tools are optional unless repository recovery itself becomes
# indeterminate. Ordinary failures are recorded by each wrapper and allow the
# next tool; status 78 stops before any later downloader or package solver.
install_optional_agent_tools() {
	local claude_status=0
	setup_node || true
	install_pnpm || true
	install_bun || true
	install_claude_code || claude_status=$?
	(( claude_status != TERRA_TRUST_FAILURE_STATUS )) \
		|| return "$TERRA_TRUST_FAILURE_STATUS"
	install_codex || true
}

# Install a mixed desktop list without letting a third-party repository shadow
# an unrelated package. Terra and Cisco names are kept in publisher-specific
# transactions; everything else can resolve only from Fedora and RPM Fusion.
install_desktop_package_file() {
	local file="${1:-$PANAMA_PATH/setup/packages/desktop-packages}" package
	local openh264_repo_file="$PANAMA_SYSTEM_ETC/yum.repos.d/fedora-cisco-openh264.repo"
	local -a general_packages=() terra_packages=() openh264_packages=()
	local -a GENERAL_REPO_ARGS=("${RPMFUSION_REPO_ARGS[@]}")
	if [[ ! -f "$file" ]]; then
		log "Package list was not in specified path: $file"
		return 0
	fi
	for package in $(packages_in "$file"); do
		case "$package" in
			mozilla-openh264)
				openh264_packages+=("$package")
				;;
			cascadiamono-nerd-fonts|espanso-wayland|firamono-nerd-fonts|ghostty|\
			jetbrainsmono-nerd-fonts|nautilus-open-any-terminal|victormono-nerd-fonts)
				terra_packages+=("$package")
				;;
			*) general_packages+=("$package") ;;
		esac
	done
	log "Installing Desktop Packages"
	echo -e "Includes the following packages:"
	echo -e "$(<"$file")"
	if [[ -f "$openh264_repo_file" && ! -L "$openh264_repo_file" ]]; then
		GENERAL_REPO_ARGS+=(--repo=fedora-cisco-openh264)
	fi
	if (( ${#general_packages[@]} > 0 )); then
		sudo dnf install -y "${GENERAL_REPO_ARGS[@]}" \
			--from-repo=fedora,updates --skip-unavailable \
			"${general_packages[@]}" > /dev/null
	fi
	if (( ${#terra_packages[@]} > 0 )); then
		_install_bound_repo_packages panama-bound-terra \
			TERRA_BASEURL 'https://repos.fyralabs.com/terra44' \
			"$PANAMA_PATH/setup/provenance/keys/terra44.asc" \
			TERRA_FINGERPRINT AE09157A4DE88B497EA1D5D300CDAB43DE226D6F \
			1 --skip-unavailable -- "${terra_packages[@]}" > /dev/null
	fi
	if (( ${#openh264_packages[@]} > 0 )); then
		if [[ -f "$openh264_repo_file" && ! -L "$openh264_repo_file" ]]; then
			sudo dnf install -y "${BASE_REPO_ARGS[@]}" \
				--repo=fedora-cisco-openh264 \
				--from-repo=fedora-cisco-openh264 --skip-unavailable \
				"${openh264_packages[@]}" > /dev/null
		else
			log "WARNING: Fedora Cisco OpenH264 repository is unavailable; skipping ${openh264_packages[*]}"
		fi
	fi
	report_missing "$file"
	log "Desktop packages installed!"
}

# The Hyprland list intentionally mixes Fedora/RPM Fusion tools with the
# reviewed COPR and Terra. Bind every known publisher-only package to its own
# repository so neither third party can replace a base package with the same
# name.
install_hyprland_package_file() {
	local file="${1:-$PANAMA_PATH/setup/packages/hyprland-packages}" package
	local -a general_packages=() copr_packages=() terra_packages=()
	if [[ ! -f "$file" ]]; then
		log "Package list was not in specified path: $file"
		return 0
	fi
	for package in $(packages_in "$file"); do
		case "$package" in
			gpu-screen-recorder|grimblast|hypridle|hyprland|hyprland-guiutils|\
			hyprland-uwsm|hyprlock|hyprpaper|hyprpicker|hyprpolkitagent|\
			hyprpwcenter|hyprshutdown|hyprsunset|hyprsysteminfo|quickshell|uwsm|\
			xdg-desktop-portal-hyprland)
				copr_packages+=("$package")
				;;
			helium-browser-bin|mpvpaper|satty|vicinae)
				terra_packages+=("$package")
				;;
			*) general_packages+=("$package") ;;
		esac
	done
	log "Installing Hyprland desktop packages"
	echo -e "Includes the following packages:"
	echo -e "$(<"$file")"
	if (( ${#general_packages[@]} > 0 )); then
		sudo dnf install -y "${RPMFUSION_REPO_ARGS[@]}" \
			--from-repo=fedora,updates \
			--setopt=install_weak_deps=False "${general_packages[@]}" > /dev/null
	fi
	if (( ${#copr_packages[@]} > 0 )); then
		_install_bound_repo_packages panama-bound-hyprland \
			HYPRLAND_COPR_BASEURL \
			'https://download.copr.fedorainfracloud.org/results/lionheartp/Hyprland/fedora-$releasever-$basearch/' \
			"$PANAMA_PATH/setup/provenance/keys/hyprland-copr.asc" \
			HYPRLAND_COPR_FINGERPRINT 97E23476C89635135407C7D5E9BA41342C4B2995 \
			0 --setopt=install_weak_deps=False -- "${copr_packages[@]}" > /dev/null
	fi
	if (( ${#terra_packages[@]} > 0 )); then
		_install_bound_repo_packages panama-bound-terra \
			TERRA_BASEURL 'https://repos.fyralabs.com/terra44' \
			"$PANAMA_PATH/setup/provenance/keys/terra44.asc" \
			TERRA_FINGERPRINT AE09157A4DE88B497EA1D5D300CDAB43DE226D6F \
			1 --setopt=install_weak_deps=False -- "${terra_packages[@]}" > /dev/null
	fi
	report_missing "$file"
	log "Hyprland packages installed!"
}

# --- The server path ---------------------------------------------------------
#
# Everything a server runs is above this line plus the lists it installs. No
# RPM Fusion, no Terra, no COPR, no multimedia, no flatpaks: those exist for a
# desktop, and every one of them is a network dependency and a failure mode a
# headless machine has no reason to carry.
if [[ "${1:-}" == --trust-preflight ]]; then
	if preflight_terra_trust; then
		exit 0
	else
		exit $?
	fi
fi

# Repeat the enclosing installer's early preflight at the package boundary so
# a repository change made after startup cannot reach this stage's first DNF.
if ! preflight_terra_trust; then
	exit "$TERRA_TRUST_FAILURE_STATUS"
fi

if [[ "$ROLE" == server ]]; then
	echo -e "\n--- Installing packages (server) ---"
	log "Updating all packages. This may take a while"
		sudo dnf update -y "${BASE_REPO_ARGS[@]}" --refresh > /dev/null
	install_list core-packages "Core"
	install_list server-packages "Server"
	set +e
	agent_tools_status=0
	install_optional_agent_tools || agent_tools_status=$?
	set -e
	(( agent_tools_status != TERRA_TRUST_FAILURE_STATUS )) \
		|| exit "$TERRA_TRUST_FAILURE_STATUS"
	report_soft_failures
	exit 0
fi

echo -e "\n--- Installing Repositories ---"
log "Installing RPM Fusion Free and Nonfree Repositories"
install_rpmfusion_repositories > /dev/null
log "Enabling Fedora Cisco OpenH264 Repository"
# soft: this repo does not exist on every spin, and its absence must not cost
# the desktop -- the ordering rule at soft()'s definition applies to the
# repository extras just as much as to the codec swaps below.
soft "enabling the openh264 repository" sudo dnf config-manager setopt fedora-cisco-openh264.enabled=1
log "Installing RPM Fusion AppStream Metadata"
soft "the core group update" sudo dnf update @core -y "${RPMFUSION_REPO_ARGS[@]}"
soft "the RPM Fusion appstream metadata" sudo dnf install -y \
	"${RPMFUSION_REPO_ARGS[@]}" \
	--from-repo=rpmfusion-free,rpmfusion-free-updates,rpmfusion-nonfree,rpmfusion-nonfree-updates \
	rpmfusion-\*-appstream-data
# Panama publishes Terra's reviewed key and repository file directly as one
# transaction. The terra-release RPM only carries that repository file, while
# adding separate RPM database state that cannot be rolled back with the pair.
log "Installing Terra Repository"
install_terra_repository > /dev/null
PACKAGE_REPO_ARGS=(
	"${RPMFUSION_REPO_ARGS[@]}" --from-repo="$RPMFUSION_FROM_REPOS"
)

echo -e "\n--- Installing relevant packages ---"
log "Updating all packages. This may take a while"
sudo dnf update -y "${RPMFUSION_REPO_ARGS[@]}" --refresh > /dev/null

# --- Install the shared core, then the desktop-only lists ---
# --skip-unavailable throughout (inside install_list): dnf5 refuses a whole
# transaction over one missing name, so a single rotted entry used to cost
# every package in a list -- and the desktop below never installed. The
# skipped names are reported afterwards rather than silently dropped.
install_list core-packages "Core"
install_list initial-packages "Initial"
install_desktop_package_file

# --- Install the Hyprland desktop ---
#
# Directly after desktop-packages and deliberately before anything optional.
# The reviewed local repository below supplies these packages. This is the one
# thing on the list that Panama is; a machine that gets only this far is a
# machine you can log into, and every step below it is a convenience.
#
# Most of these live in the lionheartp/Hyprland COPR rather than Fedora proper.
HYPR_FILE="$PANAMA_PATH/setup/packages/hyprland-packages"
if [[ -f "$HYPR_FILE" ]]; then
	log "Configuring the reviewed Hyprland repository"
	configure_hyprland_repository > /dev/null
	install_hyprland_package_file "$HYPR_FILE"
else
	log "Package list was not in specified path: $HYPR_FILE"
fi

# Said out loud, because the failure this guards against was silent. The stage
# used to die somewhere above this point and report one red line among twenty
# minutes of scrollback, and the machine looked installed until you tried to log
# into it.
if rpm -q hyprland >/dev/null 2>&1; then
	log "Hyprland $(rpm -q --queryformat '%{VERSION}' hyprland) is installed."
else
	log "Hyprland is NOT installed. Nothing below this point will give you a desktop."
	exit 1
fi

# --- Codecs and multimedia ---------------------------------------------------
#
# Below the desktop and every one of them non-fatal, because none is a
# dependency of it and each can fail for reasons that have nothing to do with
# this repository -- a swap whose source package this spin never shipped, a
# group renamed upstream between Fedora releases.
#
# A trailing `&& sync` on the group update previously meant a failure was exempt
# from set -e as well (bash does not apply -e to the left of a && list), so it
# went unreported rather than being deliberately tolerated. It is deliberate now.

log "Updating core, multimedia, and sound-and-video groups"
soft "the multimedia group update" \
    sudo dnf4 groupupdate -y "${RPMFUSION_REPO_ARGS[@]}" \
	'core' 'multimedia' 'sound-and-video' \
    --setop='install_weak_deps=False' \
    --exclude='PackageKit-gstreamer-plugin' \
    --allowerasing
sync
log "Swapping ffmpeg-free for ffmpeg"
soft "the ffmpeg swap" sudo dnf swap -y 'ffmpeg-free' 'ffmpeg' \
	"${RPMFUSION_REPO_ARGS[@]}" --allowerasing
log "Swapping mesa-va-drivers for mesa-va-drivers-freeworld"
soft "the mesa driver swap" sudo dnf swap -y mesa-va-drivers mesa-va-drivers-freeworld \
	"${RPMFUSION_REPO_ARGS[@]}"
log "Upgrading Multimedia group with optional packages"
soft "the optional Multimedia upgrade" sudo dnf4 group upgrade -y \
	"${RPMFUSION_REPO_ARGS[@]}" --with-optional Multimedia
log "Installing GStreamer plugins (bad, good, base)"
soft "the GStreamer plugins" \
    sudo dnf install -y "${RPMFUSION_REPO_ARGS[@]}" \
	gstreamer1-plugins-{bad-\*,good-\*,base} \
    --exclude=gstreamer1-plugins-bad-free-devel

# --- Install Development Packages needed for Neovim ---
DEV_FILE="$PANAMA_PATH/setup/packages/development-packages"
if [[ -f "$DEV_FILE" ]]; then
	DEV_PACKAGES=$(packages_in "$DEV_FILE")
	log "Installing Development Packages. Mostly for Neovim."
  echo -e "Includes the following packages:"
  echo -e "$(<"$DEV_FILE")"
  soft "the development packages" sudo dnf install -y \
	  "${PACKAGE_REPO_ARGS[@]}" $DEV_PACKAGES
	log "Development packages installed!"
else
	log "Package list was not in specified path: $DEV_FILE"
fi

set +e
setup_node
install_pnpm
install_bun
agent_tools_status=0
install_claude_code
agent_tools_status=$?
if (( agent_tools_status == TERRA_TRUST_FAILURE_STATUS )); then
	set -e
	exit "$TERRA_TRUST_FAILURE_STATUS"
fi
install_codex
set -e

# Claude Desktop remains optional. Panama never downloads its community setup
# script; only a repository an operator has already configured with the exact
# reviewed local key is eligible for installation.
if ! install_claude_desktop_if_trusted; then
	log "Claude Desktop install failed; skipping"
	softly_failed+=("Claude Desktop")
fi

# The RPM ships rustdesk.service already enabled, which is what provides
# unattended access; Panama deliberately does not start it a second time.
install_rustdesk || true

# --- Install Flatpak Packages ---
FLATPAK_FILE="$PANAMA_PATH/setup/packages/flatpak-packages"
if [[ -f "$FLATPAK_FILE" ]]; then
	FLATPAK_PACKAGES=$(packages_in "$FLATPAK_FILE")
	log "Adding Flathub remote"
	if ensure_flathub_remote; then
		log "Installing Flatpak Packages"
		echo -e "Includes the following packages:"
		echo -e "$(<"$FLATPAK_FILE")"
		# One ID renamed on Flathub must not cost the rest of the run; the desktop
		# is already installed by this point and none of these is part of it.
		soft "some Flatpak packages" sudo flatpak install -y flathub $FLATPAK_PACKAGES
		log "Flatpak packages installed!"
	else
		log "Flathub trust verification failed; Flatpak packages were not installed"
		softly_failed+=("Flathub")
	fi
else
	log "Package list was not in specified path: $FLATPAK_FILE"
fi

# --- Install the extras that were chosen ------------------------------------
#
# Everything above is what every Panama machine gets. This is what one machine
# asked for: the interview offers the categories in setup/packages/extras/ as a
# checklist and records the chosen names, so a work laptop does not acquire
# emulators and a desktop does not skip Steam.
#
# Absent means none. That is what makes this stage safe to re-run by hand while
# repairing one piece of a machine -- and it means a category is installed only
# by an explicit answer, never by a default that drifted.
#
# A category mixes both package managers, because the applications do: some are
# in Fedora or RPM Fusion and some publish only a flatpak. A bare line is a dnf
# package and a `flatpak:` line is a Flathub ID, so one file per category holds
# the whole answer rather than splitting each category across two.
#
# Reading the file is setup/lib/extras-catalog's job, not this function's, because
# `panama apps` offers the same catalog from the other side. Two parsers would
# eventually disagree about what a category contains, and the one that disagreed
# quietly would be this one -- it runs unattended.
#
# Neither install is fatal. A category is a set of applications somebody wanted,
# not a dependency of the desktop, and losing the rest of the run because one of
# them was renamed upstream would be the wrong trade.
install_extra_category() {
	local file="$1" name
	name="$(basename "$file")"

	local dnf_packages flatpak_ids
	# sed rather than grep -v: most categories are flatpak-only, and grep exits 1
	# when it selects nothing, which set -e above turns into a dead stage.
	dnf_packages=$(catalog_all_targets "$file" | sed '/^flatpak:/d' | tr "\n" " ")
	flatpak_ids=$(catalog_all_targets "$file" | sed -n 's/^flatpak://p' | tr "\n" " ")

	if [[ -n "${dnf_packages// /}" ]]; then
		log "Installing $name: $dnf_packages"
		sudo dnf install -y "${PACKAGE_REPO_ARGS[@]}" $dnf_packages \
			> /dev/null || { log "Some $name packages did not install"; softly_failed+=("$name packages"); }
	fi
	if [[ -n "${flatpak_ids// /}" ]]; then
		log "Installing $name flatpaks: $flatpak_ids"
		if ensure_flathub_remote; then
			sudo flatpak install -y flathub $flatpak_ids > /dev/null \
				|| { log "Some $name flatpaks did not install"; softly_failed+=("$name flatpaks"); }
		else
			log "Flathub trust verification failed; $name flatpaks were not installed"
			softly_failed+=("$name flatpaks")
		fi
	fi
}

EXTRAS_DIR="$PANAMA_PATH/setup/packages/extras"
for extra in ${PANAMA_EXTRAS:-}; do
	if [[ -f "$EXTRAS_DIR/$extra" ]]; then
		install_extra_category "$EXTRAS_DIR/$extra"
	else
		log "No such extras category: $extra"
	fi
done

report_soft_failures
