spawn-arch is a narrowly scoped, auditable installer for one machine profile: an
Intel + NVIDIA Optimus laptop with KDE Plasma, LUKS2, Btrfs, systemd-boot, and
zram. Its balanced workstation baseline also pins PipeWire, a user-scoped
OpenSSH agent, a local Docker daemon, a closed inbound firewall, bounded
persistent logs, package vulnerability auditing, and low-risk kernel hardening.
It is intentionally fail-closed around disk identity and boot state.
This repository is not a generic distribution installer. Read the generated plan before authorizing the destructive step.
wipe.sh is a separate destructive utility for use from the Arch ISO. Boot the
target laptop from external media, then run it as root:
./wipe.shThe utility shows whole disks with their device path, size, transport, and model. Select a disk and method, verify the details, then confirm once. The operation is irreversible; do not select the live USB device.
Two methods are available:
- Full zero pass writes zeroes to every byte addressable by the operating
system with
dd. It can take a long time and does not guarantee clearing remapped or reserved NAND blocks on an SSD. - Firmware secure erase uses ATA Secure Erase for a directly attached SATA SSD or the strongest NVMe Sanitize action advertised by an NVMe SSD (overwrite, block erase, then crypto erase). It rejects USB, SAS, RAID, and unsupported or frozen SATA devices. A frozen SATA drive must be power-cycled before the firmware command can run.
Boot the current official Arch Linux ISO in UEFI mode. The live environment runs as root.
-
Connect to the network. For Wi-Fi, use
iwctl; for wired Ethernet, verify the link withip linkand test connectivity withping -c 3 archlinux.org. -
Confirm that the clock is synchronized:
timedatectl status -
Download the fixed v0.1.0 release archive and its checksum. Do not substitute a branch archive or execute downloaded text through a shell pipeline.
curl --fail --location --remote-name https://github.com/evynore/spawn-arch/releases/download/v0.1.0/spawn-arch-v0.1.0.tar.gz curl --fail --location --remote-name https://github.com/evynore/spawn-arch/releases/download/v0.1.0/spawn-arch-v0.1.0.tar.gz.sha256 sha256sum -c spawn-arch-v0.1.0.tar.gz.sha256 tar -xzf spawn-arch-v0.1.0.tar.gz cd spawn-arch-v0.1.0
-
Run the read-only environment and hardware checks:
./spawn-arch doctor -
Build the non-destructive installation plan. Select only the intended Linux target SSD and answer the profile prompts:
./spawn-arch plan -
Review
/run/spawn-arch/plan.jsonin full. In particular, compare the target device, model, serial, WWN, capacity, partition geometry, username, hostname, and source commit with the hardware and the release you downloaded. -
Start the destructive phase only after that review:
./spawn-arch installThe installer re-resolves the target from stable identity immediately before writing. Its confirmation is the exact target serial from the plan, entered in this form:
ERASE <serial-from-plan>It then asks separately for the encryption secret and the user password. These secrets are held in the live runtime only and are removed during cleanup.
-
When installation completes, verify the mounted target without modifying it:
./spawn-arch verify /mntIf installation or verification reports a failure, Do not reboot. After a post-install finalization failure, the only safe continuation is:
./spawn-arch install --resume-finalize ./spawn-arch verify /mnt
The resume path verifies the recorded disk and filesystem fingerprints and never invokes the partitioner or Archinstall again. For any other failure, preserve the complete output and inspect the target from the live ISO. Before rebooting, create a local read-only diagnostic report in the current directory:
./spawn-arch investigateThe command prints paths for two bounded, redacted reports: a readable
.txtreport for paging or photographing and a canonical.jsonreport for machine analysis. Open the readable report from the same directory with:less spawn-arch-investigation-*.txtThe reports contain installer state, log tails, mounts, active LUKS status, relevant processes, systemd machine state, hardware inventory, tool versions, and a
dmesgtail. The command never reads credential files, changes the target, or uploads either report. -
Only after the offline verification succeeds, reboot:
systemctl reboot -
Select the new Linux disk in the firmware if necessary. Enter the
LUKS passphrasewhen prompted, then sign in to thePlasma Waylandsession. -
Run the physical acceptance checks below. If every required check succeeds, commit this boot as the known-good state:
sudo spawn-arch verify --bless
Do not bless an unverified boot. A successful bless is an explicit acceptance of the running kernel, root subvolume, graphics paths, services, power profile, and boot artifacts.
The root filesystem is encrypted with LUKS2. Inside it, Btrfs provides separate
@, @home, @log, @pkg, and @snapshots subvolumes. Zram supplies compressed
swap; no disk swap partition is created. The EFI System Partition remains outside
the encrypted container so firmware can start the boot chain.
Systemd-boot launches unified kernel images named spawn-arch-current.efi and
spawn-arch-last-good.efi. The current entry uses the dynamic Btrfs default
subvolume rather than embedding subvol= in the kernel command line. This is what
allows a rollback to perform a transactional default-subvolume transition.
The last-good entry is a kernel/initramfs recovery path: last-good does not switch the Btrfs root. Use the rollback command when the filesystem state must move to a snapshot as well.
The root filesystem is encrypted with LUKS2, but ESP, systemd-boot, UKIs, and boot-state JSON are unencrypted and unsigned. Therefore physical write access to the ESP can modify the boot chain. Secure Boot and TPM enrollment are deliberately left for a later, separately designed trust model; this release makes no verified boot claim.
Disk selection is fail-closed. The installer excludes the live medium, mounted disks, read-only devices, and disks with Windows markers; it revalidates immutable identity before each destructive boundary. With a dedicated Linux SSD selected, the installer never mounts or writes the Windows SSD and it does not create or modify a Windows boot entry. Use the firmware boot menu until the explicit post-install synchronization below is requested.
No software can compensate for selecting the wrong physical disk. The plan review and exact serial confirmation remain mandatory operator controls.
The encrypted-root prompt uses the official Breeze Plymouth theme at 2x scale.
Plymouth is embedded into the UKI initramfs before sd-encrypt, while quiet splash keeps normal boot output behind the graphical prompt. Press Escape to
show boot diagnostics. Before Secure Boot is enabled, the systemd-boot editor is
available with e; append plymouth.enable=0 disablehooks=plymouth for a
one-time text-mode recovery boot if the graphical prompt ever fails.
PipeWire, PipeWire Pulse compatibility, ALSA integration, and WirePlumber are
installed explicitly rather than inherited accidentally through Plasma. rtkit
provides the realtime scheduling policy expected by the audio stack, and
wireless-regdb supplies the kernel regulatory database. The
OpenSSH agent is enabled as a systemd user service and uses
$XDG_RUNTIME_DIR/ssh-agent.socket; the SSH server remains disabled. Keys are
never generated, copied, enumerated, or unlocked by the installer. OpenSSH uses
AddKeysToAgent yes, and ksshaskpass can store an encrypted key's passphrase
in KWallet only after the first use, when the user explicitly selects Remember password
in the dialog. The private key remains a normal mode-0600 file under
~/.ssh; KWallet stores only the remembered passphrase.
Automatic reuse requires KWallet to be unlocked by a password-based Plasma login
using the same password as the default wallet. Autologin, passwordless login,
and fingerprint-only login do not provide that secret and are outside
this guarantee. An empty agent is valid until a key is actually used; the
installer never runs ssh-add eagerly.
The created user's login shell is Zsh. /etc/zsh/zshrc initializes native Zsh
completions and Starship from the managed /etc/starship.toml, which is pinned
to Starship's official plain-text-symbols preset. User customization remains
available through ~/.zshrc, ~/.zshenv, and user environment.d files; the
installer creates none of those user files. FiraCode Nerd Font Mono is installed
and selectable, but it is not selected automatically in Konsole, Plasma,
editors, or global font configuration.
Docker runs as a local system service with its Unix socket only. Container logs
use the bounded local driver, and new containers inherit the daemon's
no-new-privileges policy. The installer does not add the interactive user to the
docker group because access to that socket is root-equivalent; use sudo docker until that privilege is explicitly accepted. Docker's TCP API is not
configured. Its unit wants and starts after both network-online.target and
firewalld.service, avoiding the startup race between Docker rule management and
firewalld initialization.
Firewalld uses the spawn-workstation default zone. It drops unsolicited inbound
traffic and opens no services or ports. Network sharing, KDE Connect, SSH access,
game streaming, and published container ports require explicit operator action.
Docker manages separate forwarding rules, so publishing a container port is a
network exposure decision and is not constrained by the workstation zone alone.
Persistent journald storage is compressed, limited to 1 GiB while reserving 2
GiB free, and retained for at most 30 days. arch-audit.timer provides package
vulnerability checks; upgrades remain manual full-system upgrades rather than
unattended or partial updates.
The unused systemd-pcrlogin measurement unit is conditionally disabled because
this release does not enroll TPM-backed login or disk-unlock policy. The TPM is
never cleared or re-provisioned by spawn-arch.
This baseline deliberately excludes alternative initramfs tooling, mandatory access-control policy, audit rules, signed-boot enrollment, GPU compute and container toolchains, and game packages. Those change the boot or application trust model and require separate design and acceptance work.
Run installed-state commands as root:
sudo spawn-arch status
sudo spawn-arch snapshots list
sudo spawn-arch verifyAfter booting the installed system, copy Windows Boot Manager to the Linux ESP:
sudo spawn-arch windows-boot syncThe command discovers a different GPT/vfat ESP containing both
EFI/Microsoft/Boot/bootmgfw.efi and its BCD database. It mounts that source
read-only, never mounts the Windows data partition, copies the complete
EFI/Microsoft tree through a validated staging directory, and adds an explicit
systemd-boot entry. Re-running the command after a Windows bootloader update is
safe; an unchanged tree reports already up to date.
If more than one valid Windows ESP exists, inspect lsblk -f and select the
partition explicitly:
sudo spawn-arch windows-boot sync --source /dev/nvme0n1p1The copied EFI files remain byte-identical so their Microsoft signatures are preserved. Secure Boot is still disabled in this release; a later design must sign the Linux boot chain and enroll the applicable Microsoft UEFI CA before it can make a verified-boot claim.
To prepare a transactional rollback, select either the current known recovery point or an explicit Snapper snapshot:
sudo spawn-arch rollback latest
sudo spawn-arch rollback 7394Rollback creates a read-only safety snapshot, makes a writable future root, builds and validates its UKI, and commits boot state with crash-recovery metadata. Reboot into it, run the acceptance checks, and only then use:
sudo spawn-arch verify --blessIf the current UKI cannot boot but the filesystem default should remain unchanged, select the last-good entry from systemd-boot or request it from a working console:
sudo bootctl set-oneshot spawn-arch-last-good
systemctl rebootRun these checks after the first graphical login and after every rollback. Capture their output before blessing:
uname -a
bootctl status
cat /proc/cmdline
findmnt --verify
findmnt -no SOURCE,FSTYPE,OPTIONS /
btrfs subvolume get-default /
swapon --show
powerprofilesctl get
loginctl show-session "$XDG_SESSION_ID" -p Type -p Desktop
glxinfo -B
vulkaninfo --summary
prime-run glxinfo -B
nvidia-smi
systemctl --user is-active pipewire pipewire-pulse wireplumber ssh-agent
ssh-add -l
sudo docker info
sudo firewall-cmd --get-default-zone
sudo firewall-cmd --get-log-denied
sudo firewall-cmd --zone=spawn-workstation --list-all
sudo journalctl --verify
sudo journalctl --disk-usage
systemctl is-active arch-audit.timer
systemctl --failed
journalctl -b -p warningAcceptance requires all of the following:
- The selected entry and command line belong to the current unified kernel image.
- The active Btrfs root is the filesystem default, and mount verification is clean.
- zram is the only swap and has priority 100.
- The session is a non-root local Plasma Wayland session.
- Intel is the default renderer for OpenGL and Vulkan.
- NVIDIA works through PRIME offload, and
nvidia-smiis healthy. - The initial power profile is
balancedand required services are active. - PipeWire and the user SSH agent are active; an empty
ssh-add -lresult is valid. - Docker is local and responsive, and the closed firewalld zone has no implicit openings.
- Persistent journal verification succeeds and the package audit timer is active.
- There are no unexplained failed units or boot warnings.
Do not bless the boot if any required observation fails. Diagnose it while the previous known-good UKI and snapshot state are still preserved.
The normal local gate is:
make qualityThe destructive lifecycle harness operates only on disposable QEMU disk images; it never accepts a host block device. A developer with the required virtualization tools and an independently verified Arch ISO can run:
export SPAWN_QEMU_ISO=/path/to/archlinux.iso
export SPAWN_QEMU_ISO_SHA256=<sha256-from-archlinux.org>
make integrationRelease archives are built only from a clean tree with an annotated SemVer tag at
HEAD:
scripts/build-release-archive.sh v0.1.0The builder produces a deterministic archive, checksum, installation note, and a
SOURCE_COMMIT provenance file under dist/. Tag creation and publication are
explicit maintainer actions after automated gates and physical acceptance pass.