1749e73e50
gates / gates (push) Successful in 27s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
91 lines
7.2 KiB
Markdown
91 lines
7.2 KiB
Markdown
# REPORT — 2026-09-29 afternoon: the setup gate on the other 30 apps; "Done" asks the app first; open sign-up closed after the first admin; claper's password never in code
|
||
|
||
Architecture read first: `09` §3 decisions 45–47, `01-topology-and-trust.md` §5, `audits/login-gate-2026-09-29/B/B-VERDICT.md`,
|
||
`app-catalog-felhom.eu/FIRST-ADMIN.md`, rows R-707, R-711, R-713. Controller **v0.281.0** (one release). Floor 0.281.0;
|
||
both demo boxes run it. Catalog `6faf432`. Evidence: `documentation/audits/gate-rollout-2026-09-29/`
|
||
(0 = Part 0, A, B = per-app, C = sign-up, D = claper, redproofs).
|
||
|
||
## The Parts
|
||
|
||
| Part | Step | State | Note |
|
||
|---|---|---|---|
|
||
| — | decision 47 recorded first | done | `09` §3 + `01` §5 before any work |
|
||
| 0 | installed app never gated by a catalog change | done — **holds** | 9202: vikunja installed ungated and set up, then the drill catalog added `setup_gate: true`, synced, two loop ticks, a controller restart: still answered strangers, no gate file, no record (`0/P0-1`, `P0-2`). Code: the gate is set only in `DeployStack`. Pinned by `TestSignupBlock_NeverOnAnAppThisBoxDidNotGate` (RP23). After the live push, the demo boxes' installed class-4 apps (adventurelog, docmost, opengist, romm; opengist) got no gate and no block (`0/P0-3`) |
|
||
| A1 | "Done" asks the probe first | done | refuses while the app says not done and when it cannot be read (409 + the sentence). Live: zipline pressed before its setup → 409, twice (`A/`, `B/B2-zipline-probe-before.txt`) |
|
||
| A2 | confirm for an app without a probe | done | in-page `felhomConfirm` with the sentence (native confirm is banned by a gate) |
|
||
| A3 | tests + red-proofs | done | RP17, RP18 |
|
||
| B | the gate on the other 30 | done — **28 gated (25 fully proven, 3 opening not provable here), 2 not gated** | per-app table below |
|
||
| C1 | spike: how sign-up can be closed | done, **mechanism changed** | opengist, wishlist: only in their own admin settings; vikunja: an env, but then no way to add a user but its CLI. Chosen: a box-side block of the app's own sign-up address + a household 15-minute window (CC-unattended decision, `09` §3 decision 47) |
|
||
| C2 | per app | done | 11 apps let a stranger sign up after the setup → blocked and refused; 11 more refuse by themselves; window proven (gitea, calcom, vikunja) and closes again (gitea, calcom) |
|
||
| C3 | apps that cannot close sign-up | **1: wanderer** | not gated at all (R-714) — STATUS asks |
|
||
| D | R-713 | done | code-bound values refused; `${NAME|base64}`; claper proven live with a typed password holding `"` and `#{` (default refused, typed signs in). RP24 |
|
||
|
||
**Recommendation not followed, one line why (standing rule 4):** the ruling says "only the admin adds people, from the
|
||
app's own user page"; for apps with no such page (opengist, vikunja, termix, sparkyfitness, adventurelog) the page
|
||
says to open sign-up for 15 minutes instead — the only way a family member can join those apps at all.
|
||
|
||
### Part B / C — one row per app (9202, controller 0.281.0, drill catalog)
|
||
|
||
| app | gate proven (stranger refused · household reached setup · opened · answered after) | opened by | sign-up after the setup |
|
||
|---|---|---|---|
|
||
| actualbudget | yes | probe `data.bootstrapped` (M) | refused by the app |
|
||
| komga | yes | probe `isClaimed` (M) | refused by the app |
|
||
| jellyfin | yes | probe `StartupWizardCompleted` (M) | refused by the app |
|
||
| romm | yes | probe `SYSTEM.SHOW_SETUP_WIZARD` (M) | refused by the app |
|
||
| zipline | yes | probe `/api/server/public firstSetup` (M) | refused by the app (`userRegistration: false`) |
|
||
| termix | yes | probe `setup_required` (M) | **was open → blocked** |
|
||
| emby | yes | button | refused by the app |
|
||
| navidrome | yes | button (no JSON status) | refused by the app |
|
||
| ghost | yes | button (status is a list — R-715) | refused by the app |
|
||
| home-assistant | yes | button (status is a list — R-715) | refused by the app |
|
||
| gitea | yes | button | **was open → blocked** |
|
||
| docmost | yes | button | no public sign-up |
|
||
| calcom | yes | button | **was open (a stranger's account was created) → blocked** |
|
||
| tandoor | yes | button | "Sign Up Closed" by the app |
|
||
| gramps-web | yes | button (its status answers 405 — R-715) | answered 500 → blocked anyway |
|
||
| adventurelog | yes | button | **was open → blocked** |
|
||
| homebox | yes | button | **was open → blocked** |
|
||
| papra | yes | button | **was open → blocked** |
|
||
| sparkyfitness | yes | button | **was open → blocked** |
|
||
| vikunja | yes | button | **was open → blocked**; window let a family member in |
|
||
| opengist | yes | button | **was open → blocked** |
|
||
| wishlist | yes | button | **was open → blocked** |
|
||
| radarr, sonarr | yes | button | single user; their API key was public BEFORE the setup — the gate hides it |
|
||
| recipe-importer | yes | button | our own app, open until a password is set — the confirm says so |
|
||
| seerr | stranger refused, household reached setup | **opening not proven** (needs a media server) | not measured |
|
||
| outline | stranger refused, household reached setup | **opening not proven** (needs e-mail / SSO) | not measured |
|
||
| rallly | stranger refused, household reached setup | **opening not proven** (e-mail) | not measured |
|
||
| wanderer | **not gated** | — | open (R-714) |
|
||
| plant-it | not installable (`lifecycle: abandoned`); the template carries the gate | — | — |
|
||
|
||
## Claims in the brief that turned out wrong (or right), named
|
||
|
||
- **"A catalog change never gates an installed app"** — **right** (measured on 9202 and read on both demo boxes).
|
||
- **"14 of the 34 have a probe"** — **wrong**: 9 have a probe that works (3 from the morning, 6 today); 3 more have a
|
||
status the box cannot read (ghost, home-assistant — lists; gramps-web — 405, R-715); zipline's upstream route was
|
||
wrong (`/api/setup` answers 403 after the setup; `/api/server/public` works).
|
||
- **"The first admin is the first registered user on opengist and wishlist"** — **right** (measured: the household's
|
||
sign-up became the admin; after it, a stranger could still sign up).
|
||
- **"Each app in R-711's list can close sign-up"** — **wrong** as a per-app switch: opengist and wishlist keep it only
|
||
in their admin settings, vikunja only as a start-up env; and wanderer cannot be closed at all today. The box-side
|
||
block closes all but wanderer.
|
||
- **"An env switch needs a restart"** — **right** for vikunja (read at start); not used — the block needs no restart.
|
||
- **"Register 346 rows"** — was **350** at the start of this session (the morning session ended at 350).
|
||
|
||
## Also found
|
||
|
||
- A probe that never flips blocks the household's press (fail closed; measured on gramps-web) → R-715.
|
||
- calcom created a stranger's account after the setup (measured) — closed.
|
||
- Apps installed before today keep their open sign-up (demo boxes only) → R-716, needs an operator word.
|
||
|
||
## Rows
|
||
|
||
Closed: R-707, R-711, R-713. Opened: R-714 (wanderer), R-715 (probe shapes), R-716 (installed apps' sign-up, operator).
|
||
**Register 350 → 353 rows.**
|
||
|
||
## Teardown
|
||
|
||
Machines: 9202 — every test app removed through the product (the scratch drive keeps some app folders, R-442's
|
||
refusal as before); no gate or block file left; back on the live catalog; the drill catalog reset to live `main`.
|
||
Demo boxes — read only (plus the floor). Host: nothing. Hub: floor 0.281.0. ep0: untouched.
|