Files
felhom.eu/REPORT-family-gate-2026-10-02.md
T

6.3 KiB
Raw Permalink Blame History

REPORT — the family gate built; Grimmory and MeTube published; every app's licence read (2026-10-02)

Brief: "the family gate, built (controller + catalog), Grimmory and MeTube published behind it; every app's licence read; SparkyFitness's licence ruling recorded; one controller release and a golden bake". Architecture read: 01-topology-and-trust.md §5 (the family-gate paragraph is new), 09 §3 decisions 46, 47, 63, 64, 65. Evidence root: documentation/audits/family-gate-2026-10-02/.

Part State One line
A — the controller DONE v0.287.0: family members with own logins, a door per family app, anchored exceptions, the Család card. Exit items 1–5 live on 9202.
B — the catalog DONE Format + gate family-gate; Grimmory (4 e-reader exceptions) and MeTube (none) published (catalog 96829d0) with complete records; on 9202 and demo-hp through the product.
C — licences DONE 58 templates, every image, one table (audits/licences-2026-10-02/TABLE.md); short list in STATUS; nothing hidden or changed.
D — SparkyFitness DONE (not sent) Request drafted (audits/licences-2026-10-02/EMAIL-DRAFT-sparkyfitness.md); decision 65 + trigger in STATUS.
E — release DONE Floor 0.287.0 (min_agent 0.131.0), both demo boxes in ~25 s; golden 0.287.0 baked, round-tripped, vouched; currency gate OK. Phone test SKIPPED (operator not present).

Not stopped between sessions: Part A was proven live on 9202 before Part B started (A/items.txt).

Claims in the brief, checked

  • "The family session is separable with the existing cookie scheme" — right, with one addition: a separate cookie name (felhom_family) scoped to Path=/__family and a separate store; RequireAuth never reads it (test TestFamilyGate_MemberPassesButNeverTheDashboard, red-proof RP-F1; live: the member's cookies at /launcher → the dashboard login, also through the real internet).
  • "Grimmory's e-reader paths keep their own auth behind an exception" — right, measured per path as a stranger through the simulated tunnel: OPDS 401 (Grimmory's), Kobo made-up token 401, KOReader wrong key 401, Komga API 401; the right credentials 200; look-alikes (/api/v1/opdsx, /api/koreaderx, ../) → the gate.
  • "MeTube's websocket passes forwardAuth" — right: a member's upgrade → 101; a stranger's websocket and polling → 401.
  • "Whether n8n's licence limits paid services" — partly: own internal or personal use is allowed; providing it to others is allowed only free of charge for non-commercial purposes. Pulling the unchanged image onto the household's box is arguably not that — a grey zone, now an operator row (R-791).

Proof

  • Controller: suites green; red-proofs RP-F1..F7 (A/RP-F-family-gate-mutants.txt). Live (A/items.txt): a stranger 0 app answers of 36; members in; reset/remove/logout end access at the next request; a stranger's 7 guesses lock only the stranger; controller down → 500, never the app; the gate costs 0.49 ms. Through the real internet on demo-hp (B4/member-internet.txt): a member's browser → the family sign-in → MeTube; logout → refused; a stranger 401.
  • Catalog: catalog_gates.py grimmory and metube exit 0 on the bench, every gate OK (B/catalog-gates-*.txt). Decoys of the new gate seen red (B/family-gate-decoys-red.txt).
  • Stranger per exception (Grimmory): A/items.txt item 4; R-775 re-measured: 6 tries → the gate's 401, then the household signs in 200 — the 15-minute lock can no longer be aimed from outside.
  • 9202 lifecycle (B/box/): Grimmory step 3.4.1 → 3.5.0 behind the gate (58.5 s, book read back); MeTube fresh install (a stranger's 63 polls: 404 → 401, never the app), step .28 → .29 (34.9 s), night backup, remove keeping data, restore (64.8 s / 38.5 s), seeds read back, the gate files and the stranger's refusal back by themselves.
  • demo-hp, live catalog (B4/): both installed through the product, strangers 401 through the real internet and the LAN, removed with data; the apps were removed after (STATUS asks whether to keep them).

Found on the way (all register rows)

  • R-801 (P2, fixed in the catalog): the volume-persistence gate never sent a request to ANY app — it read the port from label values, the port is in the label name. Fixed (routed_ports()), red-proofed (B/RP-R801-routed-ports.txt). A re-sweep of all 58 templates is owed. Before the fix MeTube answered UNDETERMINED; after, CLEAN with its own download (B/volume-persistence-after-R801.txt).
  • R-800 (P2, operator): "remove with data" keeps an app's files in userdata, and the dialog does not say so.
  • R-788 (APP_EXERCISE), R-796 (MeTube's send-to helpers cannot pass the gate), R-797 (rule 3 not checkable in CI), R-798 (Grimmory's dead env line), R-799 (fixture field). Licence rows R-789..R-795.
  • Harness only (no row): box_walk cached "not gated" while an app had no router (fixed); Cloudflare refuses Python's user agent (error 1010) — a test client detail, the box was never reached.

Rows and gates

  • Register 422 → 436: closed R-767, R-780, R-787; updated R-775 (narrowed), R-784 (decided B, draft ready), R-788; opened R-788..R-801 (14).
  • Releases: controller v0.287.0 (one release). Catalog 96829d0 (+ the record amendment). Golden 0.287.0.
  • CI by head_sha: catalog 96829d0 → job 1201 success; felhom.eu e6d1ebd → 1200 success; controller 9821690 → 1199 success (all pushes of the session green).
  • unproven.py --summary: unchanged (not walked 35 of 55).

Teardown

  • 9202: both apps removed (keep-data remove; the harness removed its own test folders by hand — R-442 refuses with-data there); back on the live catalog (A/repoint-drill.txt controls); family members anna/bela remain on 9202's card (scratch box, harmless).
  • Bench 9401: rebuilt and destroyed four times; pct list 9201 + 9202 only; nvme-scratch back to its baseline.
  • demo-hp 9201: apps removed, test files removed by hand, the test member removed (B4/teardown.txt).
  • Hub: the floor and the artifact manifest changed on purpose; nothing else. Secrets: scratch files shredded at the end; evidence scanned for every secret value used (0 hits, positive control 1).