docs(installer): Phase 5 — scope, the §5.3 correction, and the operator guide #96
Reference in New Issue
Block a user
No description provided.
Delete Branch "docs/installer-phase5-scope"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What & why
The documentation half of Phase 5. Follows #95, which put the phase before the cutover but left its four sketched items unexamined. Three commits, in the order the work happened: settle the scope, correct what building it disproved, then specify the run.
Code PRs this covers: installer#9, link#26, installer#10 (arm64), installer#11 (backup), installer#12 (repo README).
1 — §5.1: no
.deb, no MSIBoth were proposed before Phases 2 and 4 existed, and now collide with what those phases made the installer own.
A
.debunder link's release would own/usr/bin/runicgateway-link, the systemd unit and the service user — the three thingsservice.rswrites, hardens and removes, and thatinstall.jsonrecords sodoctoranduninstallcan reason about them. Two owners for one file is not a packaging detail:uninstalldeleting a dpkg-owned binary leaves the package installed and broken, anapt upgrademakesdoctorreport drift no operator caused, and the unit text would live in two repos free to disagree about the account it runs as. The variant that avoids all that — binary-only, no unit, no user — buys apt-managed upgrades of one file, whichupdatealready does from a protocol-checked bundle (§7.1). That is the stronger guarantee, so the package would trade correctness for familiarity.An MSI contradicts a locked decision — the installer does not install itself (Phase 0.4) — and adds a second uninstall path (Add/Remove Programs) beside the
uninstallverb, which owns state an MSI cannot see. Unsigned, it raises the same SmartScreen prompt a bare.exedoes.2 — §5.2: Linux
aarch64, in a forced orderThe step table names repo, branch and reason for each of four steps. The order is dictated by the bundle CI being strict in opposite directions — an unrecognized asset name fails, and a missing required key fails — so the name must be taught before the release that carries it, and required only after.
bundle.ymlis edited onmainonly and never onedge, so the cutover merge has nothing to conflict over.Building it added a paragraph. Neither crate cross-compiles with the arm64 compiler alone:
gcc-aarch64-linux-gnuonly recommendslibc6-dev-arm64-cross, and both release workflows install--no-install-recommends. Every Rust dependency builds fine and then the C dies on a missingbits/libc-header-start.h— bundled SQLite undersqlxfor the sidecar,ringunderureq's rustls for the installer. Reproduced both ways in a container before either workflow was written.3 — §5.3: the trigger was wrong, and building it showed that
The section said a backup is taken for an
updateand for aninstallover an existing record, justified by "a first install overwrites nothing." That is not true of a tree deployed by hand perINSTALL.mdAppendix A2 — the path this project recommends while the binary is unreleased. There, a firstinstallfinds.csfiles that differ, plans them asChange, and overwrites them with no prior record anywhere to notice.The rule is now the direct one: back up whenever the run is about to overwrite something. A genuine first install onto a clean tree still writes nothing, because there is nothing to copy.
Two smaller corrections in the same area:
sidecar.tomljoins a backup rather than causing one (nothing rewrites it, so triggering on it would leave a dated directory after every no-opupdate), and the directory is created lazily with the manifest written last — so an interrupted run can neither be mistaken for a backup nor evict a good one by being newer.4 — §5.4 /
INSTALL.md: the operator guideThe guide is the specification of the run, so this is part of building the phase rather than a write-up after it: the
aarch64download lines (uname -m, and why there is no macOS or Windows-on-arm build), the arm64 asset in Appendix A3's by-hand path, whatupdatebacks up and when it does not,--no-backupin the flags table, backups in--purge's row, the uninstall table, both paths tables anddoctor's sample output.Also updated in
PLAN.md: §3's release layout (loses the.deb, gains theaarch64assets), §2.6's arm64 bullet, §7.1's example bundle, Phase 4's uninstall "Kept" row, and a state column on the Phase 5 table linking each code PR.How it was tested
Prose. The claims that are observations rather than decisions were checked against the code they describe:
bundle.rs:102,bundle.yml's unrecognized-name failure and required-key assertion,link/release.yml's targets,store.rs'sCREATE TABLE IF NOT EXISTSDDL,overlay.rs'sAction::Changeplanning of a differing file with no prior record, and the branch comparison showingedge ⊃ mainwith identicalbundle.yml. Thelibc6-dev-arm64-crossfinding is a reproduced container build, not a recollection.Checklist
AI-assisted contributions (required)
Claude Code (Opus 5). I have reviewed and understand every change, and take responsibility for it. AI-authored commits are marked with aCo-Authored-Bytrailer.License
docs(installer): settle Phase 5's scope — no .deb, no MSI, aarch64 and backupsto docs(installer): Phase 5 — scope, the §5.3 correction, and the operator guide