Files
felhom.eu/REPORT-day-2026-10-19.md
T

157 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# REPORT — day 2026-10-19
The operator answered the two STOPs in advance („YES to the agent and the hub release") and earlier: golden 0.331.0
vouched; D16 (one sign-in) yes; D17 „one per day, 3 days". No question was asked during the session.
## In plain words
- **Agent 0.160.0 runs on all three test hosts.** A new recovery code replaces the old one only after the household types
two of its words back; a broken-into box cannot flood the whole-box backups; the local copies are one per day for 3
days; an empty partition does not ask „data will be erased". **It is not vouched — that is yours.**
- **One sign-in for the file manager is live on every box** (controller 0.332.0, the floor). „Fájlok ↗" opens the app's
folder with no second login. A sign-out on the dashboard asks again. No app on the box can pretend to be the household.
- **Hub 0.159.0 is live.** A refused backup has its own alarm text. A reinstall over an old host record now mails you; it
does not re-issue the codes by itself (a security review stopped the first draft that did).
- **The preview error (R-1153) was a broken test file**, not the box.
- **The old backup program still reads demo-hp's off-site copies** after the first real clean-up with the new one.
## 1. Agent 0.160.0 (R-978, R-973, R-1093, R-1149, R-1151) — `audits/day-2026-10-19/P1/`
- **Content:** R-978 (an abandoned second ceremony keeps the first code), R-973 (the cadence cap: daily tier 3 per 24 h,
off-site 1 per 6 days), R-1093 (an empty partition is not data), **R-1149** (local tier `keep-daily=N`, operator D17),
**R-1151** (the package uploads only at `POST /escrow/ceremony/confirm` with two typed words; a claim without
`defer_upload` keeps the R-978 order, so an old controller still completes a ceremony). Commits `1b6e316`, `c11e3e2`,
`124164d` (CHANGELOG), `4545819` (two texts, after the release, unreleased). Released with `release-agent.sh`: sha256
`7ebb547f2b1ab93544ba828d3040351b60c4126327a5b85bbcb33f8f2b3dfca1`, bundle
`6b06090190ff609af1fe9842447ebf385fd52da4be382bc7ca708b558c8e202f`, round trip verified, tag `v0.160.0`.
- **Red-proofs:** keep-last for the primary → „primary tier prune = "keep-last=3"" and „holds 0 copies made before the
compromise"; the claim's defer flag ignored → „a code that was shown but never typed back replaced the package: code 1
no longer opens it (uploads=2)" (all three abandon paths); the word check skipped → „one wrong word: got 200".
- **demo-hp proof** (signed jobs 01:22 UTC, running 01:23, „update committed" 01:24; probe 75/75):
- a normal „Mentés most" of 9201: green, 6.9 GB in 443 s; yesterday's copy pruned (keep-daily=1, the same copy keep-last
would prune); the cap's history on disk holds both successes;
- escrow through the wizard's own calls: ceremony 1 — one wrong word 422, the right words 200; code 1 opens the hub's
package, code 0 is a kept earlier one (422, superseded at the confirm second 01:47:47). Ceremony 2 shown and abandoned —
code 1 still opens it (200), code 2 opens nothing (400). demo-hp's stored code is now code 1 (CC's secret store);
- R-1093 on the real route: a 64 MB RAM disk (`scsi_debug`, `/dev/sdb`), one empty GPT partition → `POST /disks/format`
→ 200 formatted, no confirmation; control: the same partition, now ext4 → 403 `needs_confirmation`. RAM disk removed.
**A loop device cannot be used:** the route and the probe accept only sd/nvme/vd/hd names (by design).
- **The answer:** the operator's „yes" (in advance). Tester 1 and demo-felhom took 0.160.0 by signed jobs (01:52 UTC →
01:54 / 01:55, probe 75/75, `keep-daily=3` armed on both); the hub's host rows read 0.160.0 for all three, and fresh
reports after the hub restart. **Old controller with the new agent:** pinned by `TestEscrowCeremony_R1151_OldControllerKeepsTheClaimOrder`; **new controller with agent 0.159.2:** pinned by `TestR1151_OldAgentClaimCompletesAtOnce` and the agentapi test — no host runs 0.159.2 any more, so not walked live.
## 2. One sign-in (R-1100) — `audits/day-2026-10-19/P2/`, `P4/05-*`, `P4/06-*`
- **Built** exactly the design note's recommendation (controller `9bdd8f8`, `601bdba`): the dashboard pass, the host-only
files cookie (derived from the session fingerprint, the R-976 shape), the per-box secret header name, the forwardAuth
answer; header user `felhom-household` with the household's file rights from userDefaults; `logoutRedirectUrl` = the
dashboard; `admin` stays a password user; the data tab's „asks for its own password" note only without the sign-in.
- **Tests, each red-proved:** replayed pass, expired pass, pass for another host (two guards: the host check and the
host-bound session key — red only with both removed), wrong X-Forwarded-Host, no session → no pass, signed out → asks
again (and after a password change), cross-site → no pass, dot-segments in `to`, the absolute redirect, the config
trusts only the secret name, the header user's rights, the route asks the controller and strips the header, the note.
- **Live, found and fixed before release:** on rc.2 the pass answer's relative redirect became
`http://felhom-controller:8080/files/` — traefik resolves a forwardAuth answer's Location against the auth server. Fixed
(absolute), red-proved, rc.3. A background security review then flagged CSRF and revocation: `/__files/open` now refuses
a cross-site request and dot-segments; the revocation residual is R-1155.
- **Live proof (rc.3, 9201, headless Chrome through the public names mapped to the box):** signed in → calibre-web's
„Fájlok ↗" → FileBrowser at `NVME 1TB/media/books`, no login form, user `felhom-household` (admin false, modify true,
login method proxy); signed out → `files.<domain>` went to the dashboard login. Screenshots `browser/01-…`, `02-…`,
`03-…`. Forged headers (`forged-headers.txt`): through traefik with no cookie — the old public name, a random name and the
REAL secret name all 401; from the bookstack container straight to `filebrowser:80` — the old name and a random name 401;
control: the real name from the same container 200 (the protection is the name's secrecy). The brief named Nextcloud;
bookstack was used (an app on 9201's network with curl).
## 3. Preview check (R-1153) — `audits/day-2026-10-19/P3/`
On 9202 (controller 0.331.0): OnlyOffice installed, the link on (FileBrowser back in 4 s). The hand-made `teszt.docx`
(912 bytes) → 500 „fitz: cannot open document"; OnlyOffice's own `sample.docx` → **200, a 256×256 JPEG, 0.3 s**. Same with
the link OFF. FileBrowser 1.5.6 previews .docx with its own MuPDF before OnlyOffice (`preview.go` `determinePreviewType`).
**Closed: not a product defect.** OnlyOffice removed through the product (both volumes gone), test files deleted.
## 4. Controller release 0.332.0 — `audits/day-2026-10-19/P4/`
Image `0.332.0` from `601bdba` (digest `sha256:245266a4…`), 03:16 UTC. Per-box floors 03:16:43 → Tester 1 and demo-felhom
on 0.332.0 at 03:16:45–55, demo-hp (from rc.3) at 03:17. Box walk on all three: 0 unhealthy, 0 allow-list refusals,
FileBrowser re-published 6 s after its re-create, public pages 200; https-only 28 OK, 0 failures, both controls right.
„Fájlok ↗" with no login through the public internet on demo-hp and Tester 1 (pass → cookie → `felhom-household`; a fresh
browser 401; sign-out → back to the dashboard). demo-felhom: CC holds no dashboard password for the lived-in box, so its
check is the files (secret 0600, config and route carry it) and the refusals (forged secret name through traefik 401, old
name from outside 401, a forged pass 403). **Global floor 0.332.0 / MinAgent 0.158.1 at 03:24:18 UTC**, read back with the
WAL; per-box floors cleared (read back empty). MinAgent 0.158.1 ≤ the vouched agent 0.159.2. i18n fixtures changed (named):
`escrow_first`, `escrow_receremony`; all others byte-identical. No golden (decision 250); the floor is above golden 0.331.0
until Sunday's bake.
## 5. Hub 0.159.0 (R-1150, R-1154) — `audits/day-2026-10-19/P5/`
- Written by a helper (`5121536f`, `b505ce4b`). **R-1154's rule, and why:** the helper's first draft re-issued the claim
code and the off-site provider password automatically when the old host was stale or switched off. A background
security review flagged it; the helper then read what the retrieval passphrase already grants (`/config` → the
controller API key; the enroll → the host key) and found the re-issues are the operator's session-only powers
(decision 252). So the passphrase must not reach them: **the reuse path re-issues nothing; when the old box looks gone it
mails the operator** („delete the old host and run the installer again, or re-issue …"), a live box gets an info record.
The operator's delete stays the gate. **R-1150:** `whole_guest_backup_refused` (operator-only, hub-origin; NOT in
`allowedEventTypes`, against the brief's wording — the suspected controller must not post or pre-empt it, R-895's
shape). Tests red-proved (helper's list in `hub/CHANGELOG.md`).
- **A push blocker on the way:** R-887's dated check was due today. Measured: 381 CI jobs since the S21 change, 0 lost (the
three re-runs' first attempts ran 47–49 s; control: the known lost attempt of 2026-10-10 ran 11 min 48 s and the attempt
count finds it). Closed.
- **Deploy:** image from a clean clone (the shared checkout held my uncommitted evidence), manifest `200ab653`, ArgoCD
synced the hub Deployment only (the only OutOfSync resource), Synced/Healthy, no ERROR, the floor read back, then fresh
reports from all three hosts (02:23–02:25 UTC) and all three controllers (02:29–02:31 UTC).
## 6. The old-restic check — `audits/evening-2026-10-18/P8/old-restic-check.txt`
The night watcher ran it: window 12 at 02:18 UTC removed 63 of demo-hp's 324 copies (→ 261); the old restic (0.14.0) and
the new (0.19.1) both list 261 and restore a 0.19.1-made copy and an August copy to identical content hashes. STATUS item
closed; `REPORT-evening-2026-10-18.md` §9 filled.
## 7. Versions, commits, fixtures, rows
- Agent **0.160.0** (released, not vouched) — `1b6e316`, `c11e3e2`, `124164d`, `4545819`. Controller **0.332.0** (floor) —
`ba4a6f0`, `9bdd8f8`, `601bdba`; rc.1–rc.3 on 9201 only. Hub **0.159.0** (deployed) — `5121536f`, `b505ce4b`, manifest
`200ab653`. felhom.eu `afc939bb` (R-887), `5622ce27`, this commit. Catalog: none.
- Fixtures: `escrow_first`, `escrow_receremony` (controller); no other page changed.
- **Register: 168 before, 166 after; closed 10** (R-887, R-978, R-973, R-1093, R-1149, R-1151, R-1100, R-1153, R-1150,
R-1154), **opened 8** (R-1155 … R-1162).
- `unproven.py --summary`: not walked 35 of 55 — unchanged. Capability map: not changed. System poster: text only — the
local whole-guest „Kept" cell („one copy per day, up to 3 days") edited in both the facts file and the drawing.
## Observations
1. FileBrowser's own 2-hour token can outlive the dashboard session if only the files cookie is lost. FILED: R-1155.
2. A reinstall within 45 min of the old box's last report reads „live" (no mail). FILED: R-1156.
3. Repeated cap refusals inside the 24 h hold raise no new alarm. FILED: R-1157.
4. The off-site leg of the clean-slate re-issue may be obsolete since hub v0.127.0. FILED: R-1158.
5. The retrieval passphrase yields the controller API key, which registers and confirms off-site keys. FILED: R-1159.
6. Hub and agent have no gofmt gate (~20 and 14 files drift). FILED: R-1160.
7. The escrow wizard calls the code „live" at the reveal; since R-1151 it is live only after the typed-back words.
FILED: R-1161.
8. R-973's off-site half (ep0 prunes by count) outlives the closed row. FILED: R-1162.
9. traefik resolves a forwardAuth answer's relative Location against the auth server. NOT-A-FINDING: found on rc.2 and
fixed before the release (red-proved); recorded as a rule in CONTEXT and memory.
10. The ceremony log line and two R-973 comments were stale. NOT-A-FINDING: fixed in agent `4545819` (the size rule).
11. My first OnlyOffice link call sent `{}` and switched the link off. NOT-A-FINDING: my call; the API wants
`{"enabled": true}`; it was already off, nothing restarted.
12. The R-1093 route refuses loop devices. NOT-A-FINDING: by design (only real disk names are allowed); a RAM disk was used.
13. CC holds no dashboard password for demo-felhom, so its „Fájlok ↗" was not walked as a household. NOT-A-FINDING: the
lived-in box's household password is not CC's (decision 254); its files and refusals were checked instead.
14. A helper's commits sat unpushed in the shared felhom.eu clone for ~40 minutes (blocked by R-887's due check).
NOT-A-FINDING: the gate did its job; pushed with my R-887 commit.
15. Two shell scripts of mine were refused by Claude Code's removal check (a cleanup `rm` it could not read behind
`bash -c`). NOT-A-FINDING: rewritten without the removal; nothing was deleted.
## Teardown — three layers
- **Machines:** 9202 — OnlyOffice removed through the product (volumes gone), test documents deleted; 9201 — on 0.332.0
(the floor); the escrow test left demo-hp on code 1 (stored); demo-hp host — the RAM disk module removed, helper scripts
deleted, no file left in `/root` (an older helper, `/root/opens.sh`, removed by name at the end). Cookie jars and
password files on DooPlex shredded or emptied. One debugging sign-in on demo-hp's dashboard (curl, 03:03 UTC) was not
signed out; its cookie file is shredded, so the session expires unused.
- **Hub:** global floor 0.332.0 / 0.158.1, no per-box floor; hub 0.159.0; no vouch.
- **DooPlex:** builds (agent, controller rc.1–3 + 0.332.0, hub 0.159.0 from a clean clone) and the hub deploy; no Docker
cleanup.
Architecture read: `01`, `02` „Logins and folders", `03` §8a, `04`, `05`, `07` §6/§6.1; the design note. Documents changed:
`02`, `03` §8a, `07` §6.1, the poster facts + drawing text, `05` §8 (helper). Instruction files: none changed.