CHANGELOG + REPORT: MARIADB_AUTO_UPGRADE on four db services, engine-major gate, harness verdicts
gates / gates (push) Successful in 0s
gates / gates (push) Successful in 0s
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -1,3 +1,40 @@
|
||||
## MariaDB finishes its own conversion — `MARIADB_AUTO_UPGRADE=1` on four db services, and an engine-major gate (2026-09-13, R-459 / R-469)
|
||||
|
||||
**Templates changed: bookstack, kimai, nextcloud, romm — the db service's `environment:` list only.
|
||||
No `image:` line moved, so `catalog_since` does NOT move** (the rule ties it to an image change).
|
||||
|
||||
**The ruling** (operator, 2026-09-13, on `SPIKE-r459-mariadb-upgrade-2026-09-06.md`): an unconverted
|
||||
MariaDB datadir is stable but never heals — the engine says `Check required!` on every start forever —
|
||||
and the conversion costs ~7 s and takes its own system-table backup first. So every `mariadb:` sidecar
|
||||
now carries `MARIADB_AUTO_UPGRADE=1`; `MARIADB_DISABLE_UPGRADE_BACKUP` stays unset — that backup is the
|
||||
precaution. The setting is inert until an engine major actually moves.
|
||||
|
||||
**Proven by the harness before it shipped** (throwaway LXC 9403 on demo-hp, destroyed after;
|
||||
evidence `felhom.eu/documentation/audits/r459-close-2026-09-13/harness/`):
|
||||
|
||||
| edge | verdict | the engine's own view AFTER (`engine_state_after`) |
|
||||
|---|---|---|
|
||||
| C3 (negative control) | **`failed`** — the harness still says no | — |
|
||||
| E3 (app + engine 11.6 → 12.3) | `proven`, readback after = true | `12.3.3-MariaDB \| This installation of MariaDB is already upgraded to 12.3.3-MariaDB. There is no need to run mariadb-upgrade again. [exit=1]` |
|
||||
| E3b (engine half alone) | `proven`, readback after = true | same |
|
||||
|
||||
The entrypoint, verbatim: `Backing up system database to system_mysql_backup_11.6.2-MariaDB.sql.zst`
|
||||
→ `Starting mariadb-upgrade` → `Finished mariadb-upgrade` (6 s). `skipped due to $MARIADB_AUTO_UPGRADE`
|
||||
appears **0** times in either TO log — it appeared on every start before this change. The abort still
|
||||
starts and serves (spike §5.3), and the abort log still prints `MariaDB upgrade not required`, which
|
||||
is the R-464 trap and not a soundness claim.
|
||||
|
||||
**And a rule with a gate, because the Update button still takes no backup** (R-448 not shipped):
|
||||
*until Slice 4 ships, no template may move a database-engine image across a MAJOR version* — four
|
||||
MariaDB, eleven PostgreSQL services, found by image name. `scripts/check-engine-major.py` is the
|
||||
fourth row of `catalog_gates.py` (`--fast`, git reads only); `.githooks/pre-push` now hands it the
|
||||
push range. **It needs a parent commit and CI fetches at `--depth 1`** (the R-452 gap, not re-filed),
|
||||
so on a shallow clone the runner skips it out loud; the hook is where it bites. Red-proof
|
||||
(`scripts/test_gate_decoys.py`, 7 cases): `mariadb:11.6 → 12.3` and `postgres:16 → 17` REFUSED naming
|
||||
the rule and its expiry; `11.6 → 11.8` passes; the version moving only in a comment, in kimai's
|
||||
`serverVersion=` env, in README, or on the app's own image passes. The rule's removal is tracked as
|
||||
`felhom.eu` R-469 so it is a deliberate act, not a lapse.
|
||||
|
||||
## upgrade-test.py records the ENGINE's own view of itself (2026-09-06, R-459) — NOT A RELEASE
|
||||
|
||||
**Scripts only. No template changed, and deliberately so** — nothing with `MARIADB_` in it is
|
||||
|
||||
@@ -1,56 +1,51 @@
|
||||
# REPORT — `catalog_since` backfill (2026-09-02)
|
||||
# REPORT — MariaDB finishes its own conversion, and the engine-major gate (2026-09-13)
|
||||
|
||||
*Overwritten each run. This records the most recent implementation only.*
|
||||
*Overwritten each run. This records the most recent implementation only. The full run — golden bake,
|
||||
the golden waiver, the live observation on demo-hp — is in `felhom.eu/REPORT.md`.*
|
||||
|
||||
## What was done
|
||||
## What changed in this repo
|
||||
|
||||
One new optional key, `catalog_since`, in all **53** `.felhom.yml` files, plus the rule that keeps it
|
||||
true in `CLAUDE.md`. **No `docker-compose.yml` was touched and no image pin moved.**
|
||||
- `templates/{bookstack,kimai,nextcloud,romm}/docker-compose.yml` — `MARIADB_AUTO_UPGRADE=1` on the db
|
||||
service, with a comment pointing at the spike. **No image line moved; `catalog_since` untouched.**
|
||||
- `scripts/check-engine-major.py` (new) — refuses a `mariadb:`/`postgres:` pin that crosses a major
|
||||
between the two ends of a push range. Exit 0 / 1 REFUSED / 2 INCONCLUSIVE.
|
||||
- `scripts/catalog_gates.py` — fourth row, `--fast`, `--range=` passthrough, announced skip on a shallow
|
||||
clone. `scripts/test_catalog_gates.py` pins the table and the skip (7 tests green).
|
||||
- `scripts/test_gate_decoys.py` (new) — the `COVERS` literal for `felhom.eu`'s decoy-coverage gate and
|
||||
seven cases (three facts refused / inconclusive, one genuine and three decoys passing).
|
||||
- `.githooks/pre-push` — computes `--range=<remote sha>..<local sha>` from git's stdin refs.
|
||||
- `CLAUDE.md` — the engine-major rule with its expiry condition (R-448 → remove, tracked as R-469).
|
||||
- `REUSE.md` — one convention row for the MariaDB sidecar env; the gates row now lists four.
|
||||
|
||||
This is slice 2 of the update arc opened by
|
||||
`felhom.eu/documentation/audits/SPIKE-app-update-2026-09-01.md`. The consumer is felhom-controller
|
||||
**v0.233.0**, which renders one Hungarian badge from it — *"Naprakész"* or
|
||||
*"Frissítés elérhető — N napja"*. **No version number reaches the customer**, by operator ruling.
|
||||
## Harness verdicts (Scenario A and B) — engine-state field quoted
|
||||
|
||||
## Baseline
|
||||
| edge | verdict | `engine_state_after.bookstack-db.answer` |
|
||||
|---|---|---|
|
||||
| C3 | `failed` (negative control intact) | — |
|
||||
| E3 | `proven` | `12.3.3-MariaDB \| This installation of MariaDB is already upgraded to 12.3.3-MariaDB. There is no need to run mariadb-upgrade again. [exit=1]` |
|
||||
| E3b | `proven` | same |
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| repo at start | `5d8f25f61189` — matched the task's stated baseline, had not moved |
|
||||
| commit pushed | `69761cf91bfc` |
|
||||
`skipped due to $MARIADB_AUTO_UPGRADE`: **0** lines in both TO logs. Conversion lines, verbatim:
|
||||
`[Entrypoint]: Starting mariadb-upgrade` at 09:53:20 → `Finished mariadb-upgrade` at 09:53:26 (E3).
|
||||
|
||||
## How the dates were derived
|
||||
## Gate texts (Scenario D)
|
||||
|
||||
A throwaway script walked each app's `templates/<app>/docker-compose.yml` history newest→oldest and
|
||||
took the newest commit whose **set of `image:` values differs from its parent's**. A YAML parse, not a
|
||||
line scan.
|
||||
Refusal, verbatim (from the red-proof on a scratch clone):
|
||||
|
||||
**Two commits excluded by hash:** `214d448` and `30bd892` — the bentopdf pin move and its same-hour
|
||||
revert. This repo's own CHANGELOG records them as a spike measurement, not a release; counting them
|
||||
would date bentopdf 2026-09-02 for a pin that has not moved since `71828a8` (2026-07-12).
|
||||
```
|
||||
ENGINE-MAJOR GATE FAILED: templates/kimai/docker-compose.yml service kimai-db moves mariadb 11 -> 12 (mariadb:11.6 -> mariadb:12.3).
|
||||
RULE (app-catalog CLAUDE.md, operator ruling 2026-09-13): until the Update button takes a VERIFIED BACKUP as its precondition (Slice 4, felhom.eu OPEN-ITEMS.md R-448), no template may move a database-engine image across a MAJOR version.
|
||||
EXPIRY: this rule is removed DELIBERATELY when R-448 ships — the removal is its own register row, not a silent edit. Until then, keep the engine within its major.
|
||||
```
|
||||
|
||||
**Verification.** The four multi-major anchors from the spike all reproduced exactly — nextcloud
|
||||
`5e2c1ae`, grafana `b789acc`, calcom `147cee7`, vikunja `3fa63cd`, all **2026-07-18**. Six further
|
||||
apps were re-checked against `git log` **by hand**: bentopdf, plex, crafty-controller, homebox,
|
||||
bookstack, wanderer. All six correct.
|
||||
Pass, verbatim (this push's own range, 4 compose files, 4 engine pins compared):
|
||||
|
||||
Range: **2026-02-15** (plex, still on the pin it was added with) to **2026-07-21**. Thirty-eight of 53
|
||||
sit on 2026-07-18, the catalog-wide bump.
|
||||
```
|
||||
engine-major gate OK — no database engine crosses a major version (rule: CLAUDE.md, until Slice 4 / R-448 ships)
|
||||
```
|
||||
|
||||
Every file was re-parsed with `yaml.safe_load` after the edit and the key read back — 53/53 clean.
|
||||
## Honest limits
|
||||
|
||||
## Gates
|
||||
|
||||
| gate | result |
|
||||
|---|---|
|
||||
| `image-pins` | **OK** (exit 0) |
|
||||
| `image-resolvable` | INCONCLUSIVE — Docker Hub throttled 6 of 65 unauthenticated manifest lookups. 59 verified, none dead. **Not caused by this change.** |
|
||||
| `volume-persistence` | INCONCLUSIVE — the prober refused to report because its own canary came back UNDETERMINED on this host. **Not caused by this change** (it needs a scratch Docker host). |
|
||||
|
||||
Entry point: `python3 scripts/catalog_gates.py`, overall exit **0**.
|
||||
|
||||
## Known gap, filed rather than left implicit
|
||||
|
||||
There is **no gate** asserting that a commit which changes an `image:` line also moves that app's
|
||||
`catalog_since`. The gates runner fetches at `--depth 1` and has no parent commit to diff against, so
|
||||
the gate needs a deeper fetch. Filed as a row in `felhom.eu/documentation/backlog/OPEN-ITEMS.md`.
|
||||
- **CI cannot run the engine-major gate yet** — `.gitea/workflows/gates.yml` fetches at `--depth 1`.
|
||||
The runner announces the skip; enforcement is the pre-push hook. Same gap as R-452, not re-filed.
|
||||
- The harness proves the DATABASE half of bookstack only (R-460); the file half needs a browser.
|
||||
|
||||
Reference in New Issue
Block a user