From 9b706a018dacdf4fbc4c628f3062e62d70e335fd Mon Sep 17 00:00:00 2001 From: Peter Permenter <41281403+TusanHomichi@users.noreply.github.com> Date: Thu, 15 Oct 2026 21:16:40 -0700 Subject: [PATCH 1/6] docs(readme): list the five routes, their evidence, and what the VM tier proves The README still described two routes (12 and 25 fixes) and said kernels, bootloaders and reboots were untested. Five routes now pass their current version on every box, and the maintainer-run VM tier has taken four of them through real reboots (wend#13). The layout section also predates the Ubuntu adapter, the VM tier, the archive and most of tools/. Co-Authored-By: Claude Opus 5.5 Signed-off-by: Peter Permenter <41281403+TusanHomichi@users.noreply.github.com> --- README.md | 73 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index aaa52b9..858ae5b 100644 --- a/README.md +++ b/README.md @@ -9,17 +9,27 @@ machine, picks a route, and walks it. At each hop it applies the fixes whose pre a snapshot first, and rolls back if a check fails. The client uses no model and needs no network beyond your distro's mirrors. -Seed content: the dep-lab Debian results. 12 fixes take Debian 4.0 etch (2007) to Debian 13 trixie. Two very -different boxes, a PHP web server and a MySQL/BIND server, each made it with no model and no rollbacks in 13–15 -minutes, and ended with zero obsolete packages. - -Second route: CentOS 5.11 (2014) to AlmaLinux 10.2, crossing yum to dnf, the /usr merge, two package-manager -bootstraps and a vendor switch. 25 fixes take a web/MySQL box and a DNS/FTP box all the way, with no model, in about -10 minutes each (run files in `runs/el/`). Opus 5.5 found the path in all 5 of its dep-lab runs; replays are free. -Both routes are proven in chroots: userland only. Kernels, bootloaders and reboots are not covered yet. On the EL -route that includes boot-time services: CentOS 5's chkconfig settings don't carry over to systemd units, so after a -real reboot the services stay down until enabled by hand (the route's note lists them). Debian's packages enable -their own units on install. +Five routes so far. Every box below passes its route's current version from scratch, with no model: + +| Route | Fixes | Boxes | Runs | +|---|---|---|---| +| Debian 4.0 etch (2007) to Debian 13 trixie | 14 | `etch-web` (PHP web server), `etch-db` (MySQL/BIND) | CI | +| CentOS 5.11 (2014) to AlmaLinux 10 | 36 | `centos5-web` (web/MySQL), `centos5-dns` (DNS/FTP) | CI for `centos5-web`, local for `centos5-dns` | +| CentOS 7.9 to AlmaLinux 10 | 24 | `centos7-lamp`, `centos7-pyapp` (a Python 2.7 app on MariaDB) | local | +| CentOS 8.5 to AlmaLinux 10 | 20 | `centos8-lamp` | local | +| Ubuntu 14.04 trusty to 26.04 resolute | 8 | `trusty-web`, `trusty-web-updated`, `trusty-db` | local | + +CI runs are attested by the gate. Local runs were filed before that rule (CONTRIBUTING.md, "How runs land"), and CI +replays of the same routes will replace them. The Debian route began as the dep-lab results. The CentOS 5 route +crosses yum to dnf, the /usr merge, two package-manager bootstraps and a vendor switch; Opus 5.5 found the path in all +5 of its dep-lab runs, and replays are free. + +CI replays every route in a chroot, which proves the userland only. Kernels, bootloaders and the first real boot are +tested by the VM tier (`tools/vm.py`, SPEC.md "VM tier"), which the maintainer runs: each box is installed by its +release's own installer in a KVM guest, and every hop ends with a real reboot and the box's checks against the live +services. As of 2026-10-14 the Debian, Ubuntu, CentOS 5 and CentOS 7 routes have passed it from scratch on BIOS, and +the Ubuntu route also on UEFI; CentOS 8 has no VM run yet. The results are on [wend#13](https://github.com/FieldmouseWorks/wend/issues/13), +which stays open until the VM tier runs in CI. **Agents and contributors: start with [AGENTS.md](AGENTS.md).** Clone, plug in any model, discover a path, prove it with the same command CI runs, and open a PR. @@ -49,51 +59,56 @@ Every gap that gets closed makes the map work on one more kind of machine. ## Layout ``` -SPEC.md the format: fix, route, run, box, adapters, open questions +SPEC.md the format: fix, route, run, box, adapters, tiers, open questions AGENTS.md the playbook: claim, box, model, discover, self-review, verify, PR CLAUDE.md points at AGENTS.md CONTRIBUTING.md the five-layer PR gate, for humans and agents -wend the one command: check, list, replay, discover, verify, report +wend the one command: check, list, replay, discover, report, gaps, verify wanted.toml paths people want; claim them via their issue prompts/discover.md the exact question a model gets when a hop breaks NAMES.md why "wend" LICENSE-MIT, LICENSE-APACHE dual license adapters/ - debian.toml ladder, mirrors, how a hop runs, predicates, writable allowlist, adapter ops, checks - el.toml Enterprise Linux: CentOS 5 to AlmaLinux 10, the rpm backend, the mirror shim -fixes///.toml - debian/wheezy/purge-stale-libdb4.toml ...12 seed fixes - el/alma9/el8-transit.toml ...22 fixes for CentOS 5 -> AlmaLinux 10 -routes//-to-.toml - debian/etch-to-trixie.toml - el/centos5-to-alma10.toml + debian.toml, ubuntu.toml apt families: ladder, mirrors, how a hop runs, predicates, writable allowlist, ops, checks + el.toml Enterprise Linux: CentOS 5, 7 and 8 to AlmaLinux 10, the rpm backend, the mirror shim + drivers// each release's driver table (SPEC "Hardware preflight") + leapp/el/ AlmaLinux's leapp-data, vendored (SPEC "Package evolution data") +fixes///.toml 14 debian, 46 el, 8 ubuntu +routes//-to-.toml the five routes above boxes///box.toml CI fixtures, trusted test code, never shipped - debian/etch-web/ debian/etch-db/ - el/centos5-web/ el/centos5-dns/ runs////.json written by CI only: the gate refuses a run it didn't attest +archive/allowed_signers the archive's public signing key (docs/archive.md) tools/ check.py schema check, content ids, decoy check, --repin, --compile - backends.py what each typed op compiles to: apt (Debian) and rpm (EL) - mirror.py http -> https cache for EL boxes (CentOS 5's yum can't speak today's TLS) - test_check.py broken fixes the gate must refuse + backends.py what each typed op compiles to: apt (Debian, Ubuntu) and rpm (EL) + mirror.py http -> https cache for old boxes (CentOS 5's yum can't speak today's TLS; trusty's apt has no https) sandbox.py chroot boxes: build, snapshot, roll back, private /dev walk.py walk a route on a box (the map walk), write the run + vm.py the VM tier: replay a route on a real install in a KVM guest, a real reboot after every hop discover.py a hop broke: ask the model, check the answer like a PR, try it report.py a hop broke and you won't fix it: scrubbed gap report + prefilled issue link models.py bring your own model: anthropic, any OpenAI-compatible server, or the agent itself affected.py which routes and boxes a change must replay (CI matrix, ./wend verify) file_runs.py files CI's run artifacts + pesgaps.py, leappdata.py what leapp-data says changes at each EL hop, and its vendoring + hwdata.py, runtimes.py build the driver and runtime tables for hardware and runtime preflight + shelter.py, podman_standin.sh sheltering an app (SPEC "Sheltering an app"), chroot tier + net_*.py reference implementations of the network ops + archive.py, fetched.py, gate_fetched.py, r2push.py the archive: capture, store, publish (docs/archive.md) tomlw.py writes TOML (tomllib only reads) port_oldlinux.py one-off import of the dep-lab Debian results, with a lossless round-trip proof + test_*.py the tools' own tests; test_check.py holds the broken fixes the gate must refuse docs/validation/ the first end-to-end test: verify on both boxes, and Opus refilling a deleted fix docs/archive.md design: the wend archive (wend#19), every byte proven routes reference, by sha256 -client/ the Rust client (client/README.md): reads, checks and compiles the atlas exactly as - tools/ does (client/parity.py proves it). Next: walk a route, roll back on red. No AI. +docs/rebuild-and-carry.md design: moving a machine whose filesystem a later kernel can't mount (old-XFS CentOS 7) +client/ the Rust client (client/README.md): reads, checks and compiles the atlas exactly as tools/ + does (client/parity.py proves it), and walks a route on a root filesystem. It doesn't walk the running system yet: that + needs a snapshot backend. No AI. .github/ workflows/gate.yml the PR gate: dco, schema, plan, replay, decoys, claude-review workflows/client.yml the Rust client: build, test, parity with tools/ workflows/gaps.yml the gap loop: dedupe reports, triaged gap -> wanted.toml PR, ping the reporter on close - pull_request_template.md, ISSUE_TEMPLATE/route-gap.yml, ISSUE_TEMPLATE/wanted.md + pull_request_template.md, ISSUE_TEMPLATE/route-gap.yml, ISSUE_TEMPLATE/wanted.md, dependabot.yml CODEOWNERS a human on everything; the owner on tools/, adapters/, SPEC.md, .github/ ``` From 1820bd19a11c74095c3d1a5e8b9f48a4a3b1e2ce Mon Sep 17 00:00:00 2001 From: Peter Permenter <41281403+TusanHomichi@users.noreply.github.com> Date: Thu, 15 Oct 2026 21:28:22 -0700 Subject: [PATCH 2/6] docs(readme): name the VM-tier boxes, and stop saying every run came from CI Review of 9b706a0 found that centos8-lamp passed the VM tier (#92), that the VM results are per box rather than per route (#84 for UEFI), and that the intro and layout still said every run came from CI. The client line now includes preflight. Co-Authored-By: Claude Opus 5.5 Signed-off-by: Peter Permenter <41281403+TusanHomichi@users.noreply.github.com> --- README.md | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 858ae5b..bc59836 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Upgrade a 2007 server to today, one release at a time, along a path someone already proved works. This repo is **the map**: small, reviewed fixes for the places where a plain release upgrade breaks, and routes that -pin those fixes into release-to-release paths. Each route carries evidence (runs) that CI replayed it from scratch on +pin those fixes into release-to-release paths. Each route carries evidence (runs) that it was replayed from scratch on real test boxes and every health check stayed green. A client (a static Rust binary, later) fingerprints your machine, picks a route, and walks it. At each hop it applies the fixes whose preconditions hold on *your* box, takes a snapshot first, and rolls back if a check fails. The client uses no model and needs no network beyond your @@ -27,9 +27,11 @@ crosses yum to dnf, the /usr merge, two package-manager bootstraps and a vendor CI replays every route in a chroot, which proves the userland only. Kernels, bootloaders and the first real boot are tested by the VM tier (`tools/vm.py`, SPEC.md "VM tier"), which the maintainer runs: each box is installed by its release's own installer in a KVM guest, and every hop ends with a real reboot and the box's checks against the live -services. As of 2026-10-14 the Debian, Ubuntu, CentOS 5 and CentOS 7 routes have passed it from scratch on BIOS, and -the Ubuntu route also on UEFI; CentOS 8 has no VM run yet. The results are on [wend#13](https://github.com/FieldmouseWorks/wend/issues/13), -which stays open until the VM tier runs in CI. +services. As of 2026-10-14, at the route versions recorded there, these boxes have passed it from scratch on BIOS: +`etch-web`, `etch-db`, `trusty-db`, `trusty-web-updated`, `centos5-web`, `centos7-lamp` and `centos8-lamp`. All three +Ubuntu boxes have also passed on UEFI. The results are on [wend#13](https://github.com/FieldmouseWorks/wend/issues/13), +[#84](https://github.com/FieldmouseWorks/wend/pull/84) (UEFI) and [#92](https://github.com/FieldmouseWorks/wend/pull/92) +(CentOS 8); #13 stays open until the VM tier runs in CI. **Agents and contributors: start with [AGENTS.md](AGENTS.md).** Clone, plug in any model, discover a path, prove it with the same command CI runs, and open a PR. @@ -76,7 +78,7 @@ adapters/ fixes///.toml 14 debian, 46 el, 8 ubuntu routes//-to-.toml the five routes above boxes///box.toml CI fixtures, trusted test code, never shipped -runs////.json written by CI only: the gate refuses a run it didn't attest +runs////.json new runs land from CI only: the gate refuses a run it didn't attest archive/allowed_signers the archive's public signing key (docs/archive.md) tools/ check.py schema check, content ids, decoy check, --repin, --compile @@ -94,7 +96,7 @@ tools/ hwdata.py, runtimes.py build the driver and runtime tables for hardware and runtime preflight shelter.py, podman_standin.sh sheltering an app (SPEC "Sheltering an app"), chroot tier net_*.py reference implementations of the network ops - archive.py, fetched.py, gate_fetched.py, r2push.py the archive: capture, store, publish (docs/archive.md) + archive.py, fetched.py, gate_fetched.py, r2push.py the archive: capture, store, publish tomlw.py writes TOML (tomllib only reads) port_oldlinux.py one-off import of the dep-lab Debian results, with a lossless round-trip proof test_*.py the tools' own tests; test_check.py holds the broken fixes the gate must refuse @@ -102,8 +104,9 @@ docs/validation/ the first end-to-end test: verify on both boxes, and Opus r docs/archive.md design: the wend archive (wend#19), every byte proven routes reference, by sha256 docs/rebuild-and-carry.md design: moving a machine whose filesystem a later kernel can't mount (old-XFS CentOS 7) client/ the Rust client (client/README.md): reads, checks and compiles the atlas exactly as tools/ - does (client/parity.py proves it), and walks a route on a root filesystem. It doesn't walk the running system yet: that - needs a snapshot backend. No AI. + does (client/parity.py proves it), walks a route on a root filesystem, and runs hardware and + runtime preflight. Fetching by digest is the current slice. It doesn't walk the running + system yet: that needs a snapshot backend. No AI. .github/ workflows/gate.yml the PR gate: dco, schema, plan, replay, decoys, claude-review workflows/client.yml the Rust client: build, test, parity with tools/ From 3a10ef67f3a0bc598d23fcfa334e1286090205f7 Mon Sep 17 00:00:00 2001 From: Peter Permenter <41281403+TusanHomichi@users.noreply.github.com> Date: Thu, 15 Oct 2026 21:28:31 -0700 Subject: [PATCH 3/6] docs(readme): keep the mirror.py line within the file's wrap Co-Authored-By: Claude Opus 5.5 Signed-off-by: Peter Permenter <41281403+TusanHomichi@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bc59836..b02ccd6 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ archive/allowed_signers the archive's public signing key (docs tools/ check.py schema check, content ids, decoy check, --repin, --compile backends.py what each typed op compiles to: apt (Debian, Ubuntu) and rpm (EL) - mirror.py http -> https cache for old boxes (CentOS 5's yum can't speak today's TLS; trusty's apt has no https) + mirror.py http -> https cache for old boxes (CentOS 5's yum can't do today's TLS; trusty's apt lacks https) sandbox.py chroot boxes: build, snapshot, roll back, private /dev walk.py walk a route on a box (the map walk), write the run vm.py the VM tier: replay a route on a real install in a KVM guest, a real reboot after every hop From cb3471a45b29fd0474723dd0885bbf8c1a52a331 Mon Sep 17 00:00:00 2001 From: Peter Permenter <41281403+TusanHomichi@users.noreply.github.com> Date: Thu, 15 Oct 2026 21:30:24 -0700 Subject: [PATCH 4/6] docs(readme): CI replays the routes a change touches, not every route Co-Authored-By: Claude Opus 5.5 Signed-off-by: Peter Permenter <41281403+TusanHomichi@users.noreply.github.com> --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b02ccd6..b8f3230 100644 --- a/README.md +++ b/README.md @@ -24,8 +24,8 @@ replays of the same routes will replace them. The Debian route began as the dep- crosses yum to dnf, the /usr merge, two package-manager bootstraps and a vendor switch; Opus 5.5 found the path in all 5 of its dep-lab runs, and replays are free. -CI replays every route in a chroot, which proves the userland only. Kernels, bootloaders and the first real boot are -tested by the VM tier (`tools/vm.py`, SPEC.md "VM tier"), which the maintainer runs: each box is installed by its +CI replays a route in a chroot whenever a change touches it, which proves the userland only. Kernels, bootloaders and +the first real boot are tested by the VM tier (`tools/vm.py`, SPEC.md "VM tier"), which the maintainer runs: each box is installed by its release's own installer in a KVM guest, and every hop ends with a real reboot and the box's checks against the live services. As of 2026-10-14, at the route versions recorded there, these boxes have passed it from scratch on BIOS: `etch-web`, `etch-db`, `trusty-db`, `trusty-web-updated`, `centos5-web`, `centos7-lamp` and `centos8-lamp`. All three From 8f2f13bd59b9d4d4319a4522e0c0a9a309cd235e Mon Sep 17 00:00:00 2001 From: Peter Permenter <41281403+TusanHomichi@users.noreply.github.com> Date: Thu, 15 Oct 2026 21:30:31 -0700 Subject: [PATCH 5/6] docs(readme): rewrap the VM-tier paragraph Co-Authored-By: Claude Opus 5.5 Signed-off-by: Peter Permenter <41281403+TusanHomichi@users.noreply.github.com> --- README.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index b8f3230..2e19cb9 100644 --- a/README.md +++ b/README.md @@ -25,13 +25,14 @@ crosses yum to dnf, the /usr merge, two package-manager bootstraps and a vendor 5 of its dep-lab runs, and replays are free. CI replays a route in a chroot whenever a change touches it, which proves the userland only. Kernels, bootloaders and -the first real boot are tested by the VM tier (`tools/vm.py`, SPEC.md "VM tier"), which the maintainer runs: each box is installed by its -release's own installer in a KVM guest, and every hop ends with a real reboot and the box's checks against the live -services. As of 2026-10-14, at the route versions recorded there, these boxes have passed it from scratch on BIOS: -`etch-web`, `etch-db`, `trusty-db`, `trusty-web-updated`, `centos5-web`, `centos7-lamp` and `centos8-lamp`. All three -Ubuntu boxes have also passed on UEFI. The results are on [wend#13](https://github.com/FieldmouseWorks/wend/issues/13), -[#84](https://github.com/FieldmouseWorks/wend/pull/84) (UEFI) and [#92](https://github.com/FieldmouseWorks/wend/pull/92) -(CentOS 8); #13 stays open until the VM tier runs in CI. +the first real boot are tested by the VM tier (`tools/vm.py`, SPEC.md "VM tier"), which the maintainer runs: each box +is installed by its release's own installer in a KVM guest, and every hop ends with a real reboot and the box's +checks against the live services. As of 2026-10-14, at the route versions recorded there, these boxes have passed it +from scratch on BIOS: `etch-web`, `etch-db`, `trusty-db`, `trusty-web-updated`, `centos5-web`, `centos7-lamp` and +`centos8-lamp`. All three Ubuntu boxes have also passed on UEFI. The results are on +[wend#13](https://github.com/FieldmouseWorks/wend/issues/13), [#84](https://github.com/FieldmouseWorks/wend/pull/84) +(UEFI) and [#92](https://github.com/FieldmouseWorks/wend/pull/92) (CentOS 8); #13 stays open until the VM tier runs +in CI. **Agents and contributors: start with [AGENTS.md](AGENTS.md).** Clone, plug in any model, discover a path, prove it with the same command CI runs, and open a PR. From 80fbbe0ca635e878643d1df85d1ae6680e9b6df4 Mon Sep 17 00:00:00 2001 From: Peter Permenter <41281403+TusanHomichi@users.noreply.github.com> Date: Thu, 15 Oct 2026 21:33:47 -0700 Subject: [PATCH 6/6] docs(readme): drop a closing condition for #13 that SPEC rules out SPEC.md "VM tier" says it is maintainer-run only and never wired to a CI runner a pull request can trigger (Codex review of 8f2f13b). Co-Authored-By: Claude Opus 5.5 Signed-off-by: Peter Permenter <41281403+TusanHomichi@users.noreply.github.com> --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 2e19cb9..a9bdfb9 100644 --- a/README.md +++ b/README.md @@ -31,8 +31,7 @@ checks against the live services. As of 2026-10-14, at the route versions record from scratch on BIOS: `etch-web`, `etch-db`, `trusty-db`, `trusty-web-updated`, `centos5-web`, `centos7-lamp` and `centos8-lamp`. All three Ubuntu boxes have also passed on UEFI. The results are on [wend#13](https://github.com/FieldmouseWorks/wend/issues/13), [#84](https://github.com/FieldmouseWorks/wend/pull/84) -(UEFI) and [#92](https://github.com/FieldmouseWorks/wend/pull/92) (CentOS 8); #13 stays open until the VM tier runs -in CI. +(UEFI) and [#92](https://github.com/FieldmouseWorks/wend/pull/92) (CentOS 8). **Agents and contributors: start with [AGENTS.md](AGENTS.md).** Clone, plug in any model, discover a path, prove it with the same command CI runs, and open a PR.