Rulings 66 (licences) + 67 (userdata stays on remove, 07 §6.5); R-789..R-795 ruled, R-802 (lawyer review) opened; R-800 live proof on 9202 (0.288.0); floor 0.288.0; golden 0.288.0 baked + vouched
gates / gates (push) Successful in 29s

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
2026-10-02 14:16:41 +02:00
parent 2633dc1654
commit 5ed44ada6e
14 changed files with 618 additions and 6 deletions
+7 -6
View File
@@ -900,19 +900,20 @@ class (an image `VOLUME` at an unmounted path) is still live — `immich-server`
| **R-786** | **[P3-LOW] SparkyFitness's onboarding record has six open rows** (`app-catalog-felhom.eu/onboarding/sparkyfitness.md`): 0.5 runtime internet (food search providers), 0.7 the phone app's sign-in route through traefik, 1.6 the env names the server reads, 1.7 the entrypoint read, 5.4 a second memory watch at another limit, 8.3 no logo/screenshots on felhom.eu (404). Everything else measured this session (bench + 9202). **Needs:** each row measured, or n/a with a reason. | **READY — rank P3-LOW; owner: CC (catalog)** |
| **R-787** | **[P2-MEDIUM] No catalog app's LICENCE has been checked against Felhom being a paid service; the first look (SparkyFitness, R-784) found a non-commercial-only licence.** The new-app checklist row 0.1 binds apps opened from 2026-10-01; the 53 exempt apps were never read. **Needs:** a read of every template's licence at its pinned tag (SPDX + any custom terms), one table, and the non-open ones to the operator. **UPDATE 2026-10-02 — READ:** all 58 templates (56 published + Grimmory + MeTube), every image, at the pinned tag — one table: `audits/licences-2026-10-02/TABLE.md` (method in `read-1.md`, `read-2.md`). OSI-approved: all but the rows below. Not OSI / limiting, each now its own row: Tandoor (Commons Clause, R-789), Emby (R-790), n8n (R-791), Plex (R-792), the EE/BUSL parts of Cal.com, Docmost, Outline and meilisearch (R-793), redis 7.4 in seven apps (R-794), recipe-importer has no licence file (R-795); SparkyFitness is R-784. Nothing was hidden or changed because of the read (the brief's rule). New apps carry their licence in record row 0.1. | **CLOSED 2026-10-02 — the read (decisions are R-784, R-789..R-795)** |
| **R-788** | **[P3-LOW] The volume-persistence gate reads an EMPTY declared volume as CLEAN — MeTube's `/state` passed while the app had written nothing there.** MEASURED 2026-10-02 on the bench (`audits/family-gate-2026-10-02/C-metube-bench/C2-volume-persistence-metube.txt`): "declared volume /state is EMPTY" → exit 0. The catalog's CLAUDE.md says an app that wrote nothing is UNDETERMINED (exit 2), never a pass. MeTube's real proof came from elsewhere (the history read back after a recreate and after a restore). **Needs:** the gate treats an empty declared volume as undecided, or the app gets an exerciser (MeTube: one `POST /add`); a decoy that is an app writing nothing. **UPDATE 2026-10-02:** part of the cause was R-801 (no port → no exercise at all); the catalog now also has `APP_EXERCISE` (MeTube: one `POST /add`). The empty-volume → CLEAN path itself is still to be checked. | **READY — rank P3-LOW; owner: CC** |
| **R-789** | **[P2-MEDIUM] Tandoor's licence is AGPL-3.0 WITH the Commons Clause: it forbids selling "a product or service whose value derives, entirely or substantially, from the functionality of the Software" — fees for hosting or support included.** READ 2026-10-02 at 2.6.15 (`audits/licences-2026-10-02/TABLE.md`). Felhom charges for installing and caring for the household's apps; whether that value comes "substantially" from Tandoor is the question. **Needs (operator):** keep (the fee is for the box, not Tandoor), hide for new installs, or ask the authors. Nothing changed meanwhile. | **WAITING-ON-OPERATOR — rank P2-MEDIUM; owner: operator** |
| **R-790** | **[P2-MEDIUM] Emby is proprietary: a personal, non-commercial, non-transferable licence.** READ 2026-10-02 (emby.media/terms.html; `audits/licences-2026-10-02/TABLE.md`). The household's private use fits; Felhom installs the official image from Emby (no copy distributed) as part of a paid service, a context the licence does not cover. Jellyfin (GPL) offers the same. **Needs (operator):** keep, hide, or ask Emby. | **WAITING-ON-OPERATOR — rank P2-MEDIUM; owner: operator** |
| **R-791** | **[P3-LOW] n8n's Sustainable Use License allows own internal or personal use, and distribution only free of charge for non-commercial purposes.** READ 2026-10-02 at 2.42.1 (`audits/licences-2026-10-02/TABLE.md`). The household's own use is allowed; Felhom pulling the unchanged official image onto the household's box is arguably not distributing — a grey zone. **Needs (operator):** keep (recommended reading) or ask n8n. | **WAITING-ON-OPERATOR — rank P3-LOW; owner: operator** |
| **R-792** | **[P3-LOW] Plex is proprietary (Plex Terms of Service): the HOUSEHOLD is the licensee under its own Plex account.** READ 2026-10-02 (the ToS page answered 403; quoted from a search snippet — `audits/licences-2026-10-02/TABLE.md`). Felhom gets no right and installs it as the household's agent; selling Plex or Plex Pass is not covered. **Needs (operator):** keep as is, or a page sentence that the Plex account is the household's own. | **WAITING-ON-OPERATOR — rank P3-LOW; owner: operator** |
| **R-789** | **[P2-MEDIUM] Tandoor's licence is AGPL-3.0 WITH the Commons Clause: it forbids selling "a product or service whose value derives, entirely or substantially, from the functionality of the Software" — fees for hosting or support included.** READ 2026-10-02 at 2.6.15 (`audits/licences-2026-10-02/TABLE.md`). Felhom charges for installing and caring for the household's apps; whether that value comes "substantially" from Tandoor is the question. **Needs (operator):** keep (the fee is for the box, not Tandoor), hide for new installs, or ask the authors. Nothing changed meanwhile. **RULED 2026-10-02 afternoon (`09` §3 decision 66):** treated like SparkyFitness — stays offered; the operator asks the authors for written permission; without it before the first paying customer Tandoor is hidden (`lifecycle: hidden`). STATUS "Before the first paying customer". | **WAITING-ON-OPERATOR — rank P2-MEDIUM; owner: operator (the request; trigger: first paying customer)** |
| **R-790** | **[P2-MEDIUM] Emby is proprietary: a personal, non-commercial, non-transferable licence.** READ 2026-10-02 (emby.media/terms.html; `audits/licences-2026-10-02/TABLE.md`). The household's private use fits; Felhom installs the official image from Emby (no copy distributed) as part of a paid service, a context the licence does not cover. Jellyfin (GPL) offers the same. **Needs (operator):** keep, hide, or ask Emby. **RULED 2026-10-02 afternoon (`09` §3 decision 66):** KEPT — the household is the licensee; Felhom installs the official, unchanged image. Part of the lawyer's review (R-802). | **CLOSED 2026-10-02 — operator ruling (kept)** |
| **R-791** | **[P3-LOW] n8n's Sustainable Use License allows own internal or personal use, and distribution only free of charge for non-commercial purposes.** READ 2026-10-02 at 2.42.1 (`audits/licences-2026-10-02/TABLE.md`). The household's own use is allowed; Felhom pulling the unchanged official image onto the household's box is arguably not distributing — a grey zone. **Needs (operator):** keep (recommended reading) or ask n8n. **RULED 2026-10-02 afternoon (`09` §3 decision 66):** KEPT — the household is the user; the official, unchanged image. Part of the lawyer's review (R-802). | **CLOSED 2026-10-02 — operator ruling (kept)** |
| **R-792** | **[P3-LOW] Plex is proprietary (Plex Terms of Service): the HOUSEHOLD is the licensee under its own Plex account.** READ 2026-10-02 (the ToS page answered 403; quoted from a search snippet — `audits/licences-2026-10-02/TABLE.md`). Felhom gets no right and installs it as the household's agent; selling Plex or Plex Pass is not covered. **Needs (operator):** keep as is, or a page sentence that the Plex account is the household's own. **RULED 2026-10-02 afternoon (`09` §3 decision 66):** KEPT — the household is the licensee under its own Plex account. Part of the lawyer's review (R-802). | **CLOSED 2026-10-02 — operator ruling (kept)** |
| **R-793** | **[P3-LOW] Enterprise / BUSL code ships inside four open images — Cal.com and Docmost (EE folders, off without a key), Outline (BUSL-1.1: no commercial "Document Service"), meilisearch v1.36 in Wanderer (EE modules).** READ 2026-10-02 (`audits/licences-2026-10-02/TABLE.md`). Each is fine as the catalog runs them: no EE key, the household's own Outline is not a Document Service, Wanderer uses plain search. **Watch:** never turn on an EE feature, never switch Karakeep's/Wanderer's meilisearch to the `-enterprise` image, and re-read on each major. | **WATCHING — rank P3-LOW; owner: CC** |
| **R-794** | **[P3-LOW] redis 7.4 (RSALv2 / SSPL, not OSI) runs as a private cache in seven apps: dawarich, docmost, immich, nextcloud, outline, paperless-ngx, romm.** READ 2026-10-02 (`audits/licences-2026-10-02/TABLE.md`). Read as permitted (a private cache only its app uses is not Redis offered as a service — inferred). Valkey (BSD-3) or redis 8 (AGPL option) removes the question. **Needs:** a ladder step per app to valkey or redis 8, through the harness — no hurry. | **READY — rank P3-LOW; owner: CC** |
| **R-795** | **[P3-LOW] recipe-importer, Felhom's own image, has no licence file.** READ 2026-10-02 (`audits/licences-2026-10-02/TABLE.md`): all rights reserved by default; its dependencies are permissive (inferred from requirements.txt). **Needs (operator):** pick a licence (or none, on purpose) and add the file. | **WAITING-ON-OPERATOR — rank P3-LOW; owner: operator** |
| **R-795** | **[P3-LOW] recipe-importer, Felhom's own image, has no licence file.** READ 2026-10-02 (`audits/licences-2026-10-02/TABLE.md`): all rights reserved by default; its dependencies are permissive (inferred from requirements.txt). **Needs (operator):** pick a licence (or none, on purpose) and add the file. **RULED 2026-10-02 afternoon (`09` §3 decision 66):** Felhom's own code — no action unless it is shared with anyone. | **CLOSED 2026-10-02 — operator ruling (no action unless shared)** |
| **R-796** | **[P3-LOW] MeTube's "send to MeTube" helpers (browser extensions, bookmarklets, phone apps) cannot work behind the family gate.** READ 2026-10-02 (`audits/family-gate-2026-10-02/B/metube-reads/reads-2026.09.29.txt`): they call `/add` from another site and carry no family login; the template sets no CORS origin and MeTube has NO exception by design (an exception on an app with no login would be an open door). The household pastes links in the page (first_steps). **Needs:** nothing unless households ask; a way would be a per-member token the gate accepts on `/add` only — a design question, not a fix. | **WATCHING — rank P3-LOW; owner: CC** |
| **R-797** | **[P3-LOW] `check-family-gate.py` rule 3 (a family_gate template needs a baked golden ≥ 0.287.0) is checked only where the felhom.eu sibling exists — CI's single clone cannot.** MEASURED 2026-10-02 (`audits/family-gate-2026-10-02/C-metube-bench/C3b-family-gate-with-sibling.txt`): without the sibling the gate printed NOT CHECKED and its summary read OK. The summary line now says "rule 3 … NOT CHECKED here". The pre-push hook (with the sibling) is where it bites. **Needs:** nothing more unless CI gets the sibling. | **WATCHING — rank P3-LOW; owner: CC** |
| **R-798** | **[P3-LOW] Grimmory's template sets `SWAGGER_ENABLED=false`, which v3.5.0 does not read (it reads `API_DOCS_ENABLED`, default false).** READ 2026-10-02 (`audits/family-gate-2026-10-02/B/grimmory-reads/upstream-v3.5.0.txt`). Harmless today — the API docs are off by default. **Needs:** remove the dead line or set the right name, on the next Grimmory step. | **READY — rank P3-LOW; owner: CC** |
| **R-799** | **[P3-LOW] The MeTube fixture's `POST /add` leaves out `download_type`, which upstream's validator lists as required.** MEASURED 2026-10-02 (`audits/family-gate-2026-10-02/C-metube-bench/`): both 2026.09.28 and .29 answered 200 and downloaded anyway. Fragile if a later tag enforces it. **Needs:** add `download_type: video` to the fixture with the next MeTube step. | **READY — rank P3-LOW; owner: CC** |
| **R-800** | **[P2-MEDIUM] "Delete your data from the hard drive" keeps the app's files in the household's userdata folder — and neither the dialog nor the result says so.** MEASURED 2026-10-02. On demo-hp (live catalog, `audits/family-gate-2026-10-02/B4/grimmory-demo.txt`, `metube-demo.txt`): remove WITH data removed Grimmory's database volume, appdata and backups but KEPT the uploaded EPUB in `userdata/media/grimmory`; for MeTube the dialog offers no data checkbox at all and the result says "the app stored no data of its own on a drive" while the downloaded video stays in `userdata/media/metube`. On 9202 "keeping data" answers `hdd_paths_preserved: []` for the same reason (`audits/family-gate-2026-10-02/B/box/life.txt`): the remove reads `${HDD_PATH}` binds only. The model behind it may be right — userdata is the household's own files (a shared `media/` tree must never go with one app) — but then the dialog must say the files stay and where. **Needs (operator):** keep userdata on remove (and say so on the dialog), or delete an app's OWN userdata subfolder when the household ticks the box. | **WAITING-ON-OPERATOR — rank P2-MEDIUM; owner: operator (the rule), CC (the dialog)** |
| **R-800** | **[P2-MEDIUM] "Delete your data from the hard drive" keeps the app's files in the household's userdata folder — and neither the dialog nor the result says so.** MEASURED 2026-10-02. On demo-hp (live catalog, `audits/family-gate-2026-10-02/B4/grimmory-demo.txt`, `metube-demo.txt`): remove WITH data removed Grimmory's database volume, appdata and backups but KEPT the uploaded EPUB in `userdata/media/grimmory`; for MeTube the dialog offers no data checkbox at all and the result says "the app stored no data of its own on a drive" while the downloaded video stays in `userdata/media/metube`. On 9202 "keeping data" answers `hdd_paths_preserved: []` for the same reason (`audits/family-gate-2026-10-02/B/box/life.txt`): the remove reads `${HDD_PATH}` binds only. The model behind it may be right — userdata is the household's own files (a shared `media/` tree must never go with one app) — but then the dialog must say the files stay and where. **Needs (operator):** keep userdata on remove (and say so on the dialog), or delete an app's OWN userdata subfolder when the household ticks the box. **RULED 2026-10-02 afternoon (`09` §3 decision 67, option A):** the household's userdata files stay on every remove; the dialog and the result say so and name the folder. Recorded in `07` §6.5. Built in the next controller release. | **READY — rank P2-MEDIUM; owner: CC (the dialog and the result text)** |
| **R-801** | **[P2-MEDIUM] The volume-persistence gate never sent a request to ANY app: it read the routed port from label VALUES while `docker compose config --format json` puts the port in the label NAME.** MEASURED 2026-10-02 on the bench (`audits/family-gate-2026-10-02/B/volume-persistence-metube-exerciser-diag.txt`: `"ports": []`, `"exercise": []` for MeTube; the label shape read on Compose 2.26.1). So every verdict since the gate exists came only from what an app writes at start by itself; the GET exercise and the deep second pass never ran. **Fixed in the catalog** (`routed_ports()`, key=value; unit tests, red-proofed: `audits/family-gate-2026-10-02/B/RP-R801-routed-ports.txt`). **Still owed:** a full re-sweep of all 58 templates on the bench with the fixed gate — an app whose data path is written only on a request may now read differently. | **READY — rank P2-MEDIUM; owner: CC (the re-sweep)** |
| **R-802** | **[P2-MEDIUM] A lawyer reviews the non-OSI licence list before the first paying customer.** Operator ruling 2026-10-02 (`09` §3 decision 66): Tandoor (R-789), SparkyFitness (R-784), Emby, n8n, Plex (kept — R-790..R-792), the EE/BUSL parts (R-793), redis 7.4 (R-794); the table is `audits/licences-2026-10-02/TABLE.md`. STATUS "Before the first paying customer". | **WAITING-ON-OPERATOR — rank P2-MEDIUM; owner: operator (trigger: first paying customer)** |
<!-- DUE-CHECKS-BEGIN — machine-readable. Parsed by scripts/due_checks_gate.py.
One row per dated check. The R-number must have a row above. Dates are UTC.