PLAN.md §5.3. Before anything is written, every file this run will
replace is copied into <state>/backups/<utc-stamp>/ with a manifest
naming where each came from. --no-backup opts out; --verify takes none.
Scoped by what cannot be fetched again. The sidecar binary and the
overlay files are re-downloadable and hash-named in the bundle, and the
database is a cache with a schema -- link's store.rs creates every table
IF NOT EXISTS over shard state the sweeps repopulate. What a run can
destroy for good is an operator's edits to a deployed .cs file, which
Phase 1 overwrites unconditionally and by design, and sidecar.toml,
whose token the website already holds.
Two deviations from §5.3 as written, both found by building it:
- The trigger is "this run is about to overwrite something", not "an
update, or an install over an existing record". §5.3 justified the
latter with "a first install overwrites nothing" -- which is not true
of a tree deployed by hand per INSTALL.md Appendix A2, a documented
path. There the first install finds .cs files that differ, plans them
as Change, and overwrites them with no record anywhere. The direct
test covers that case and still writes nothing for a genuine first
install, because there is nothing to copy.
- sidecar.toml joins a backup that is already being taken and is never
the reason for one. Nothing here rewrites it, so making it a trigger
would put a dated directory on disk after every no-op update; it is
copied so a restored set of files comes with the token that matches
them.
The directory is created lazily and the manifest is written last, so a
directory carrying one is a complete backup -- and pruning only
considers those, so a run interrupted mid-copy cannot evict a good
backup by being newer than it. Three are kept. uninstall keeps them and
names them in its report; --purge removes them, alongside the config,
the database and the cached patch set. doctor reports the newest.
Restoring stays printed rather than done, as the uninstall report is:
the installer cannot know what has changed since, and putting an old
.cs file back over a newer overlay eats work rather than saving it.
Verified live against two scratch ServUO trees built from the real 57.4
files: a clean first install leaving no backups directory at all, an
update after editing a deployed .cs (copy holds the edit, tree gets the
release's file, manifest lists both it and sidecar.toml), a no-op update
taking none, --no-backup and --verify each taking none, a fourth backup
pruning the oldest, doctor's row, uninstall keeping three and listing
them, --purge removing them, and a --patches run capturing the
pre-patch Logging.cs while the two rung-0 patches correctly captured
nothing. fmt, clippy -D warnings and 144 tests on both Linux and
Windows.
Co-Authored-By: Claude <noreply@anthropic.com>