Files
felhom.eu/documentation/audits/pg-last-six-2026-09-30
…
..
…
…
…
…
…
…
…

The last six PostgreSQL apps, by day (2026-09-30)

Brief: the 2026-09-30 day brief (Parts 0, A–F). Architecture read first: architecture/09-update-architecture.md §3 (decisions 16, 35, 37–39, 42–43), §6.4 parts 7 and 10, §6.4.2, §6.5; 07-backup-architecture.md §6.1. Baselines (verified live 12:00): controller d48da6c v0.283.1 · agent d766666 v0.138.0 · felhom.eu 2de56ce · catalog 6446197. No controller, agent or hub release in this session.

Part 0 — Tester-2 (read only, hub GET /configs + GET /hosts, P0/)

  • The customer record Tester-2 (sajatfelhom.hu) exists, its config is v0.283.1 MANAGED.
  • No box has registered: status and version read —, and /hosts lists no Tester-2 host.
  • So no apps and no app_update.unattended value exist yet to read.

Part A — the upstream table (A1, read 2026-09-30; raw notes and URLs in A1/upstream-notes.md)

Rule (decision 42): the newer major only when the app's own upstream runs it; else the newest major its stack documents.

app pinned app pinned engine upstream engine (pinned tag / newest release) documented range outcome reason EOL of the major it is on after today
outline 1.9.1 postgres:16-alpine docs self-host compose: postgres:18 at /var/lib/postgresql (the repo's own compose is dev-only) / v1.10.1 same PostgreSQL 14+ → 18, moved upstream runs 18 18: 2030-11-14
rallly 4.11.1 postgres:16-alpine postgres:18-alpine at /var/lib/postgresql (v4.11.1 compose) / v4.15.3 same 18 for fresh installs (rallly-selfhosted README) → 18, moved upstream runs 18 at the pinned tag 2030-11-14
sparkyfitness v0.17.3 postgres:15-alpine postgres:18.3-alpine at /var/lib/postgresql (v0.17.3 docker-compose.prod.yml) / v1.7.3 same upstream guide "PostgreSQL Upgrade (15 to 18.3)" → 18, moved upstream pairs this very tag with 18 2030-11-14
zipline 4.6.1 postgres:16-alpine postgres:16 / v4.8.0 postgres:16 only "PG 14 supported until 2026-11-12"; nothing on 17/18 stay 16 upstream runs the same major 16: 2028-11-09
adventurelog v0.13.0 (= newest) postgis/postgis:16-3.5-alpine postgis/postgis:16-3.5 / same not documented (Django 5.2.13, psycopg2) stay 16 upstream runs the same major 2028-11-09
immich v3.2.2 …/postgres:16-vectorchord0.4.3-pgvectors0.2.0 …/postgres:14-vectorchord0.4.3-pgvectors0.2.0 / v3.2.4, v3.3.0-rc.0 same >= 14, < 20 stay 16 upstream runs an OLDER major (14) than ours 2028-11-09

A2 (the special images), measured from the registries and upstream source — no build, both stay:

  • immich: the only PostgreSQL 18 images carry VectorChord 0.5.3+ and no pgvecto.rs; PostgreSQL 17 carries only pgvecto.rs 0.3.0. So any major move of ours would also swap an extension version → the stop rule would apply. It does not arise: upstream runs 14, so the rule says stay. Recorded in R-463.
  • adventurelog (PostGIS): every candidate tag is PostGIS 3.x; a dump/load is PostGIS's own "hard upgrade" (the dump carries CREATE EXTENSION postgis, no postgis_extensions_upgrade() needed). Moot: stay 16.

Part A — per-app outcome (the part-10 method: bench → 9202 → --write-ladder → one commit)

app bench (LXC 9401, harness v4) box 9202 (controller 0.283.1, the guarded Update) undo case on 9202 (the load fails: adminpack) memory (anon peak, 10 min) catalog
rallly converted 21.4 s (dump 0.54 s / 92 kB, load 1.05 s), 31 tables equal, poll read back CONVERTED 16 → 18 in 7.1 s (2 dbs, 31 tables, 138 rows equal), done 32.9 s, poll read back undone in 57.5 s, back on 16, poll read back app 61.6 %, db 2.1 % 25ffd89
outline converted 26.7 s (dump 0.58 s / 128 kB, load 1.68 s), 42 tables equal, document read back CONVERTED 16 → 18 in 7.9 s (2 dbs, 42 tables, 312 rows equal), done 41.1 s, document read back undone in 57.5 s, back on 16, document read back app 48.9 %, db 5.4 % aeb0cd6
sparkyfitness converted 13.3 s (dump 0.69 s / 378 kB, load 3.99 s), 94 tables equal, weight read back CONVERTED 15 → 18 in 9.8 s (2 dbs, 94 tables, 261 rows equal), done 58.5 s, weight read back (after a reinstall at 15) undone in 74.9 s, back on 15, weight read back server 31.3 %, db 1.8 % 1666572

No step is memory_tight; no limit moved; no per-box cost. Evidence: bench/apps/<app>/bench/, box/<app>/{prep,move,undo,undo-setup}.txt, box/<app>/{box-verdict,undo-verdict}-*.json. Fixtures: catalog e6f3ec2. The engine gate printed ALLOWED for all three on push.

Seed routes — all three are the app's own front door; decision 52 was NOT needed and is not recorded: sparkyfitness (better-auth sign-up + a check-in), outline (installation.create, its self-hosted first-run route, + an API key + a document), rallly (sign-up, then the six-digit e-mail code READ from its own verifications row in place of a mailbox, verify-email, polls.make). Negative control on every read-back.

Part B — the demo boxes

Neither demo box has rallly, outline or sparkyfitness installed (demo-hp 9201: adventurelog, bentopdf, bookstack, calibre-web, docmost, kimai, opengist, paperless-ngx, privatebin, romm; demo-felhom: opengist). Nothing installed for this. Part F's moves (bookstack, kimai) ARE on demo-hp: their conversion-free steps ran through the chain press of Part C — see C/.

Part C, Part D, Part E, Part F — see C/README.md, ../catalog-currency-2026-09-30.md, E/, F/.