Closed R-1115, R-1111, R-1112, R-1113, R-1109, R-1110, R-1114, R-1096; opened R-1116 (decoy suites in the other runners), R-1117 (Immich/Nextcloud Redis volume, deferred). Controller 0.325.0 is the floor since 08:21 UTC. Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
11 KiB
REPORT — burndown 3 (2026-10-17): the translation gate's lost case, two limiters, family sessions, three small fixes, Redis
Written in ASD-STE100 Simplified Technical English. Brief: „burndown 3" (2026-10-17). Design read first:
architecture/04-control-plane-authorization.md (it had no section on the box's own password doors — added as §6.3),
07-backup-architecture.md (app classes, the nightly volume dump), 09-update-architecture.md (ladder format L2257–2263,
decision 4 L156, part 5 L2325, „frozen WHOLE" L2662). Evidence: documentation/audits/burndown-3-2026-10-17/.
Plain words first
- Everything in the brief is done. No STOP fired. Nothing waits on you.
- Controller 0.325.0 is the floor for every box since 08:21 UTC, after Tester 1, demo-hp and demo-felhom updated by themselves and passed the box walk.
- Five apps' Redis now saves snapshots. It was proven first on the scratch box, then switched on demo-hp. Every other box switches at the app's next start, normally the same night's backup. Tester 1 does not get it yet: it still follows the drill catalog (R-1022, waits on your word).
- Two findings came from live tests and were fixed before the release: the family list was converted only on the first family visit (now at start), and the off-site wizard said „Hibás jelszó." to English boxes too.
- One mistake of mine, fixed: my Samba test tool wrote the throwaway test-share password into its log. I removed it from the evidence, replaced the password before turning sharing off, and changed the tool to redact it.
1. Each part
| Part | Done | Note |
|---|---|---|
| 1 R-1115 | yes | the decoy moved; fixed; the decoy suite is now a gate (full run) |
| 2 R-1111 | yes | one limiter body for three doors, parallel tests red-proved |
| 3 R-1112, R-1113 | yes | fingerprints + conversion at start (found live); one household session |
| 4 R-1109, R-1110, R-1114 | yes | samba label; guard over 42 calls; one resolver for the sibling |
| 5 release | yes | 0.325.0, per-box floors, box walk, global floor, read back |
| 6 R-1096 | yes | 6a proof passed; 6b reading confirmed; 6c pushed and checked |
2. R-1115 — what moved
- The decoy moved, not the gate. Commit
326f846(R-1102, 2026-10-16) removed gokapi's Hungarian login line. The case appended an English login to gokapi, so the gate had nothing to compare and rightly said OK (rc 0). - Fixed side: the decoy. It now rewrites wger's existing English login in place (when the line is gone, the suite
stops, so it cannot pass on a lost premise again). New case: calibre-web
admin123→admin1234. Both: rc 1, token named. - Gate run time: the decoy suite takes 196 s (measured twice). So it joined
catalog_gates.py's full run asgate-decoys, not--fast. - Also found:
test_catalog_gates.pywas red on main since the night before (it counted 18 gates; 19 were registered — my miss last night). Fixed; now 21 with today's two. - Whole catalog after the fix: the copy gate says OK. No real template convicted.
3. R-1110 — each call site and its verdict (42 calls, P2-P4/r1110-census.txt)
| Calls | Where | Verdict |
|---|---|---|
| 14 | stacks/migrate.go (copy, verify, cleanup, size, validate, skip set) |
correct — j.SourceNS/j.TargetNS are set only by NamespaceRoot (accepted by name) |
| 4 + 3 | appbackup/paths.go, backup/appbackup_bridge.go |
correct — nsRoot parameters |
| 15 | backup/ capture, restore, tier-2, update guard, prune, kept load |
correct — nsRoot, sourceNsRoot or m.namespaceRoot(...) |
| 1 | api/router.go removeStack |
correct — nsRoot |
| 2 + 1 + 1 | backup/removed_units.go, offbox_placement.go, offbox.go |
correct — the loop variable came from namespaceRoot; renamed nsRoot |
| 1 | stacks/delete.go GetStackBackupData |
correct (its caller passes AppNamespaceRoot); parameter renamed drivePath → nsRoot |
| 1 | web/handlers.go appDetailsForPath |
correct only while the system drive is never a storage path — now through NamespaceRootFor (same path on an enrolled drive) |
No live defect. Red-proofs: the six named sites before the fix; a bare call inside package backup.
4. Redis (R-1096)
6a — the proof on 9202 (docmost, the throwaway). The new line reached the box through a catalog (the drill, copied into the box; no password on the box) and the dashboard's restart:
- 100/100 probe keys back;
aof_enabled:0,rdb_last_bgsave_status:ok;- Redis log: „Loading RDB … keys loaded: 133".
- Then the nightly volume dump, FLUSHALL (0 keys) and the backups page's restore: 100/100 back.
Damage:
- Old form, 64 zero bytes written into the AOF 400 bytes before its end: exit 1, „Bad file format reading the append only file … use ./redis-check-aof --fix". Control (undamaged copy): starts.
- New form on a full disk (1 MiB tmpfs): BGSAVE
err(„No space left on device"), the olddump.rdbbyte-identical (same sha256), and after a stop without saving Redis starts on it with 50 keys. - New form, a half-cut
dump.rdb: Redis also refuses to start („RDB ERROR DETECTED"). The write path never leaves one (temp file, then rename).
6b — the step-file reading, confirmed:
09L2259–2263: every step but the last has its own complete definition insteps/<to>.yml.09L2325: one press applies ONE step with its OWN definition; the last step is the current template.- Code:
stacks/ladder.go:152nextLadderStep,:110the step file path,stacks/pin.go:336advancePinTopins that file. - A frozen app gets nothing:
09L2662;sync/sync.go:545–546(pinned and equal → the catalog template, fixes flow; pinned and different → the stored definition, frozen whole). - Nothing says a step file must change with its final template.
check-test-record.pyrule 4 checks only that a step file names its step's images. Step files unchanged (romm 2, docmost 1, nextcloud 2, immich 2).
6c — the change (catalog 5d9450b, pushed 07:31 UTC). Boxes read from the hub right before the push:
- demo-hp: romm, docmost, paperless-ngx;
- Tester 1: paperless-ngx;
- demo-felhom: none of the five;
- scratch 9202 (not hub-reporting): paperless-ngx, immich.
Checks after the push:
- demo-hp 9201: sync, then the dashboard's restart of each app. All three run
--appendonly no,aof_enabled:0,rdb_last_bgsave_status:ok, and arerunning. Keys stayed: RomM 153→150, Docmost 54→58, paperless 2→4 (the apps add and drop their own keys). - 9202: the compose holds the new line; it switches at the next start.
- Tester 1: not reached. It syncs from a drill copy inside the box (R-1022); its paperless still runs AOF.
One finding for the record: sync alone does not restart a running app. The new line runs from the app's next start, which the nightly backup gives every app.
Also done:
- gate
redis-persistence(--fast, 9 decoy cases, red-proved); - a
07[DESIGN] paragraph; - the research file updated;
- R-1117 opened for the deferred volume removal.
5. Versions, commits, fixtures
- Controller 0.325.0 (MinAgent 0.158.1, no golden), built from
68af0e9.- Test builds: rc.1 (
94f4493), rc.2 (6ed2238, the family store opens at start). - Docs:
88aa65d. Census correction:85d60a1(no new image). - CI green: 1979, 1981, 1982.
- Test builds: rc.1 (
- Catalog:
33a4b3b(R-1115, CI 1977) and5d9450b(Redis, CI 1978). - felhom.eu:
0314b8e7(reuse_refs_check.py, R-1114, CI 1980), then this report's commit. - i18n: no page changed; every parity fixture byte-identical. The escrow fix reuses the existing key
login.msg.wrong_password(same Hungarian bytes). - Drill catalog repo (scratch):
9bad48a(its tree set to live main),daff3d2(docmost's Redis line, for 6a). - Release timeline:
- per-box floors 08:20:02 UTC;
- all three boxes on 0.325.0 by 08:20:16;
- box walk green (24 / 9 / 17 containers, none unhealthy; dashboards 200; https-only check OK);
- global floor 08:21:31 UTC (303
floor_set), read back fromhub.db+ WAL (integrity ok,0.325.0=0.158.1, no per-box floor) and from the hub's page.
Instruction file edit (allowed by §5): app-catalog-felhom.eu/CLAUDE.md L54–56.
- Before: „every gate except
image-resolvableandvolume-persistence". - After: the same, plus
gate-decoyswith its ~3 minutes. - Why: that gate is new today and is not in
--fast.
Poster: no fact on felhom-system-poster.facts.md changed.
6. Rows
Before 174. Opened 2 (R-1116, R-1117). Closed 8 (R-1115, R-1111, R-1112, R-1113, R-1109, R-1110, R-1114, R-1096).
After 168. R-1022 got one dated sentence (the drill repo's state). unproven.py: NOT WALKED 35 of 55, unchanged.
7. Observations
- The catalog's own runner test was red on main since 2026-10-16 night. NOT-A-FINDING: fixed today (count 18 → 21).
- The controller, agent and felhom.eu runners do not run their own decoy suites. FILED: R-1116
- The family store opened (and converted an old file) only on the first family request, so a box nobody visits through a family gate kept the old values. NOT-A-FINDING: found live on rc.1, fixed in 0.325.0 before release.
- The escrow re-auth answered a wrong password in Hungarian only. NOT-A-FINDING: fixed in 0.325.0 (small).
- A stacks test wrote the update journal into its package folder; the R-578 walk tripped on it once. NOT-A-FINDING: fixed (small); a probe run proved no other test does it.
- Through the dashboard a share rename already applied before R-1109 (delete and add each change the compose). NOT-A-FINDING: recorded in R-1109's close; the label covers a controller update that changes smb.conf alone.
- Sync alone does not restart a running app; a catalog fix runs from the app's next start. NOT-A-FINDING: by design (decision 4 keeps fixes flowing; the nightly backup restarts every app).
- Tester 1 did not take the Redis change. NOT-A-FINDING: it follows the drill catalog by your ruling (R-1022, note added).
- On 9202 a catalog URL change to the private drill repo made the clone fail and left the box with no templates until I pointed it back. NOT-A-FINDING: my own setting change on a scratch box; the running apps kept their definitions; the next good sync restored them.
- Immich and Nextcloud keep a Redis volume they do not need. FILED: R-1117
- My Samba tool logged the throwaway test-share password. NOT-A-FINDING: my tooling; scrubbed, the password replaced, the tool redacts now.
setup-gate.keysits besidefamily.json, so someone who reads the data folder could still forge a family app cookie. NOT-A-FINDING: reading that folder already gives every key of the box; R-1112 removed the one value that worked without a key.- The launcher asks for SVG logos that do not exist (404). NOT-A-FINDING: as last night — it falls back to the PNG.
8. Teardown (three layers)
- Machine:
- 9202: docmost removed through the product (no volume left), the catalog setting put back (live catalog, controller
restarted), the damage-test folder removed, no
r1096-*container left. 9202 now runs controller 0.324.0 → it was 0.314.0 before; I moved it to 0.324.0 by hand for the proof (it is set by hand on purpose,nodes.md). - 9201: MeTube removed through the product (its empty media folder removed by hand), sharing turned off, the test shares and their folder removed, the test password replaced first. 9201 runs 0.325.0.
- 9202: docmost removed through the product (no volume left), the catalog setting put back (live catalog, controller
restarted), the damage-test folder removed, no
- Host: nothing.
- Hub: per-box floors set and cleared; the global floor raised to 0.325.0 / MinAgent 0.158.1.