Test code only — no template changed and no image: line moved. The update night walked real within-a-major upstream edges on scratch guest 9202 through the product's own guarded Update, against a PRIVATE DRILL CATALOG; the live catalog was never touched. This brings the expensive half of that work — the seed routes — back into the harness so the same edges can be run here WITH their ABORT step, which the box deliberately does not offer (09 6.1: whether the old image starts on migrated data is per-app and unpredictable). - upgrade_fixtures.py: ActualBudget, Navidrome, AudiobookShelf, Vikunja. Each seeds through the app's OWN interface (R-156); each carries a negative control run on every verify(), so a readback that has broken into always succeeding fails instead of passing everything. - upgrade-test.py: edges U1..U7, all real upstream moves existing 2026-09-21 that this catalog has NOT made, each holding its database engine constant. - Limitations kept: Navidrome and AudiobookShelf seed the DATABASE half only, and say so. OWED, stated so it is not mistaken for done: the U1..U7 harness RUNS, and with them the per-app ABORT answers. The code is in; the runs are not. Gates: catalog_gates.py --fast — image-pins, engine-major, catalog-since, copy-i18n all OK. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2.3 KiB
REPORT — upgrade harness widened from the update night (2026-09-21)
Test code only. No template was changed; no image: line moved; git diff touches exactly
scripts/upgrade_fixtures.py and scripts/upgrade-test.py.
What was done
The update night (felhom.eu/documentation/audits/DRILL-update-night-2026-09-21.md) walked real
within-a-major upstream edges on scratch guest 9202 through the product's own guarded Update,
each app seeded and read back through its own front door, against a private drill catalog — the
live catalog was never touched. This commit brings the expensive half of that work (the seed routes)
back into the harness, so the same edges can also be run here with their ABORT step, which the
box deliberately does not offer.
- Four new fixtures:
ActualBudget,Navidrome,AudiobookShelf,Vikunja. Each seeds through the app's OWN interface (R-156) and each carries a negative control that runs on everyverify(). - Seven new edges
U1–U7, all real upstream moves that existed on 2026-09-21 and that this catalog has NOT made. Every one holds its database engine constant.
What was proven, and where
Box-side, through the guarded Update, with the data read back before and after — evidence per app in
felhom.eu/documentation/audits/update-night-2026-09-21/apps/<app>/. The harness-side runs of
U1–U7 are owed: the code is in, the runs are not.
Gates
python3 scripts/catalog_gates.py --fast — image-pins OK, engine-major OK, catalog-since OK,
copy-i18n OK. all catalog gates OK, exit 0. The two slow gates need a container runtime and were
not run; no template changed, which is what they inspect.
A catalog defect found by the night, filed and NOT fixed here
Two apps are presented to the household as UNHEALTHY while working perfectly: tandoor's
.felhom.yml probe names port 8080 where the container listens only on 80, and zipline's names
/api/health where that app answers 404 — while the compose healthcheck in the same file uses
/api/healthcheck and is correct. A static sweep of all 53 templates comparing the two health
checks against each other finds both, plus wger and home-assistant as unmeasured candidates and
adventurelog as a false positive. Filed as R-618 with the proposed gate; deliberately not
fixed in the same commit as the harness change.