docs(installer): Phase 5 — scope, the §5.3 correction, and the operator guide #96

Merged
whitlocktech merged 3 commits from docs/installer-phase5-scope into main 2026-08-05 17:52:22 +00:00
Showing only changes of commit e18eec8957 - Show all commits

View File

@@ -894,12 +894,13 @@ operators who downloaded a bare binary being told to re-download a package. Defe
costs nothing: nothing is published from `edge`, and the guide's Appendix A is the supported path costs nothing: nothing is published from `edge`, and the guide's Appendix A is the supported path
meanwhile. meanwhile.
| Item | Decision | | Item | Decision | State |
|---|---| |---|---|---|
| `.deb` for uo-link | **Dropped** (§5.1) | | `.deb` for uo-link | **Dropped** (§5.1) | — |
| Windows MSI | **Dropped** (§5.1) | | Windows MSI | **Dropped** (§5.1) | — |
| arm64 cross build | **Build** — Linux `aarch64`, both components (§5.2) | | arm64 cross build | **Build** — Linux `aarch64`, both components (§5.2) | In review: [installer#9](https://gitea.whitlocktech.com/RunicGateway/installer/pulls/9), [link#26](https://gitea.whitlocktech.com/RunicGateway/link/pulls/26), [installer#10](https://gitea.whitlocktech.com/RunicGateway/installer/pulls/10); step 3 waits on link's first arm64 release |
| Backup before upgrade | **Build** — on by default, scoped to what a run overwrites (§5.3) | | Backup before upgrade | **Build** — on by default, scoped to what a run overwrites (§5.3) | In review: [installer#11](https://gitea.whitlocktech.com/RunicGateway/installer/pulls/11) |
| Docs the release invalidates | **Do** (§5.4) | Pending |
#### 5.1 What ships is plain binaries: no `.deb`, no MSI #### 5.1 What ships is plain binaries: no `.deb`, no MSI
@@ -961,6 +962,13 @@ lasts. Hence:
`bundle.yml` is therefore edited on `main` only and never on `edge`, so the cutover merge has nothing `bundle.yml` is therefore edited on `main` only and never on `edge`, so the cutover merge has nothing
to conflict over. to conflict over.
**What building it found.** Neither crate cross-compiles with the arm64 *compiler* alone.
`gcc-aarch64-linux-gnu` only **recommends** `libc6-dev-arm64-cross`, and both release workflows
install with `--no-install-recommends` — so the C that each crate pulls in (bundled SQLite under
`sqlx` for the sidecar, `ring` under `ureq`'s rustls for the installer) dies on a missing
`bits/libc-header-start.h` while every Rust dependency builds fine. Both halves were reproduced in a
`rust:1-slim-bookworm` container, failure then fix, before either workflow was written.
#### 5.3 Backup before overwrite #### 5.3 Backup before overwrite
**Scoped by what cannot be fetched again.** Not the sidecar binary or the overlay files — both are **Scoped by what cannot be fetched again.** Not the sidecar binary or the overlay files — both are
@@ -982,14 +990,28 @@ that is still downloadable, and the noise would bury the two files that matter.
from, beside a `manifest.json` naming the source path, its SHA256, and the bundle moved from and from, beside a `manifest.json` naming the source path, its SHA256, and the bundle moved from and
to. In the state directory, not the ServUO tree — the same rule the tier's `patches/originals/` to. In the state directory, not the ServUO tree — the same rule the tier's `patches/originals/`
follows, and for the same reason: `uninstall` has promised never to clean up in there. follows, and for the same reason: `uninstall` has promised never to clean up in there.
- **When:** on by default for `update`, and for an `install` over an existing record. A first - **When: whenever the run is about to overwrite something**, whichever verb was typed. This
install overwrites nothing and writes no backup. `--verify` writes none either, for the reason it section first said "`update`, and `install` over an existing record", justified by a first install
runs no part of the sidecar half (Phase 2): a dry run must not create state. overwriting nothing — **which is wrong**, and building it is what showed that. A tree deployed by
hand per [`INSTALL.md`](INSTALL.md) Appendix A2 — the path this project recommends while the
binary is unreleased — has `.cs` files the first `install` plans as `Change` and overwrites, with
no prior record anywhere to notice. The direct test covers that case, and a genuine first install
onto a clean tree still writes nothing, because there is nothing to copy. `--verify` writes none
either, for the reason it runs no part of the sidecar half (Phase 2): a dry run must not create
state.
- **`sidecar.toml` joins a backup that is already being taken; it is never the reason for one.**
Nothing in the installer rewrites it, so treating it as a trigger would leave a dated directory
behind after every no-op `update` — the empty-backup problem one step along. It is copied so that
a restored set of files arrives with the token that matches it.
- **`--no-backup`** opts out, for an operator with their own snapshotting. - **`--no-backup`** opts out, for an operator with their own snapshotting.
- **Retention is three.** Older ones are pruned as new ones are written; an unbounded directory of - **Retention is three.** Older ones are pruned as new ones are written; an unbounded directory of
ServUO source copies on a shard host is its own support problem. `uninstall` keeps them and ServUO source copies on a shard host is its own support problem. `uninstall` keeps them and
`--purge` drops them, alongside the config, the database and the cached patch set — same rule as `--purge` drops them, alongside the config, the database and the cached patch set — same rule as
Phase 4, and the same reason: they are the only offline record of what was there before. Phase 4, and the same reason: they are the only offline record of what was there before.
- **The directory is created lazily and the manifest is written last**, so a directory carrying one
is a *complete* backup. Listing and pruning consider only those: a run interrupted mid-copy must
neither be mistaken for a backup nor be able to evict a good one by being newer than it. It is
left on disk for a human to look at rather than silently deleted.
- **Restore is printed, not done.** Consistent with the uninstall report, and for the identical - **Restore is printed, not done.** Consistent with the uninstall report, and for the identical
reason: the installer cannot know what has changed since, and a clever automatic restore over a reason: the installer cannot know what has changed since, and a clever automatic restore over a
newer overlay eats work rather than saving it. `doctor` names the most recent backup and its newer overlay eats work rather than saving it. `doctor` names the most recent backup and its