night 2026-09-13/14: first "be a customer" rotation (adventurelog) — 7 defects found, 13 rows closed
gates / gates (push) Successful in 18s

New runbooks/nightly-rotation.md; observations_gate.py reads every section
(R-471); target-selection.md names real paths (R-461); R-93 carries the
fact that drill-r50 is gone. Register: R-473/R-474/R-466/R-471/R-453/R-461
and v0.240.0's R-477/R-478/R-480/R-482/R-484/R-485/R-486 closed; R-481,
R-483, R-487, R-488, R-489 opened. 09 §6.1, 07 §6, CONTEXT, STATUS note.
Evidence: audits/nightly-2026-09-13-adventurelog/, audits/v0240-2026-09-13/.
This commit is contained in:
2026-09-13 19:38:00 +02:00
parent 681c3d6a6d
commit 5e8a82c3c4
37 changed files with 1067 additions and 76 deletions
+13
View File
@@ -264,3 +264,16 @@ Compressed here to title, shipping version, evidence, and the sentences that sta
| **R-470** | **Four controller CHANGELOG headers (v0.233.0–v0.236.0) carried no `MinAgent:` line, while the vouch and now the declared floor read it from the header.** Closed 2026-09-13 (`felhom-controller` `f946b0d`): the four headers backfilled with `**MinAgent: 0.129.0** (unchanged)` — v0.232.0's value, proven unchanged (no commit under `internal/agentapi` since 2026-09-01; highest `featureMinAgent` 0.129.0) — and `controller/scripts/minagent_header_gate.py` (fast, blocking) refuses a newest header without the line; a prose or code-span mention does not count (decoy; red-proof F). | **CLOSED 2026-09-13 — GATED** | full text: `git show 2f5d3af:documentation/backlog/OPEN-ITEMS.md` |
| **R-472** | **The golden cadence ruling and the hub's floor rule contradicted each other: a floor above the vouched golden delivered nothing.** Operator ruling 2026-09-13, hub **v0.112.0** (`f181efd`): a floor saved with the release's declared MinAgent is served above the golden under the same agent comparison; an undeclared one is still held and both forms refuse it (`floor_needs_min_agent`). Proven live: controller 0.239.0 reached demo-hp in 14 s and demo-felhom in 15 s from the save, hub `managed floor SERVED … from declared`. Evidence: `audits/rulings-r472-r475-2026-09-13/` 02, 03. **Reasoning kept:** *the manifest leads the floor inside the golden; above it, the release's own declared MinAgent does* (publish-train rule 1); a declaration binds to its exact floor. | **CLOSED 2026-09-13 — PROVEN-LIVE** | full text: `git show 2f5d3af:documentation/backlog/OPEN-ITEMS.md` |
| **R-475** | **The update precondition was Tier-2-only, so an app with no second-drive copy could not be updated.** Operator ruling 2026-09-13, controller **v0.239.0** (`b93c154`): the first fresh copy in the order Tier 2, Tier 1, Tier 3 (bounded, unreachable = absent + WARN); `backup_max_age` applies to the chosen tier; nothing anywhere → back up first; refused only when no copy and no backup can be taken; the hold names the tier; a Tier-2 failure in the pre-backup is a WARN. Proven live on demo-hp: nothing anywhere → backed up first (04), Tier 1 alone (05), held naming „saját meghajtó” (07), restored from „helyi” (08). Red-proof M (age only on Tier 2) fails. **Reasoning kept:** *first FRESH copy, not first copy* — a stale mirror must not force a backup while the own unit is minutes old. Follow-ups: R-477..R-480. | **CLOSED 2026-09-13 — PROVEN-LIVE** | full text: `git show 2f5d3af:documentation/backlog/OPEN-ITEMS.md` |
| **R-473** | **The `glance` catalog template crash-looped on every fresh install — the image ships no default config.** Closed 2026-09-13 (catalog `50ad286`): an `entrypoint` wrapper seeds a small Hungarian start page on first boot only when `/app/config/glance.yml` is absent, then execs the image's own command (read from the image, not guessed); the seed validated with the image's `config:validate`. Proven live on demo-hp the same evening: a fresh throwaway install healthy in 21 s, restart count 0, front door 200, seed present in the volume (`audits/nightly-2026-09-13-adventurelog/08-R473-glance-fresh-install.txt`). No version moved. | **CLOSED 2026-09-13 — PROVEN-LIVE** | full text: `git show 681c3d6:documentation/backlog/OPEN-ITEMS.md` |
| **R-471** | **`observations_gate.py` read only the FIRST observations section, so an appended second section with an unmarked item passed — and the R-419 decoy had been reading LIVE HOLE at HEAD.** Closed 2026-09-13 (felhom.eu `scripts/observations_gate.py`): `observation_sections` collects every observations heading and `observation_items` pools their items; the heading shown is all of them joined. Cause established: first-heading-wins (the parser `break`s on the first match). Red-proof: the old parser exits 0 on the decoy shape, the new one 1 (`audits/v0240-2026-09-13/rp-R471.txt`); all 12 felhom.eu decoys behave; the felhom.eu and controller REPORTs still pass through the shared script. The "run by hand" half stands: the decoy suite is still not in any runner (R-426's exemptions) — that is a separate row if wanted. | **CLOSED 2026-09-13 — GATED** | full text: `git show 681c3d6:documentation/backlog/OPEN-ITEMS.md` |
| **R-486** | **Removing an app with its backups KEPT forgot its Tier-2 record, so the second-drive restore was refused over an intact mirror.** Closed in controller **v0.240.0** (`bdcbd50`): the record goes only with `remove_backups`. Proven live on demo-hp: remove keeping backups → `cross_drive` record kept → „Teljes visszaállítás" restored 2 volumes and the database, data identical. Red-proof: an unconditional `SetCrossDriveConfig(nil)` fails the wiring test. `audits/v0240-2026-09-13/` (10-v0240-validation.txt; red-proofs rp-v240-*) | **CLOSED 2026-09-13 — PROVEN-LIVE** | full text: `git show 681c3d6:documentation/backlog/OPEN-ITEMS.md` |
| **R-484** | **PostGIS was not a database.** Closed in v0.240.0: `dbTypeForImage` matches `postgis`, `pgvector`, `timescaledb` as Postgres. Proven live: adventurelog's unit now carries `db-dumps/adventurelog-postgres.sql` (8 MB) and the unit restore reports „2 adatkötet és az adatbázis visszaállítva". Red-proof: dropping `postgis` fails the table test. Immich's own image already matched. `audits/v0240-2026-09-13/` (10-v0240-validation.txt; red-proofs rp-v240-*) | **CLOSED 2026-09-13 — PROVEN-LIVE** | full text: `git show 681c3d6:documentation/backlog/OPEN-ITEMS.md` |
| **R-485** | **The backup card read two dead paths and said `has_backups:false` over 484 MB.** Closed in v0.240.0: it sizes the recovery unit and the app's Tier-2 mirror(s). Proven live: `244M` + `244M`, `has_backups:true`. Red-proof: the old paths fail `TestR485`. `audits/v0240-2026-09-13/` (10-v0240-validation.txt; red-proofs rp-v240-*) | **CLOSED 2026-09-13 — PROVEN-LIVE** | full text: `git show 681c3d6:documentation/backlog/OPEN-ITEMS.md` |
| **R-480** | **The card kept a held update's „leállítva marad" sentence after a successful restore and after removal.** Closed in v0.240.0: the stack remembers its last update ended held; `fillHoldReason` hides that outcome once the hold is gone or the app is not deployed; a pull failure keeps its sentence. Red-proof: disabling the block fails three assertions. Live: the card after a restore reads clean. `audits/v0240-2026-09-13/` (10-v0240-validation.txt; red-proofs rp-v240-*) | **CLOSED 2026-09-13 — PROVEN-LIVE** | full text: `git show 681c3d6:documentation/backlog/OPEN-ITEMS.md` |
| **R-477** | **The update's Tier-3 lookup paid the full 15 s bound and blamed another app.** Closed in v0.240.0: `OffsiteSnapshotTimes` — one `snapshots --json`, no per-app `stats`; the inventory page and the update share `offsiteNewestPerTag` (registered read-only for R-408). Red-proof: routing the lookup through the inventory fails `TestR477`. `audits/v0240-2026-09-13/` (10-v0240-validation.txt; red-proofs rp-v240-*) | **CLOSED 2026-09-13 — GATED** | full text: `git show 681c3d6:documentation/backlog/OPEN-ITEMS.md` |
| **R-478** | **A unit left by a removed install counted as the reinstall's fresh copy.** Closed in v0.240.0: `usableRestorePoint` refuses a copy older than the app's `deployed_at`; R-474's fix removes such units anyway. Red-proof: dropping the check fails `TestR478`. `audits/v0240-2026-09-13/` (10-v0240-validation.txt; red-proofs rp-v240-*) | **CLOSED 2026-09-13 — GATED** | full text: `git show 681c3d6:documentation/backlog/OPEN-ITEMS.md` |
| **R-474** | **„Delete backups" deleted only `db-dumps`; the unit and the Tier-2 mirror survived; prefs stayed.** Closed in v0.240.0 for the backups half: the whole unit, every mirror (`Tier2MirrorDirsForApp` / `RemoveTier2Mirrors`, exact-path guarded) and the prefs go; `backup_paths_removed` lists them. Proven live: 244M + 243.6 MB removed, nothing left on either drive, prefs `None`. **The `volumes_removed: null` half is re-filed as R-489.** `audits/v0240-2026-09-13/` (10-v0240-validation.txt; red-proofs rp-v240-*) | **CLOSED 2026-09-13 — PROVEN-LIVE** | full text: `git show 681c3d6:documentation/backlog/OPEN-ITEMS.md` |
| **R-466** | **Removal with „Mentési adatok törlése" left the unit's `compose/` + `manifest.json`.** Subsumed by R-474's fix in v0.240.0 (the whole unit goes). Decided by the same change: the button means the WHOLE unit. `audits/v0240-2026-09-13/` (10-v0240-validation.txt; red-proofs rp-v240-*) | **CLOSED 2026-09-13 — GATED** | full text: `git show 681c3d6:documentation/backlog/OPEN-ITEMS.md` |
| **R-482** | **`adventurelog` ran Django with DEBUG=True on the public origin.** Closed in catalog `ed2c018`: `DEBUG=False` on the backend service. Proven live after the sync: the same CSRF failure renders the 300-byte production page, no debug text. `wger`, `tandoor`, `paperless-ngx` are recorded as unmeasured. `audits/v0240-2026-09-13/` (10-v0240-validation.txt; red-proofs rp-v240-*) | **CLOSED 2026-09-13 — PROVEN-LIVE** | full text: `git show 681c3d6:documentation/backlog/OPEN-ITEMS.md` |
| **R-453** | **`~/.config/credentials` values are single-quoted, and a half-applied strip produced a confidently wrong "password is stale" verdict — twice.** Closed 2026-09-13: the instrument the row asked for exists — `felhom.eu/scripts/read_credential.py KEY <0600-file>` (`66156c6`, 2026-08-31) — and the whole 2026-09-13 night used it for every controller and hub password with zero quoting incidents; the memory `credentials-file-values-are-quoted` now names it. The instrumentation lesson (a discriminator that rules out one alternative does not rule in the rest) stays in the memory. | **CLOSED 2026-09-13 — INSTRUMENTED** | full text: `git show 681c3d6:documentation/backlog/OPEN-ITEMS.md` |
| **R-461** | **`runbooks/target-selection.md` named a venue that does not exist and fenced a fixture that is gone.** Closed 2026-09-13, both halves checked against both boxes first: (a) no `/mnt/nvme-1tb` on demo-hp or demo-felhom; demo-hp's NVMe is `nvme0n1` at `/mnt/hdd_1` (demo-felhom's `/mnt/hdd_1` is `sdb`) — the runbook now names `/mnt/hdd_1` and says it is the same disk as the data drive; (b) `qm list` is empty on BOTH boxes — `drill-r50` (VM 300) exists nowhere; the fence text stays with the measured absence written beside it, and R-93 carries the fact. | **CLOSED 2026-09-13 — DOCUMENTED** | full text: `git show 681c3d6:documentation/backlog/OPEN-ITEMS.md` |