# Trusted installation inputs implementation plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Ensure every automatic executable input is publisher-signed or pinned by a reviewed SHA-256 before Panama executes or installs it. **Architecture:** Add four small provenance helpers plus declarative reviewed pins. Keep vendor-specific decisions in `install-packages`, drive them through one hermetic public contract, and preserve existing installations when verification fails. Finish with a commit-pinned, digest-checked Panama bootstrap. **Tech Stack:** Bash 5, GnuPG, rpmkeys with a temporary database, SHA-256, DNF5/Flatpak/Git command adapters, Panama contract runner. **Spec:** `docs/superpowers/specs/2026-08-27-secure-bootstrap-privileged-installation-design.md` ## Global constraints - Never execute fetched shell, install an unverified RPM, or accept a moving `latest` response during automatic setup. - Download without sudo into a private checked temporary directory. Verify before any sudo, extraction, execution, or target replacement. - Preserve a known-good installed version on every verification/download failure. - Use exact complete fingerprints and reviewed per-architecture SHA-256 values from the approved spec. - Use `curl --connect-timeout 10 --max-time 600`; enforce each configured maximum byte count before verification. - Parse `setup/provenance/installers.conf` as data. Do not `source`, `eval`, or shell-expand it. - Claude Desktop repository setup is optional and never automatic. - No task may mutate the host package database, repository configuration, Flatpak remotes, or live installed tools. - The Terra command gets at most one disposable Fedora 44 container smoke test with no host mounts, credentials, services, or production state. - Package 3 owns authenticated `panama update`; Package 5 owns mutable source-app and Neovim inputs. - Preserve `/home/gib/.local/share/Panama/config/bash/.bashrc` outside this worktree. ## File map - `setup/lib/artifact-provenance`: fingerprint, digest-download, detached-signature, and temporary-RPM-keyring helpers. - `setup/provenance/installers.conf`: strict reviewed versions, URLs, SHA-256 values, fingerprints, and maximum sizes. - `setup/provenance/keys/*`: reviewed ASCII-armored public keys. - `setup/provenance/README.md`: source, retrieval date, verification command, and rotation notes. - `tests/setup/package-provenance-contract`: real cryptographic fixture plus stateful curl/sudo/DNF/Flatpak/rpm command adapters. - `tests/setup/fixtures/provenance/*`: test-only GPG key, tiny signed manifest, good/tampered artifacts, and trusted/untrusted repo data. - `setup/scripts/install-packages`: vendor-specific verified repository/artifact flows. - `install`: include provenance and installer behavior in the package-stage hash. - `setup/scripts/link-vicinae-scripts`: use `npm ci` against the tracked lock. - `boot`, `README.md`, `tests/setup/boot-contract`, `tests/setup/readme-contract`: verified initial Panama revision and boot digest. - `tests/contracts.manifest`: one new hermetic contract. --- ### Task 1: Build and prove the provenance helpers **Files:** - Create: `setup/lib/artifact-provenance` - Create: `setup/provenance/installers.conf` - Create: `setup/provenance/keys/terra44.asc` - Create: `setup/provenance/keys/claude-code.asc` - Create: `setup/provenance/keys/bun.asc` - Create: `setup/provenance/keys/rpmfusion-free.asc` - Create: `setup/provenance/keys/rpmfusion-nonfree.asc` - Create: `setup/provenance/keys/hyprland-copr.asc` - Create: `setup/provenance/keys/flathub.asc` - Create: `setup/provenance/keys/claude-desktop.asc` - Create: `setup/provenance/README.md` - Create: `tests/setup/package-provenance-contract` - Create: `tests/setup/fixtures/provenance/` - Modify: `tests/contracts.manifest` **Interfaces:** - Consumes: `curl`, `gpg`, `sha256sum`, `rpmkeys`, `stat`, and strict `NAME=value` provenance data. - Produces: `load_installer_provenance FILE`, `key_fingerprint_matches FILE EXPECTED`, `download_sha256 URL EXPECTED MAX_BYTES DEST`, `verify_detached_signature KEY SIGNATURE CONTENT`, and `rpm_signature_matches PACKAGE KEY EXPECTED`. - [ ] **Step 1: Create cryptographic fixtures and write failing helper cases** Generate a test-only key in a temporary `GNUPGHOME`, export its public key, sign a four-line `SHASUMS256.txt`, and commit only the public key, content, detached signature, a good tiny artifact, and a one-byte-tampered artifact. The private key must never enter the repository; the contract does not need it after fixture creation. Write contract cases that source only `setup/lib/artifact-provenance` and assert: ```text known fingerprint -> 0 wrong fingerprint -> nonzero valid detached signature -> 0 wrong content or signature -> nonzero matching digest/size -> atomic destination created wrong digest, oversized body, interrupted curl -> destination absent or original bytes preserved valid RPM signed by fixture key -> 0 through a temporary rpmdb unsigned/wrong-key RPM -> nonzero and host rpmdb untouched ``` Add provenance-parser cases for unknown key, duplicate key, missing required key, whitespace around the name, shell expansion text, and unsupported architecture. - [ ] **Step 2: Run the new contract and confirm the missing-helper failure** ```bash bash -n tests/setup/package-provenance-contract tests/setup/package-provenance-contract ``` Expected: nonzero because the helper/config do not exist. - [ ] **Step 3: Implement exact helpers** Use these signatures and behaviors: ```bash key_fingerprint_matches() { local file="$1" expected="$2" actual actual="$(gpg --batch --with-colons --import-options show-only --import "$file" 2>/dev/null \ | awk -F: '$1 == "fpr" { print $10; exit }')" [[ "$actual" == "$expected" ]] } verify_detached_signature() { local key="$1" signature="$2" content="$3" home home="$(mktemp -d)" || return 1 chmod 700 "$home" GNUPGHOME="$home" gpg --batch --quiet --import "$key" >/dev/null 2>&1 \ && GNUPGHOME="$home" gpg --batch --verify "$signature" "$content" >/dev/null 2>&1 local status=$? rm -rf -- "$home" return "$status" } ``` `download_sha256` downloads to `DEST.part`, passes `--max-filesize MAX_BYTES`, verifies `stat -c %s <= MAX_BYTES`, compares a lowercase 64-hex digest, then `mv -f` atomically. Its EXIT/INT/TERM cleanup removes only the checked `.part` path. The installer may define one private `download_bounded URL MAX_BYTES DEST` wrapper for publisher-signed RPMs whose trust assertion is the later RPM signature rather than a reviewed digest. It uses the same curl timeouts, `.part` cleanup, post-download size check, and atomic rename as `download_sha256`; it does not execute or install the result before `rpm_signature_matches` succeeds. `rpm_signature_matches` creates a private temporary rpmdb, imports only `KEY`, verifies the complete expected primary fingerprint before import, and requires `rpmkeys --dbpath DB --checksig PACKAGE` success with an OpenPGP signature line. It never imports into the host keyring. `load_installer_provenance` reads with `IFS='=' read -r name value`, accepts only an explicit name allowlist, rejects duplicate/empty values and any line without exactly one `=`, and exports nothing. Store values in one associative array named `INSTALLER_PROVENANCE`. - [ ] **Step 4: Add reviewed keys and config** Fetch each key from the exact source URL in the spec to a temporary directory, verify its full fingerprint, and add its exact ASCII-armored content with `apply_patch`. Fill `installers.conf` with these reviewed values and conservative byte caps: ```text BUN_VERSION=1.4.0 BUN_X86_64_URL=https://github.com/oven-sh/bun/releases/download/bun-v1.4.0/bun-linux-x64.zip BUN_X86_64_SHA256=2d03fb5fb83ac8b567aca0a281b2ce1a1a19d488f56c2968d88c3f25e92fe452 BUN_X86_64_MAX_BYTES=67108864 BUN_AARCH64_URL=https://github.com/oven-sh/bun/releases/download/bun-v1.4.0/bun-linux-aarch64.zip BUN_AARCH64_SHA256=4b1a332ee861983eb93bcfe6f770fff94e3e31b2c388bdaea3c8ed35e58eed0e BUN_AARCH64_MAX_BYTES=67108864 NODE_VERSION=24.20.0 NODE_X86_64_URL=https://nodejs.org/dist/v24.20.0/node-v24.20.0-linux-x64.tar.xz NODE_X86_64_SHA256=2f2c0da162318f0de47665410c7c8c2ed3d36c8f3105de4bbc61176c70a7cbf2 NODE_X86_64_MAX_BYTES=67108864 NODE_AARCH64_URL=https://nodejs.org/dist/v24.20.0/node-v24.20.0-linux-arm64.tar.xz NODE_AARCH64_SHA256=5f4ddab610c1ab2016b3c227cebdbf6d9495161487e4739c7b90090595f465f7 NODE_AARCH64_MAX_BYTES=67108864 CODEX_VERSION=0.150.1 CODEX_X86_64_URL=https://github.com/openai/codex/releases/download/rust-v0.150.1/codex-package-x86_64-unknown-linux-musl.tar.gz CODEX_X86_64_SHA256=00aba704f029f6dc0d948be407a756e0c97cc840132fd691353b2c6b0a505b17 CODEX_X86_64_MAX_BYTES=134217728 CODEX_AARCH64_URL=https://github.com/openai/codex/releases/download/rust-v0.150.1/codex-package-aarch64-unknown-linux-musl.tar.gz CODEX_AARCH64_SHA256=1ecac3f87823efb98153233b076ea3d6e34a7a8cebe43c5285dc5f79e1514639 CODEX_AARCH64_MAX_BYTES=134217728 RUSTDESK_VERSION=1.4.9 RUSTDESK_X86_64_URL=https://github.com/rustdesk/rustdesk/releases/download/1.4.9/rustdesk-1.4.9-0.x86_64.rpm RUSTDESK_X86_64_SHA256=eb1b053ac5b2f774f2271f7fbbfd2ea475899f7a55135c5e172bc54b9388f108 RUSTDESK_X86_64_MAX_BYTES=134217728 FEDORA_RELEASE=44 RPMFUSION_FREE_RELEASE_URL=https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-44.noarch.rpm RPMFUSION_FREE_RELEASE_MAX_BYTES=4194304 RPMFUSION_NONFREE_RELEASE_URL=https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-44.noarch.rpm RPMFUSION_NONFREE_RELEASE_MAX_BYTES=4194304 TERRA_BASEURL=https://repos.fyralabs.com/terra44 HYPRLAND_COPR_BASEURL=https://download.copr.fedorainfracloud.org/results/lionheartp/Hyprland/fedora-$releasever-$basearch/ FLATHUB_DESCRIPTOR_URL=https://flathub.org/repo/flathub.flatpakrepo FLATHUB_DESCRIPTOR_MAX_BYTES=1048576 CLAUDE_CODE_BASEURL=https://downloads.claude.ai/claude-code/rpm/stable CLAUDE_DESKTOP_BASEURL=https://patrickjaja.github.io/claude-desktop-extra/rpm/ TERRA_FINGERPRINT=AE09157A4DE88B497EA1D5D300CDAB43DE226D6F CLAUDE_CODE_FINGERPRINT=31DDDE24DDFAB679F42D7BD2BAA929FF1A7ECACE BUN_FINGERPRINT=F3DCC08A8572C0749B3E18888EAB4D40A7B22B59 RPMFUSION_FREE_FINGERPRINT=E9A491A3DE247814E7E067EAE06F8ECDD651FF2E RPMFUSION_NONFREE_FINGERPRINT=79BDB88F9BBF73910FD4095B6A2AF96194843C65 HYPRLAND_COPR_FINGERPRINT=97E23476C89635135407C7D5E9BA41342C4B2995 FLATHUB_FINGERPRINT=6E5C05D979C76DAF93C081354184DD4D907A7CAE CLAUDE_DESKTOP_FINGERPRINT=825A7D15D78BABE45646D5DF382409F597908867 ``` Use the exact hashes and fingerprints from the spec; no value may be resolved through `latest`. The provenance README must list every source URL and the command used to verify it on 2026-08-27. - [ ] **Step 5: Add the manifest entry and run the focused gate** ```text # Provenance uses local signed fixtures and stubs every network/package operation. hermetic tests/setup/package-provenance-contract ``` Run: ```bash bash -n setup/lib/artifact-provenance tests/setup/package-provenance-contract tests/setup/package-provenance-contract tests/setup/contract-manifest-contract ./bin/panama test --safe package-provenance git diff --check ``` Expected: all pass and no host GPG/RPM state changes. - [ ] **Step 6: Commit the provenance foundation** ```bash git add setup/lib/artifact-provenance setup/provenance tests/setup/fixtures/provenance \ tests/setup/package-provenance-contract tests/contracts.manifest git commit -m "Test: Add installer provenance boundary" ``` --- ### Task 2: Verify third-party repository roots **Files:** - Modify: `setup/scripts/install-packages:218-276,339-370,396-456` - Modify: `tests/setup/package-provenance-contract` - Test: `tests/setup/desktop-first-contract` - Test: `tests/setup/package-lists-contract` **Interfaces:** - Consumes: `INSTALLER_PROVENANCE`, the four helper functions, vendored keys, and command adapters. - Produces: `install_rpmfusion_repositories`, `install_terra_repository`, `configure_hyprland_repository`, `ensure_flathub_remote`, `install_claude_code`, and `install_claude_desktop_if_trusted`. - [ ] **Step 1: Add public installer cases for every repository** Run a fixture copy of `install-packages` with temporary HOME/state and stubbed `sudo`, `dnf`, `rpm`, `rpmkeys`, `curl`, `flatpak`, and `gpg`. Assert exact command-log order and policy: ```text RPM Fusion: exact Fedora 44 URL -> size cap -> RPM signature -> localpkg_gpgcheck=1 install Terra: exact F44 key -> pkg_gpgcheck=1 -> repo_gpgcheck=1 -> local gpgkey -> terra-release COPR: exact baseurl/local key, package gpgcheck=1, explicit metadata-signature exception; no `dnf copr enable` Flathub: decoded embedded key fingerprint and GPG-enabled remote; mismatch preserves existing remote Claude Code: exact Anthropic key/repo checks before DNF Claude Desktop absent/untrusted: one manual message, no download, no DNF, overall success Claude Desktop trusted existing repo: DNF install only ``` Inject wrong keys, wrong base URLs, GPG flags off, signature failure, and DNF failure. Assert nothing downstream in the dependent transaction runs after a trust-root failure. Require `rpm -E %fedora` to equal the reviewed `FEDORA_RELEASE`; any other release fails before a third-party download or repository mutation. - [ ] **Step 2: Run the contract and confirm current unsafe paths fail** ```bash tests/setup/package-provenance-contract ``` Expected: nonzero findings for `--nogpgcheck`, TOFU COPR, unvalidated Flathub, remote-script Claude Desktop, and unverified RPM Fusion URLs. - [ ] **Step 3: Implement signed repository setup** Source the helper and load the config from `PANAMA_PATH` at installer start. Download RPM Fusion release RPMs, verify signatures with the matching vendored key, then call: ```bash sudo dnf install -y --setopt=localpkg_gpgcheck=1 "$free_rpm" "$nonfree_rpm" ``` Replace Terra with `--repofrompath terra,https://repos.fyralabs.com/terra44` plus: ```text --setopt=terra.pkg_gpgcheck=1 --setopt=terra.repo_gpgcheck=1 --setopt=terra.gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-terra44-panama ``` Stage repo/key files completely before atomic sudo install. Write the COPR repo from reviewed local values rather than `dnf copr enable`, with: ```ini [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 ``` The `repo_gpgcheck=0` line is the single audited exception: the publisher returns no `repodata/repomd.xml.asc`, while its RPMs are signed by the pinned project key. The contract rejects this exception for every other repository and still requires package signatures. Parse the Flathub descriptor as INI data, base64-decode `GPGKey`, verify its fingerprint, and reject `NoGPGVerify=true` or equivalent disabled state. Write Claude Code's stable repository with the vendored local key, `gpgcheck=1`, and `repo_gpgcheck=1`; its publisher provides signed metadata. For Claude Desktop, inspect only an already configured repo. Trust it only when its base URL equals `https://patrickjaja.github.io/claude-desktop-extra/rpm/`, both GPG checks are `1`, and its `gpgkey` is an existing local file whose complete fingerprint matches the vendored `claude-desktop.asc`. Never curl or run the community setup script. The host's current remote-key configuration is therefore treated as untrusted until an operator configures a local reviewed key. Untrusted/absent configuration logs an optional manual instruction and returns success. - [ ] **Step 4: Verify ordering and regression contracts** ```bash bash -n setup/scripts/install-packages tests/setup/package-provenance-contract tests/setup/package-provenance-contract tests/setup/desktop-first-contract tests/setup/package-lists-contract ./bin/panama test --safe package-provenance git diff --check ``` - [ ] **Step 5: Commit repository trust roots** ```bash git add setup/scripts/install-packages tests/setup/package-provenance-contract git commit -m "Fix: Verify third-party package repositories" ``` --- ### Task 3: Pin language runtimes and agent tools **Files:** - Modify: `setup/scripts/install-packages:100-177,334-394` - Modify: `tests/setup/package-provenance-contract` - Modify: `tests/quickshell/declared-dependencies-contract` **Interfaces:** - Consumes: `download_sha256`, loaded reviewed pins, supported `uname -m` values `x86_64` and `aarch64`. - Produces: `install_node`, `install_bun`, `install_claude_code`, `install_codex`, and `install_rustdesk` with verified staging and known-good preservation. - [ ] **Step 1: Add failing per-architecture and preservation cases** For each artifact, assert exact URL/digest selection for x86_64 and aarch64, unsupported-architecture refusal before curl, digest mismatch preserving a seeded old version, interrupted download cleanup, atomic replacement, and already-installed exact-version no-op. Require source scans and public command logs to reject: ```text curl ... | bash nvm install --lts npm install -g pnpm npm install -g @openai/codex releases/latest api.github.com/.../releases/latest ``` RustDesk supports only the reviewed x86_64 RPM. aarch64 records a deliberate soft failure without downloading. pnpm must come from signed Fedora DNF; no network-script/npm fallback is allowed. - [ ] **Step 2: Run the focused contract and confirm it fails on moving inputs** ```bash tests/setup/package-provenance-contract ``` Expected: nonzero findings naming each current moving or piped installer. - [ ] **Step 3: Implement verified atomic installs** Map architecture once: ```bash case "$(uname -m)" in x86_64) artifact_arch=X86_64 ;; aarch64) artifact_arch=AARCH64 ;; *) log "Unsupported architecture: $(uname -m)"; return 1 ;; esac ``` Install Node 24.20.0 into `$NVM_DIR/versions/node/v24.20.0` from a sibling staging directory, reject archive entries outside the expected single top-level directory, require staged `bin/node --version` to print `v24.20.0`, then rename and set nvm's default alias to `24.20.0` without `nvm install`. For Bun, reject unexpected archive paths, stage the binary at `$HOME/.bun/versions/1.4.0/bin/bun`, require `--version` to print `1.4.0`, then atomically replace a temporary symlink at `$HOME/.bun/bin/bun`. For Codex, reject absolute/parent-traversal tar members, stage the release's `codex` binary at `$HOME/.local/lib/panama/codex/0.150.1/codex`, require `--version` to identify `0.150.1`, then atomically replace `$HOME/.local/bin/codex` through a temporary symlink. Existing version directories must match the reviewed binary/version or cause a soft failure; never delete and recreate an unverified collision. Install Claude Code through the signed stable repository from Task 2. Download RustDesk's versioned RPM, verify SHA-256, then pass only that local path to DNF. Install pnpm through the signed Fedora package transaction and record a soft failure if unavailable. Every archive extracts into a checked private directory first; no archive writes directly into its final prefix. Every helper failure appends the same component name to `softly_failed`; `report_soft_failures` keeps the package hash unstamped. - [ ] **Step 4: Run focused and dependency checks** ```bash bash -n setup/scripts/install-packages tests/setup/package-provenance-contract tests/setup/package-provenance-contract tests/quickshell/declared-dependencies-contract tests/setup/desktop-first-contract ./bin/panama test --safe package-provenance git diff --check ``` - [ ] **Step 5: Commit pinned user tools** ```bash git add setup/scripts/install-packages tests/setup/package-provenance-contract \ tests/quickshell/declared-dependencies-contract git commit -m "Fix: Pin runtime and agent artifacts" ``` --- ### Task 4: Invalidate stale installer state and lock npm installs **Files:** - Modify: `install:67-106` - Modify: `setup/scripts/link-vicinae-scripts:79-97` - Modify: `tests/setup/launcher-search-contract` - Modify: `tests/setup/update-command-contract` - Modify: `tests/setup/package-provenance-contract` **Interfaces:** - Consumes: tracked package lists, installer, provenance helper/config/keys, and extension lockfile. - Produces: `hash_packages` covering every installer trust input and Vicinae `npm ci` behavior. - [ ] **Step 1: Write failing hash and lockfile assertions** Run `hash_packages` from a disposable installer copy and assert the digest changes independently when each of these changes: ```text setup/packages/core-packages setup/scripts/install-packages setup/lib/artifact-provenance setup/provenance/installers.conf one setup/provenance/keys file ``` In the Vicinae fixture, stub npm and require argv `ci`, not `install`. Seed a lock mismatch and assert nonzero extension-build status with the lockfile byte-for-byte unchanged. - [ ] **Step 2: Confirm current hash and npm behavior fail** ```bash tests/setup/package-provenance-contract tests/setup/launcher-search-contract ``` Expected: current hash ignores installer/provenance changes and extension setup invokes `npm install`. - [ ] **Step 3: Hash exact inputs and switch to `npm ci`** Replace the current `find ... -maxdepth 1` stream with a sorted NUL-safe list containing top-level package files, `setup/scripts/install-packages`, `setup/lib/artifact-provenance`, and every regular file under `setup/provenance`. Hash file paths plus contents so renames change the digest. Change only the extension dependency command to `npm ci`; do not add lockfile repair or update behavior. - [ ] **Step 4: Verify upgrade and extension behavior** ```bash bash -n install setup/scripts/link-vicinae-scripts tests/setup/package-provenance-contract tests/setup/launcher-search-contract tests/setup/update-command-contract ./bin/panama test --safe package-provenance git diff --check ``` - [ ] **Step 5: Commit state invalidation and npm locking** ```bash git add install setup/scripts/link-vicinae-scripts tests/setup/launcher-search-contract \ tests/setup/update-command-contract tests/setup/package-provenance-contract git commit -m "Fix: Re-run verified installer inputs" ``` --- ### Task 5: Verify the initial Panama revision before handoff **Files:** - Modify: `boot:20-166` - Modify: `tests/setup/boot-contract` - Modify: `README.md:1-48` - Modify: `tests/setup/readme-contract` - Modify: `.claude/skills/panama/SKILL.md` - Modify: `skills/panama-desktop/SKILL.md` **Interfaces:** - Consumes: `PANAMA_BOOT_REVISION` as a full lowercase 40-hex commit and `PANAMA_BOOT_SHA256` as a lowercase 64-hex digest. - Produces: verified fresh clone at that revision, fast-forward-only clean existing checkout, and documentation pinned to the implementation commit immediately preceding its documentation commit. - [ ] **Step 1: Replace old permissive boot-contract expectations with red trust cases** The public fixture must assert: ```text missing/malformed revision -> no git clone/fetch and no install fresh clone -> fetch exact revision, resolve HEAD^{commit}, equality, handoff HEAD mismatch -> nonzero, no install existing clean ancestor -> fast-forward to exact revision, then install existing dirty or divergent checkout -> nonzero, no reset, no install fetch failure -> nonzero, no install ``` Delete the old assertion that a failed pull proceeds with the checkout as-is. Add README assertions rejecting `bash <(curl .../main/boot)` and requiring a commit URL, 40-hex revision, 64-hex SHA-256, `sha256sum -c`, 10-second connect timeout, 30-second total timeout, and 256 KiB maximum. - [ ] **Step 2: Run boot and README contracts to prove they fail** ```bash tests/setup/boot-contract tests/setup/readme-contract ``` Expected: both fail on the mutable branch bootstrap and permissive pull fallback. - [ ] **Step 3: Implement exact-revision clone/handoff and commit it** Validate inputs before Git: ```bash [[ "${PANAMA_BOOT_REVISION:-}" =~ ^[0-9a-f]{40}$ ]] || exit 1 [[ "${PANAMA_BOOT_SHA256:-}" =~ ^[0-9a-f]{64}$ ]] || exit 1 actual_boot_sha="$(sha256sum "${BASH_SOURCE[0]}" | cut -d' ' -f1)" [[ "$actual_boot_sha" == "$PANAMA_BOOT_SHA256" ]] || exit 1 ``` For a fresh destination, initialize/fetch the exact commit, verify `git rev-parse HEAD^{commit}` equality, create local `main` at that commit, and set `branch.main.remote=origin` plus `branch.main.merge=refs/heads/main`. For an existing checkout, require empty `git status --porcelain`, fetch the exact commit, require `git merge-base --is-ancestor HEAD REVISION`, and fast-forward only. Never use reset or execute after mismatch/failure. Run focused tests, then commit only implementation and contract changes: ```bash bash -n boot tests/setup/boot-contract tests/setup/boot-contract tests/setup/root-server-bootstrap-contract git add boot tests/setup/boot-contract tests/setup/root-server-bootstrap-contract git commit -m "Fix: Verify the initial Panama revision" ``` - [ ] **Step 4: Compute the committed boot pin and write the documented command** Use the implementation commit just created: ```bash bootstrap_commit="$(git rev-parse HEAD)" bootstrap_sha="$(git show "$bootstrap_commit:boot" | sha256sum | cut -d' ' -f1)" ``` Write README commands that download `https://git.gbrown.org/gib/Panama/raw/commit/$bootstrap_commit/boot` to a checked temporary file with `curl --connect-timeout 10 --max-time 30 --max-filesize 262144`, compare `$bootstrap_sha` through `sha256sum -c`, then invoke with both environment values. Use the same verified command for desktop and `--server`; never pipe the response to Bash. The README contract must parse those literal values, run `git cat-file -e COMMIT^{commit}`, and require: ```bash test "$(git show "$commit:boot" | sha256sum | cut -d' ' -f1)" = "$documented_sha" ``` - [ ] **Step 5: Update operator skills and run the complete installer plan gate** ```bash bash -n boot install setup/scripts/install-packages setup/scripts/link-vicinae-scripts \ setup/lib/artifact-provenance tests/setup/package-provenance-contract \ tests/setup/boot-contract tests/setup/package-provenance-contract tests/setup/boot-contract tests/setup/root-server-bootstrap-contract tests/setup/readme-contract tests/setup/package-lists-contract tests/setup/desktop-first-contract tests/setup/launcher-search-contract tests/setup/update-command-contract ./bin/panama test --safe git diff --check ``` Expected: 133 hermetic contracts pass after the SSH and provenance contracts exist; non-hermetic skip counts remain unchanged. - [ ] **Step 6: Commit the pinned documentation** ```bash git add README.md tests/setup/readme-contract .claude/skills/panama/SKILL.md \ skills/panama-desktop/SKILL.md setup/provenance/README.md git commit -m "Docs: Pin the verified Panama bootstrap" ``` --- ### Task 6: Smoke-test signed Terra bootstrap in a disposable Fedora 44 container **Files:** - Modify: `setup/provenance/README.md` - Modify: `tests/setup/package-provenance-contract` only if the smoke test exposes a fixture gap **Interfaces:** - Consumes: exact Terra key/repo command landed in Task 2. - Produces: recorded disposable proof or a fail-closed Terra-unavailable implementation; never host installation. - [ ] **Step 1: Preflight the disposable target** Require rootless Podman, no bind mounts, a fresh `registry.fedoraproject.org/fedora:44` container, and no forwarded credentials or host sockets. The command may download repository metadata and the `terra-release` package only inside the disposable container. - [ ] **Step 2: Run the exact key and DNF verification path** Copy only the vendored Terra key into the container, verify its full fingerprint, then run the exact `--repofrompath` and three `terra.*` GPG settings from Task 2. Query the resulting repo file and package signature settings. Remove the container on exit. Expected: DNF installs `terra-release` with both package and metadata verification enabled and without `--nogpgcheck`. - [ ] **Step 3: Apply the fail-closed result** If the exact command fails, do not weaken GPG settings. Change the installer to print Terra unavailable and exit before initial/desktop/Hyprland transactions; update the fixture expectation to that branch. If it succeeds, make no production change. - [ ] **Step 4: Record proof and rerun the hermetic gate** Document the container image, date, exact command, exit status, key fingerprint, and inspected repo settings in `setup/provenance/README.md`. Do not claim host installation. ```bash tests/setup/package-provenance-contract ./bin/panama test --safe git diff --check ``` - [ ] **Step 5: Commit the provenance proof** ```bash git add setup/provenance/README.md setup/scripts/install-packages \ tests/setup/package-provenance-contract git commit -m "Docs: Record signed Terra bootstrap proof" ```