diff --git a/CONTEXT.md b/CONTEXT.md
index bce68449..a7f5eac3 100644
--- a/CONTEXT.md
+++ b/CONTEXT.md
@@ -25,6 +25,15 @@
> while a release is ahead. CC has no scoped route to the global floor (R-1051) — only the operator page with the
> operator's password. A box on an `-rc` tag is never moved by the floor (R-1053).
+> **2026-10-15 (evening) — Prowlarr in the live catalog (catalog `73b45a6`, R-1048 closed).** Config volume only,
+> setup gate, `AuthenticationRequired=Enabled` + `AnalyticsEnabled=False` seeded by the template's entrypoint on the first
+> start. The box links it to Sonarr/Radarr only in a wiring run, and a run starts when a `media_library` app comes up —
+> Prowlarr has no marker, so installed AFTER them it waits for „Bekötés most" (R-1058, measured on 9201). A restore of a
+> REMOVED gated app comes back without the gate even from a pre-setup backup (`carryLifeRecords`: no prior record = no
+> gate; R-1057, measured on 9202). The new-app walk tool's bump emptied the drill `.felhom.yml` (open-for-write before
+> read) — fixed; `audits/prowlarr-2026-10-15/README.md`. Part B of the release-rule task stays STOPPED: hub v0.152.0's
+> scoped tokens (decision 251, another session) are the route, but no CC token exists on DooPlex yet (R-1051).
+
> **Night 2026-10-14 — https only and the media drive events.** Operator rulings recorded as `09` §3 **244** (R-1033 is
> P1) and **245** (drive events = option A: the box handles each event per app). **Decided by CC unattended — operator
> may reverse:** `09` §3 **246** — https-only is enforced on the box (traefik `felhom-forwarded` chain: a
diff --git a/REPORT-release-rule-prowlarr-2026-10-15.md b/REPORT-release-rule-prowlarr-2026-10-15.md
new file mode 100644
index 00000000..5cb54cf2
--- /dev/null
+++ b/REPORT-release-rule-prowlarr-2026-10-15.md
@@ -0,0 +1,123 @@
+# REPORT — the new release rule, and Prowlarr in the live catalog (2026-10-15)
+
+Written in ASD-STE100 Simplified Technical English. Architecture read first: `09-update-architecture.md` (§3, §6.4),
+`05-hub-architecture.md` (the floor, §17 tokens), `15-media-library.md` §6 (the links).
+
+## 1. The rule, and the files I changed
+
+The rule is `09` §3 decision 250 (operator, 2026-10-15 11:26 and 11:29):
+
+- A controller release needs no golden.
+- Push the image only when it is ready for every box.
+- CC raises the floor, with the MinAgent declared, after the release ran on Tester 1, demo-hp and demo-felhom through
+ the normal update path, and the box walk is green (`https_only_check.py` included). Not at night, unless the brief says so.
+- Agent releases still wait for the operator's vouch.
+- The golden is baked weekly. The operator vouches it.
+- Decision 7 stands again. Decision 247 („bake first", the same morning) is marked REVERSED. It is not deleted.
+
+Files changed (felhom.eu `e92501f5`, unless named):
+
+- `documentation/architecture/09-update-architecture.md` — decision 250; 247 marked reversed; 7 restored.
+- `documentation/architecture/05-hub-architecture.md` — the floor and the golden after decision 250.
+- `CLAUDE.md` — the golden-weekly bullet (instruction file; before: „bake before a release").
+- `.claude/rules/unprompted-work.md` §3 item 6 — the new text. The same text is in the controller (`e209a8d`), agent
+ (`d2053e7`), catalog (`3ff0cf3`) and the workspace root copy (unversioned). The five copies have the same md5.
+- `documentation/runbooks/RUNBOOK-manual-build.md`, `publish-train-rules.md`, `target-selection.md`, `nightly-rotation.md`.
+- `skills/felhom-build-deploy/SKILL.md` — a new section „Releasing a controller (decision 250)".
+- `scripts/golden_currency_gate.py`, `scripts/test_golden_currency_gate.py`, `scripts/repo_gates.py`.
+- `CONTEXT.md`, `STATUS.md`, `OPEN-ITEMS.md` (R-468 updated), `CLOSED-ITEMS.md`.
+
+## 2. Can CC raise the floor?
+
+**No, not today. Part B stopped.**
+
+- At the time of Part B, the only route was the operator page. It needs the operator's own password. I did not use it.
+ I did no save.
+- I read the floor from the hub database (copied with its WAL, from the pod): floor 0.313.0, MinAgent 0.155.0.
+- Later the same day, another session built and deployed hub 0.152.0. It adds scoped access tokens (decision 251).
+- **What you must do:** make the token „cc-releases" with *Overview: read* + *Releases: floor: write*. Save it on
+ DooPlex as `~/.felhom-hub/cc-token` (`chmod 600`). Do not paste it to me. The file does not exist now (I checked).
+- After that, the no-op save (0.313.0 / MinAgent 0.155.0) and its read-back can run. The skill gets the steps then.
+- Row: R-1051 (BLOCKED on the token).
+
+## 3. The gate
+
+- `golden_currency_gate.py` now judges the golden's AGE.
+- It convicts when the newest golden is more than 7 days old and a released controller is ahead of it.
+- On a docs-only push it stays advisory.
+- Tests: a 3-day-old golden passes; an 8-day-old golden convicts (CASE 18–21). I proved the tests fail with the limit
+ set to 0 and to 30.
+- **Limit:** the gate works offline. It reads the CHANGELOG and the bake folders. It cannot see the hub's floor or the vouch.
+
+## 4. The weekly golden
+
+- `runbooks/nightly-rotation.md` has a Sunday-night step: bake the golden when the floor is above it.
+- The operator vouches it. CC never vouches.
+- Row R-1052: the path for a new box is not proven.
+
+## 5. Prowlarr: live, linked, proven how
+
+**Live:** catalog `73b45a6`. Image `lscr.io/linuxserver/prowlarr:version-2.6.5.5623`. Published 2026-10-07 (8 days
+old). Digest `sha256:f9151e5b…` in the ladder entry. Config volume only. Setup gate. The first start sets „sign-in
+required" and turns usage data OFF (it was ON by default — measured).
+
+**The record:** `onboarding/prowlarr.md`. All 61 checks are done or n/a. All catalog gates pass.
+
+**Proof, by venue:**
+
+- Bench (LXC 9401): the update test passed; the negative control failed, as it must; 10-minute soak 7.6 % of 512 MB;
+ 0 kills; the data-folder gate is CLEAN.
+- 9202 (drill catalog): install window, gate, first account, stranger, 6 wrong passwords, the update, remove, and
+ backup → remove → restore → data back.
+- 9201 (live catalog, controller 0.313.0):
+ - Sonarr first, then Prowlarr: **no link by itself.** „Bekötés most" made it.
+ - Radarr after Prowlarr: **linked by itself**, about 60 s later.
+ - Prowlarr's own connection test: 200 for both. Its sync command: completed.
+ - All three removed without „delete data". 0 containers and 0 volumes left.
+
+**Not as the brief expected:** the box does not link Prowlarr when Prowlarr itself is installed. It links it only when
+Sonarr or Radarr starts, or when the household presses the button. The app text and the website card now say this.
+Row R-1058 asks for the fix (a controller change; I made no controller change).
+
+**Two more things I found:**
+
+- **R-1057 (security, P3):** a removed app that is restored comes back WITHOUT its setup gate. This is by design. But if
+ the backup was made before the first sign-in, the app comes back open, with no account. Measured on 9202.
+- **My own test-tool bug:** my first 9202 update emptied the test catalog's Prowlarr settings file. I found it, fixed
+ it, and ran the update and the restore again (run 3). The record cites run 3 only.
+
+**Deviation:** I used scratch guest 9202 for the box walk. The brief named only the bench and 9201. 9202 is Tier 0.
+It is back on the live catalog (byte-identical settings file); the test mirror is deleted.
+
+**Website:** a Prowlarr card on both apps pages. Every stated app count: 62 → 63. The machine estimator has Prowlarr.
+
+## 6. Wrong claims in the prompt; commits; register; STATUS
+
+**Wrong claims in the prompt:**
+
+1. „CC raises the floor itself" — with the access CC had, it could not. Only the operator's password could (§2).
+2. „The gate convicts when the golden is >7 days old while the floor is ahead" — the gate cannot see the floor. It
+ compares the golden with the newest released controller in the CHANGELOG (§3).
+3. „Confirm the controller links Prowlarr on install" — it does not when Prowlarr comes last (§5, R-1058).
+
+**Commits:**
+
+- felhom.eu: `e92501f5` (Part A–C), `2f1f6c80` (Prowlarr evidence, website, R-1057), and the final commit with this
+ report (R-1048 closed, R-1058, STATUS, CONTEXT).
+- felhom-controller `e209a8d`, felhom-agent `d2053e7` — the rule file only. No release.
+- app-catalog `3ff0cf3` (rule file), `73b45a6` (Prowlarr).
+- Drill catalog (test only): `b5bb89c`, `f2b0cc1`, `e985077`, `03b0c0d`, `e917a58`, `ebf3668`.
+
+**Register:** before 153 · opened 5 (R-1051, R-1052, R-1053, R-1057, R-1058) · closed 2 (R-1045, R-1048) · after 158.
+The 158 also holds another session's work today: 3 opened (R-1054..R-1056), 1 closed (R-952).
+
+**STATUS.md:** 59 lines.
+
+**Not-walked claims** (`unproven.py --summary`): 35 of 55. No change.
+
+**Teardown:** bench 9401 stopped, 0 containers. 9202: Prowlarr removed, live catalog back. 9201: Prowlarr, Sonarr,
+Radarr removed (keeping data); the drive's media folder stays (4.9 MB). Hub: nothing changed by me. Tester 1 and ep0:
+not touched.
+
+**Still running from the earlier task:** the Plex claim watcher waits for your code file. An unclaimed, gated Plex waits
+on demo-hp 9201.
diff --git a/STATUS.md b/STATUS.md
index 5148f41a..f826bac2 100644
--- a/STATUS.md
+++ b/STATUS.md
@@ -14,7 +14,7 @@
- A real power cut on demo-hp: it started by itself after all 8 cuts of the night (with the BIOS set), every app back in ~4 min; stale and recovered mails true and paired.
- A page for people searching „felhő tárhely" is live (/sajat-felho-tarhely, /en/own-cloud-storage): what cloud storage is, what to do when Google or iCloud fills up, a five-year cost table with prices read 2026-10-14, and who should NOT buy this.
- The machine estimator is public (/gepigeny, /en/sizing), with figures from two machines (N100 and HP t740; raised only, 2026-10-14).
-- 64 apps in the catalog, the Usenet and torrent clients included (the website lists 62 of them — R-1036). OS updates, the kernel lane too, run at night.
+- 65 apps in the catalog. New today: Prowlarr — you enter your download sources once, and Sonarr and Radarr get them (the website lists 63 apps — R-1036). OS updates, the kernel lane too, run at night.
- The hub is closed again after the 2026-10-12 security review; one box cannot read another's data.
## What is broken
@@ -22,6 +22,8 @@
- DooPlex: a failed disk with its alarms silenced (R-934); CI jobs still get lost (R-887); something sets the shared
checkout to „bare" (R-935); a Longhorn volume at 91 %.
- Tester 2 has never made an off-site check (R-862). The scratch box cannot read the drill catalog (R-992).
+- A removed app that is restored from a backup made BEFORE its first sign-in comes back open, with no account (R-1057).
+ Prowlarr installed after Sonarr/Radarr needs one press of „Bekötés most” to link; the app's text says so (R-1058).
## What we work on
- The power-cut findings still open (R-1004, R-1005, R-1010, R-1012, R-1013).
diff --git a/documentation/audits/prowlarr-2026-10-15/README.md b/documentation/audits/prowlarr-2026-10-15/README.md
index 96c66d2c..9dbc3b85 100644
--- a/documentation/audits/prowlarr-2026-10-15/README.md
+++ b/documentation/audits/prowlarr-2026-10-15/README.md
@@ -29,5 +29,7 @@ e917a58 restored the file; run 3 repeated the step. Run 1's checks before the bu
it redirects to the login (measured; FIRST-ADMIN row).
- No lock-out after wrong passwords → a stranger cannot lock the household out (the property `09` §3 decisions 57–60
protect); no row.
-- The box links Prowlarr only when Sonarr/Radarr come up, or on „Bekötés most" → the copy says so; the register row is
- in `OPEN-ITEMS.md` (filed in this session, see `box9201/`).
+- The box links Prowlarr only when Sonarr/Radarr come up, or on „Bekötés most" → measured on 9201 (`box9201/`); the copy
+ and the website card say so; R-1058.
+- A restore of a removed gated app comes back without the gate, even from a backup made before the setup → measured
+ on 9202 run 3 (a stranger's `/ping` 200 after the restore, 401 before); R-1057.
diff --git a/documentation/audits/prowlarr-2026-10-15/box/run3/99-restore.txt b/documentation/audits/prowlarr-2026-10-15/box/run3/99-restore.txt
new file mode 100644
index 00000000..4aa6b33d
--- /dev/null
+++ b/documentation/audits/prowlarr-2026-10-15/box/run3/99-restore.txt
@@ -0,0 +1,14 @@
+2026/10/15 11:01:52 sync.go:283: [INFO] [sync] Catalog sync complete
+2026/10/15 11:01:52 sync.go:126: [INFO] [sync] Initial sync: Sablonok frissítve — frissítve: immich, prowlarr
+
+26: repo_url: https://gitea.dooplex.hu/admin/app-catalog-felhom.eu.git
+27: sync_interval: 15m
+-rw------- 1 root root 1944 Oct 12 20:52 /var/lib/docker/volumes/felhom-controller-data/_data/controller.yaml.pre-prowlarr1015
+mirror main ebf3668f DRILL prowlarr: the step -> lscr.io/linuxserver/prowlarr:version-2.6.5.5623 (R-1048, checklist 2.5)
+cache HEAD 73b45a6 Prowlarr into the live catalog, with its complete onboarding record (R-1048)
+https://gitea.dooplex.hu/admin/app-catalog-felhom.eu.git
+
+ls: cannot access '/var/lib/docker/volumes/felhom-controller-data/_data/drill-catalog.git': No such file or directory
+ repo_url: https://gitea.dooplex.hu/admin/app-catalog-felhom.eu.git
+0
+e129d58b0b4f1ad551c92aeb876d52a3 /opt/docker/stacks/prowlarr/.felhom.yml
diff --git a/documentation/audits/prowlarr-2026-10-15/box9201/README.md b/documentation/audits/prowlarr-2026-10-15/box9201/README.md
new file mode 100644
index 00000000..4bdccb94
--- /dev/null
+++ b/documentation/audits/prowlarr-2026-10-15/box9201/README.md
@@ -0,0 +1,20 @@
+# demo-hp 9201, LIVE catalog 73b45a6, controller 0.313.0 — the Prowlarr link read-back (2026-10-15)
+
+`link.txt` is the record; the two consoles are the raw output. Pressed only what a person presses: the sync, the deploy
+wizard's call, „Bekötés most" (`POST /api/storage/media/wire`), stop + remove keeping data.
+
+- **[B] Sonarr first, Prowlarr after:** the box's wiring ran when Sonarr came up; in the 150 s after Prowlarr came up no
+ wiring ran at all. „Bekötés most" then answered `prowlarr: done, wrote application Sonarr` — the wirer writes only a
+ link that is missing (`mediawire.go` `prowlarr()`), so the link was not there before the press.
+- **[A] Radarr after Prowlarr:** the wiring ran ~60 s after Radarr came up (`radarr=done(3) prowlarr=done(1)`) and
+ Prowlarr's Apps listed Radarr and Sonarr, both `fullSync`, by container name.
+- **[D]** Prowlarr's own connection test for each link: 200. Its sync command `ApplicationIndexerSync`: completed.
+ Prowlarr holds no indexer yet, so Sonarr's and Radarr's indexer lists are empty, as expected.
+- **[X]** All three removed keeping data: each config volume removed (that is what remove does to a volume), the
+ drive's media folder kept (4.9 MB, Sonarr's and Radarr's), 0 containers and 0 volumes left.
+
+**One tool defect, recorded:** the first run read Prowlarr's API key in the guest shell instead of inside the container
+(double quotes), so its own reads in [B3] and [C2] show 401. The box-side facts above do not depend on them. The
+script was fixed (`shlex.quote`) and re-entered with `CONTINUE=1` from [A] on; the installs stood.
+
+The install-order gap is register row R-1058; the copy and the website card already tell the household about the button.
diff --git a/documentation/audits/prowlarr-2026-10-15/box9201/link-console-part1.txt b/documentation/audits/prowlarr-2026-10-15/box9201/link-console-part1.txt
new file mode 100644
index 00000000..4c511a21
--- /dev/null
+++ b/documentation/audits/prowlarr-2026-10-15/box9201/link-console-part1.txt
@@ -0,0 +1,18 @@
+13:02:21 [0] controller: gitea.dooplex.hu/admin/felhom-controller:0.313.0
+13:03:40 [sync] the badge NEVER caught up to lscr.io/linuxserver/prowlarr:version-2.6.5.5623 in 79.2s — catalog_images = None
+13:03:44 [0] live catalog on the box: 73b45a6 Prowlarr into the live catalog, with its complete onboarding record (R-1048) | https://gitea.dooplex.hu/admin/app-catalog-felhom.eu.git
+13:03:47 [0] prowlarr template on the box: 4949 /opt/docker/stacks/prowlarr/.felhom.yml | image: lscr.io/linuxserver/prowlarr:version-2.6.5.5623@sha256:f9151e5bc1025c6d0a630d503210cdcb6bb55a7cc098562609d96a408d838902 | setup_gate: true
+13:03:47 deploy sonarr {"DOMAIN": "enkisfelhom.hu", "SUBDOMAIN": "sonarr", "HDD_PATH": "/mnt/felhom-drives/hdd_1"} -> 202 {"ok": true, "message": "The install has started – the card shows how it is going"}
+13:04:17 sonarr: deployed, running, pinned={'sonarr': 'lscr.io/linuxserver/sonarr:4.0.20'}
+13:05:40 [B1] wiring after Sonarr came up:
+2026/10/15 11:04:55 media_events.go:69: [INFO] [media] wiring the drives into the media apps (a media app came up: sonarr)
+2026/10/15 11:04:56 mediawire.go:138: [INFO] [mediawire] 1 drive(s) wired in 1.046s: folders=done(0) sonarr=done(3) plex=household(0)
+13:05:40 deploy prowlarr {"DOMAIN": "enkisfelhom.hu", "SUBDOMAIN": "prowlarr"} -> 202 {"ok": true, "message": "The install has started – the card shows how it is going"}
+13:06:05 prowlarr: deployed, running, pinned={'prowlarr': 'lscr.io/linuxserver/prowlarr:version-2.6.5.5623'}
+13:06:12 [B2] prowlarr first-start line: [felhom] first start - AuthenticationRequired=Enabled, AnalyticsEnabled=False seeded
+13:08:48 [B3] 150 s after Prowlarr came up (Sonarr was there first): Prowlarr's Apps = 401
+13:08:48 [B3] wiring runs since Prowlarr's install: (none)
+13:08:50 [C1] „Bekötés most” (POST /api/storage/media/wire) -> 200; prowlarr result: [{"app": "prowlarr", "state": "done", "wrote": ["application Sonarr"]}]
+13:08:53 [C2] Prowlarr's Apps after the press: 401
+13:08:53 deploy radarr {"DOMAIN": "enkisfelhom.hu", "SUBDOMAIN": "radarr", "HDD_PATH": "/mnt/felhom-drives/hdd_1"} -> 202 {"ok": true, "message": "The install has started – the card shows how it is going"}
+13:09:14 radarr: deployed, running, pinned={'radarr': 'lscr.io/linuxserver/radarr:6.4.4'}
diff --git a/documentation/audits/prowlarr-2026-10-15/box9201/link-console-part2.txt b/documentation/audits/prowlarr-2026-10-15/box9201/link-console-part2.txt
new file mode 100644
index 00000000..57fa38bb
--- /dev/null
+++ b/documentation/audits/prowlarr-2026-10-15/box9201/link-console-part2.txt
@@ -0,0 +1,17 @@
+13:09:45 [CONTINUE] re-entered after the key fix; Radarr started 2026-10-15T11:09:01Z; Sonarr, Prowlarr, Radarr installed by run 1 of this script
+13:09:48 [CONTINUE] Prowlarr's Apps read now with the right key: [('Sonarr', 'fullSync', 'http://sonarr:8989')]
+13:10:15 [A1] Radarr appeared in Prowlarr's Apps by itself, ~20 s after Radarr ran
+13:10:15 [A2] Prowlarr's Apps: [('Radarr', 'fullSync', 'http://radarr:7878'), ('Sonarr', 'fullSync', 'http://sonarr:8989')]
+13:10:18 [A2] wiring runs since Radarr's install:
+2026/10/15 11:10:02 media_events.go:69: [INFO] [media] wiring the drives into the media apps (a media app came up: radarr)
+2026/10/15 11:10:03 mediawire.go:138: [INFO] [mediawire] 1 drive(s) wired in 1.849s: folders=done(0) sonarr=unchanged(0) radarr=done(3) prowlarr=done(1) plex=household(0)
+13:10:25 [D1] Prowlarr's connection test for Radarr (Radarr, syncLevel fullSync) -> 200
+13:10:28 [D1] Prowlarr's connection test for Sonarr (Sonarr, syncLevel fullSync) -> 200
+13:10:31 [D2] sync command ApplicationIndexerSync -> 201 id=1
+13:10:37 [D2] sync command status: completed
+13:10:40 [D3] Prowlarr's own log of the sync:
+13:10:43 [D4] Sonarr's and Radarr's indexer lists (Prowlarr has no indexer yet, so both empty is the expected answer): [] <- sonarr | [] <- radarr
+13:11:19 [X] radarr: stop 200, remove keeping data -> 200 {"ok": true, "data": {"removed": "radarr", "volumes_removed": ["radarr_radarr_config"], "hdd_paths_removed": [], "hdd_paths_preserved": [], "userdata_kept": ["/mnt/felhom-drives/hdd_1/userdata/media (4.9M)"], "verified": true}, "message": "Stack radarr removed
+13:11:54 [X] prowlarr: stop 200, remove keeping data -> 200 {"ok": true, "data": {"removed": "prowlarr", "volumes_removed": ["prowlarr_prowlarr_config"], "hdd_paths_removed": [], "hdd_paths_preserved": [], "userdata_kept": [], "verified": true}, "message": "Stack prowlarr removed"}
+13:12:30 [X] sonarr: stop 200, remove keeping data -> 200 {"ok": true, "data": {"removed": "sonarr", "volumes_removed": ["sonarr_sonarr_config"], "hdd_paths_removed": [], "hdd_paths_preserved": [], "userdata_kept": ["/mnt/felhom-drives/hdd_1/userdata/media (4.9M)"], "verified": true}, "message": "Stack sonarr removed
+13:12:39 [X] left: containers=0 volumes=0
diff --git a/documentation/audits/prowlarr-2026-10-15/box9201/link-results.json b/documentation/audits/prowlarr-2026-10-15/box9201/link-results.json
new file mode 100644
index 00000000..2726e514
--- /dev/null
+++ b/documentation/audits/prowlarr-2026-10-15/box9201/link-results.json
@@ -0,0 +1,17 @@
+{
+ "order_A_apps": [
+ [
+ "Radarr",
+ "fullSync",
+ "http://radarr:7878"
+ ],
+ [
+ "Sonarr",
+ "fullSync",
+ "http://sonarr:8989"
+ ]
+ ],
+ "test_Radarr": "200",
+ "test_Sonarr": "200",
+ "sync_status": "completed"
+}
\ No newline at end of file
diff --git a/documentation/audits/prowlarr-2026-10-15/box9201/link.txt b/documentation/audits/prowlarr-2026-10-15/box9201/link.txt
new file mode 100644
index 00000000..40e15b42
--- /dev/null
+++ b/documentation/audits/prowlarr-2026-10-15/box9201/link.txt
@@ -0,0 +1,35 @@
+[0] controller: gitea.dooplex.hu/admin/felhom-controller:0.313.0
+ [sync] the badge NEVER caught up to lscr.io/linuxserver/prowlarr:version-2.6.5.5623 in 79.2s — catalog_images = None
+[0] live catalog on the box: 73b45a6 Prowlarr into the live catalog, with its complete onboarding record (R-1048) | https://gitea.dooplex.hu/admin/app-catalog-felhom.eu.git
+[0] prowlarr template on the box: 4949 /opt/docker/stacks/prowlarr/.felhom.yml | image: lscr.io/linuxserver/prowlarr:version-2.6.5.5623@sha256:f9151e5bc1025c6d0a630d503210cdcb6bb55a7cc098562609d96a408d838902 | setup_gate: true
+ deploy sonarr {"DOMAIN": "enkisfelhom.hu", "SUBDOMAIN": "sonarr", "HDD_PATH": "/mnt/felhom-drives/hdd_1"} -> 202 {"ok": true, "message": "The install has started – the card shows how it is going"}
+ sonarr: deployed, running, pinned={'sonarr': 'lscr.io/linuxserver/sonarr:4.0.20'}
+[B1] wiring after Sonarr came up:
+2026/10/15 11:04:55 media_events.go:69: [INFO] [media] wiring the drives into the media apps (a media app came up: sonarr)
+2026/10/15 11:04:56 mediawire.go:138: [INFO] [mediawire] 1 drive(s) wired in 1.046s: folders=done(0) sonarr=done(3) plex=household(0)
+ deploy prowlarr {"DOMAIN": "enkisfelhom.hu", "SUBDOMAIN": "prowlarr"} -> 202 {"ok": true, "message": "The install has started – the card shows how it is going"}
+ prowlarr: deployed, running, pinned={'prowlarr': 'lscr.io/linuxserver/prowlarr:version-2.6.5.5623'}
+[B2] prowlarr first-start line: [felhom] first start - AuthenticationRequired=Enabled, AnalyticsEnabled=False seeded
+[B3] 150 s after Prowlarr came up (Sonarr was there first): Prowlarr's Apps = 401
+[B3] wiring runs since Prowlarr's install: (none)
+[C1] „Bekötés most” (POST /api/storage/media/wire) -> 200; prowlarr result: [{"app": "prowlarr", "state": "done", "wrote": ["application Sonarr"]}]
+[C2] Prowlarr's Apps after the press: 401
+ deploy radarr {"DOMAIN": "enkisfelhom.hu", "SUBDOMAIN": "radarr", "HDD_PATH": "/mnt/felhom-drives/hdd_1"} -> 202 {"ok": true, "message": "The install has started – the card shows how it is going"}
+ radarr: deployed, running, pinned={'radarr': 'lscr.io/linuxserver/radarr:6.4.4'}
+[CONTINUE] re-entered after the key fix; Radarr started 2026-10-15T11:09:01Z; Sonarr, Prowlarr, Radarr installed by run 1 of this script
+[CONTINUE] Prowlarr's Apps read now with the right key: [('Sonarr', 'fullSync', 'http://sonarr:8989')]
+[A1] Radarr appeared in Prowlarr's Apps by itself, ~20 s after Radarr ran
+[A2] Prowlarr's Apps: [('Radarr', 'fullSync', 'http://radarr:7878'), ('Sonarr', 'fullSync', 'http://sonarr:8989')]
+[A2] wiring runs since Radarr's install:
+2026/10/15 11:10:02 media_events.go:69: [INFO] [media] wiring the drives into the media apps (a media app came up: radarr)
+2026/10/15 11:10:03 mediawire.go:138: [INFO] [mediawire] 1 drive(s) wired in 1.849s: folders=done(0) sonarr=unchanged(0) radarr=done(3) prowlarr=done(1) plex=household(0)
+[D1] Prowlarr's connection test for Radarr (Radarr, syncLevel fullSync) -> 200
+[D1] Prowlarr's connection test for Sonarr (Sonarr, syncLevel fullSync) -> 200
+[D2] sync command ApplicationIndexerSync -> 201 id=1
+[D2] sync command status: completed
+[D3] Prowlarr's own log of the sync:
+[D4] Sonarr's and Radarr's indexer lists (Prowlarr has no indexer yet, so both empty is the expected answer): [] <- sonarr | [] <- radarr
+[X] radarr: stop 200, remove keeping data -> 200 {"ok": true, "data": {"removed": "radarr", "volumes_removed": ["radarr_radarr_config"], "hdd_paths_removed": [], "hdd_paths_preserved": [], "userdata_kept": ["/mnt/felhom-drives/hdd_1/userdata/media (4.9M)"], "verified": true}, "message": "Stack radarr removed
+[X] prowlarr: stop 200, remove keeping data -> 200 {"ok": true, "data": {"removed": "prowlarr", "volumes_removed": ["prowlarr_prowlarr_config"], "hdd_paths_removed": [], "hdd_paths_preserved": [], "userdata_kept": [], "verified": true}, "message": "Stack prowlarr removed"}
+[X] sonarr: stop 200, remove keeping data -> 200 {"ok": true, "data": {"removed": "sonarr", "volumes_removed": ["sonarr_sonarr_config"], "hdd_paths_removed": [], "hdd_paths_preserved": [], "userdata_kept": ["/mnt/felhom-drives/hdd_1/userdata/media (4.9M)"], "verified": true}, "message": "Stack sonarr removed
+[X] left: containers=0 volumes=0
diff --git a/documentation/audits/prowlarr-2026-10-15/tools/walk_9201_link.py b/documentation/audits/prowlarr-2026-10-15/tools/walk_9201_link.py
index 6cbc3be1..26940a34 100644
--- a/documentation/audits/prowlarr-2026-10-15/tools/walk_9201_link.py
+++ b/documentation/audits/prowlarr-2026-10-15/tools/walk_9201_link.py
@@ -14,6 +14,7 @@ Then: Prowlarr's own connection test for each link, and its sync command to comp
import json
import os
import re
+import shlex
import sys
import time
@@ -38,13 +39,15 @@ w.say = say
def papi(path, body=None, method=None):
+ # FIXED 2026-10-15 after the first run: json.dumps() quoted this with DOUBLE quotes, so the guest shell expanded
+ # $(sed …) and $K before docker exec — empty key, every call 401 (link.txt [B3]/[C2]). shlex.quote keeps it literal.
"""Prowlarr's own API from inside its container (the key read from its config.xml at use, never printed)."""
m = method or ("POST" if body is not None else "GET")
data = json.dumps(body) if body is not None else ""
script = ("K=$(sed -n 's:.*\\(.*\\).*:\\1:p' /config/config.xml); "
f"curl -s -o /tmp/pb.json -w '%{{http_code}}' -X {m} -H \"X-Api-Key: $K\" -H 'Content-Type: application/json' "
f"--data-binary @- http://127.0.0.1:9696/api/v1{path}; echo; cat /tmp/pb.json")
- out = w.guest(f"docker exec -i prowlarr sh -c {json.dumps(script)} <<'EOF'\n{data}\nEOF")
+ out = w.guest(f"docker exec -i prowlarr sh -c {shlex.quote(script)} <<'EOF'\n{data}\nEOF")
code, _, body_ = out.partition("\n")
try:
return code.strip(), json.loads(body_) if body_.strip() else None
@@ -87,6 +90,8 @@ def wait_healthy(c, tries=60):
def main():
w.login()
+ if os.environ.get("CONTINUE") == "1":
+ return part2()
t0 = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
for a in ("prowlarr", "sonarr", "radarr"):
if w.stack(a).get("deployed"):
@@ -125,6 +130,15 @@ def main():
tR = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
install("radarr", {"DOMAIN": w.DOMAIN, "SUBDOMAIN": "radarr", "HDD_PATH": HDD})
wait_healthy("radarr")
+ part2(tR)
+
+
+def part2(tR=None):
+ """From order A's check on (CONTINUE=1 re-enters here after the first run's key bug; the installs stand)."""
+ if tR is None:
+ tR = w.guest("docker inspect radarr -f '{{.State.StartedAt}}'").strip()[:19] + "Z"
+ say(f"[CONTINUE] re-entered after the key fix; Radarr started {tR}; Sonarr, Prowlarr, Radarr installed by run 1 of this script")
+ say(f"[CONTINUE] Prowlarr's Apps read now with the right key: {apps()}")
a_apps = None
for i in range(30):
time.sleep(10)
diff --git a/documentation/backlog/CLOSED-ITEMS.md b/documentation/backlog/CLOSED-ITEMS.md
index 81a87839..123bb5aa 100644
--- a/documentation/backlog/CLOSED-ITEMS.md
+++ b/documentation/backlog/CLOSED-ITEMS.md
@@ -26,6 +26,12 @@
---
+## 2026-10-15 (evening) — Prowlarr in the live catalog (catalog 73b45a6)
+
+| Row | What | Closed | Evidence |
+|---|---|---|---|
+| **R-1048** | **Prowlarr into the live catalog (full new-app checklist), linked by the box.** (P3) | CLOSED 2026-10-15 — published in catalog `73b45a6` with `onboarding/prowlarr.md` (61 checks done or n/a): pinned `version-2.6.5.5623` (published 2026-10-07, digest in the ladder), config volume only (`important`), setup gate, `AuthenticationRequired=Enabled` + `AnalyticsEnabled=False` seeded at the first start. Bench: update test proven, C3 failed as it must, soak 7.6 %, volume-persistence CLEAN. 9202: gate, first account, stranger, lock-out, the step and backup → remove → restore (run 3; runs 1–2 hit a test-tool bug, recorded). 9201 (live): Sonarr then Prowlarr — no link until „Bekötés most"; Radarr after Prowlarr — linked by itself; Prowlarr's connection test 200 for both; its sync command completed; all removed keeping data, nothing left. The install-order gap is R-1058; the restore-without-gate finding is R-1057. | `audits/prowlarr-2026-10-15/` (README.md, `box9201/link.txt`, `box/run3/restore.txt`) |
+
## 2026-10-15 (evening) — hub access tokens (hub v0.152.0, built, not deployed)
| Row | What | Closed | Evidence |
diff --git a/documentation/backlog/OPEN-ITEMS.md b/documentation/backlog/OPEN-ITEMS.md
index 630bdfba..0fa48fd0 100644
--- a/documentation/backlog/OPEN-ITEMS.md
+++ b/documentation/backlog/OPEN-ITEMS.md
@@ -136,12 +136,12 @@ stopping line that lies.
| **R-1028** | Apps & catalog | P3 | **Plex's claim code can run out during the install, and the box cannot recover it.** plex.tv's code lives 4 minutes from the moment the household copies it; the clock covers the wizard, the image pull (`plexinc/pms-docker` is 351 MB, measured) and the first start. Plex reads `PLEX_CLAIM` only on its first run, and the field is `locked_after_deploy` — so a late code leaves an unclaimed server and the only way back is remove + install again. Reported by the operator during the 2026-10-14 test; on Tester 1's line the pull+start took 8.5 s and the claim worked (`audits/media-all-drives-2026-10-14/``G-auth/G3-plex-claim.txt`), so it bites on a slow line or a slow hand. **K6, 2026-10-14 night (`audits/media-drive-events-2026-10-14/``K6-1-unclaimed-plex.txt`):** an unclaimed Plex starts with no code at all, and `POST /myplex/claim?token=` on the RUNNING server reaches plex.tv (a wrong code → 500 after plex.tv's 401). So the box can pull + start first and ask for the code after: no race. A real claim needs the household's code — the morning step on the throwaway `plex-k6` on Tester 1. Narrowed 2026-10-14 night. **PROVEN 2026-10-15 morning (`K6-2-claim-after-start.txt`):** the operator's real code, given to the RUNNING unclaimed `plex-k6` → 200, `claimed` 0→1, `PlexOnlineToken` written, and the open door closed (no token → 401). `ADVERTISE_IP` was unset and the claim did not need it; whether clients find the server without it was not measurable (the throwaway had no published port). **BUILT 2026-10-15 (v0.313.0):** `after_start` field — not asked at install; the Plex page asks for the code once Plex runs and claims the running server; the gate opens only when Plex says claimed. Proven up to the code on 9201 (G5). | **NARROWED** — the dashboard claim with a real code is the last step | a household Plex code | Claim through the Plex page with a real code (G5c); then close | CC |
| **R-1029** | Apps & catalog | P3 | **Plex's folder picker shows the drives as identical „media” folders.** With one bind per drive at the same path (`/mnt/felhom-drives//userdata/media`), the leaf of every library folder is `media`; the drive's name sits two levels up, so in Plex's picker the household sees several folders all called „media” (reported by the operator during the 2026-10-14 test on Tester 1). It conflicts with `15` §2 reason 2 (the same path everywhere). | **READY** — filed 2026-10-14 | the layout decision (STATUS D9) | Decide in `15` §2: the players (`:ro`, never linked) may get a readable path per drive (e.g. `/media/`) without breaking the hardlink rule, which binds only the download/library apps | CC |
| **R-1036** | Apps & catalog | P3 | **The apps page lags the catalog by two apps.** `app-catalog-felhom.eu/templates/` holds **64** apps; `/alkalmazasok` and `/en/apps` render **63** cards, one of which (`filebrowser`) is built in and not a catalog template — so **62 catalog apps are listed**. Missing: **`plant-it`** and **`wger`**, both in the catalog since 2026-10-06/08. Their website assets are ALREADY present (`plant-it-logo.svg` + 3 screenshots, `wger-logo.png` + 3 screenshots, renamed to the catalog slug by `a3507761`, 2026-10-08) — only the cards were never written, so this is not a new-asset job. Found 2026-10-14 while reconciling the app count for the „felhő tárhely” page, where four places said **60** and the rest said **62**. **Done in that session:** every stated count on the site set to **62** (`index.html`, `szolgaltatasok.html`, `en/services.html` were 60), which is what the apps page actually shows — so no visitor can count the cards and find the number wrong. **62 is still not the catalog's number.** **To close:** write the two cards on both apps pages (gate 15 keeps the two pages' app sets equal, so they move together), then raise every stated count 62 → 64 in the same commit. **The operator chose this split at the 2026-10-14 STOP** over doing it inside the SEO change. **2026-10-15 (R-1048):** Prowlarr's card added on both pages and every stated count 62 → 63 (the media group 19 → 20), so the site still states what it shows; the two owed cards would make it 65. **Note before writing them:** `wger` is `lifecycle: hidden` and `plant-it` `lifecycle: abandoned` — neither is offered for a new install, so a card would advertise an app the wizard refuses. | **OPEN** | — | write the `plant-it` + `wger` cards on both apps pages, then 62 → 64 everywhere, one commit | CC |
+| **R-1058** | Apps & catalog | P3 | **Prowlarr installed AFTER Sonarr/Radarr is not linked to them until the household presses „Bekötés most" (or a media app restarts).** The box's wiring runs when an app with the `media_library` marker comes up (`felhom-controller` `internal/stacks/manager.go` `onMediaUp`); Prowlarr has no marker (it uses no drive), so its own install starts no run. Measured 2026-10-15 on demo-hp 9201, live catalog, controller 0.313.0 (`audits/prowlarr-2026-10-15/box9201/link.txt`): Sonarr first → its run; Prowlarr after → no run in 150 s; „Bekötés most" wrote `application Sonarr`; Radarr after Prowlarr → linked by itself ~60 s later. The template copy and the website card tell the household this today. | **OPEN** — filed 2026-10-15 by the Prowlarr read-back | — | Start the wiring when Prowlarr comes up too (a list of link-only apps beside the marker, no drive binds); red-proof with the 9201 order (Sonarr, then Prowlarr); then drop the button sentence from the copy | CC |
| **R-76** | Apps & catalog | P4 | **FileBrowser-created folders break the setgid chain, and a drop-zone's mode is not stable** **MIGRATED FROM `ROADMAP.md` 2026-08-22 (R-369) — originally filed 2026-07-26, size S, roadmap state `idea (surfaced by the R-75 spike, 2026-07-26)`.** Moved verbatim; nothing added or reinterpreted. The roadmap keeps its copy as history, marked moved. | **OPEN — migrated from ROADMAP 2026-08-22, rank unchanged** **2026-10-06 night: not a catalog fix** — the setgid chain is set by the controller's FileBrowser setup; a controller row. | — | Two related findings from `audits/SPIKE-catalog-data-paths-2026-07-26.md` P3/P5, both **pre-existing** and deliberately left alone by that spike. **(a)** FileBrowser Quantum 1.3.3 creates files `0644` and folders `0755` and does **not** propagate the setgid bit — even though the entrypoint wrapper's `umask 002` really is in effect (`/proc/1/status` `Umask: 0002`). Group inheritance itself works (a file uploaded into a 2775 group-100 dir landed group 100, not the process gid 1000), so the convention's *group* half holds and only its *mode* half is lost. The consequence is proven with a control: inside a UI-created `0755` folder a gid-1000 process's file landed group **1000**, while the identical write into the 2775 parent landed group **100**. So **any folder a customer creates through FileBrowser breaks the shared-group chain one level down.** Latent today — every userdata-touching catalog app that declares an identity declares uid/gid **1000**, the same uid FileBrowser runs as, so owner permissions mask it; it bites the day a content app runs as a different non-root uid with gid 1000. The comment at `infra/infra.go:156` is right that the image ignores `-e UMASK` but does not say t | CC |
| **R-707** | Apps & catalog | P4 | **[P2] 37 apps still start with a login a stranger can take (`09` §3 decision 45).** Audit of all 53 apps: `app-catalog-felhom.eu/FIRST-ADMIN.md` (class, fix route, status, measured or read). Open: **3 hard-coded defaults** — calibre-web (`admin / admin123`, measured working on demo-hp and 9202; its own `cps.py -s` route needs a generated password WITH a special character — our generator is letters+digits, a controller change), mealie (`changeme@example.com / MyPassword`), wger (`admin / adminadmin`); **34 open first-run screens** (the first visitor creates the admin: actualbudget, adventurelog, audiobookshelf, calcom, docmost, emby, ghost, gitea, gramps-web, home-assistant, homebox, immich, jellyfin, komga, n8n, navidrome, opengist, outline, papra, plant-it, radarr, rallly, recipe-importer, romm, seerr, sonarr, sparkyfitness, tandoor, termix, uptime-kuma, vikunja, wanderer, wishlist, zipline). **Stale notes:** romm's `default_creds` `admin / admin` answers 401 on demo-hp (like a wrong password) — the page now warns with a login that does not exist; zipline's looks stale too. **Measured on demo-hp 2026-09-28 (read-only):** bookstack's default still logs in on the INSTALLED app (the fix is for new installs; the page now warns). Each fix: route (a) env or (b) the app's own CLI/API via `after_install:`, proven on 9202 with the default failing and the generated password working; route (c) a page sentence. Several sessions (operator, 2026-09-28). **2026-09-29 (controller v0.280.0, catalog `d0e7e2e`):** every class-3 app fixed — mealie, wger, calibre-web by `after_install` (calibre-web with the new `password:24:special`), proven on 9202 fresh installs (`audits/login-gate-2026-09-29/D/`); the setup gate (decision 46, spike PASSED) built and live on immich, n8n, audiobookshelf (probes measured) and uptime-kuma (button) (`…/C/`); romm's and zipline's stale notes removed. **Left: 30 class-4 apps** — gate each (probe measured on 9202 where one exists — 11 upstream candidates listed in `…/B/B-VERDICT.md` §3; the button otherwise). **2026-09-29 afternoon (controller v0.281.0, catalog `6faf432`):** 28 more class-4 apps gated — 32 of 34 — each proven on 9202 (`audits/gate-rollout-2026-09-29/`B): stranger → gate page / 401, household reached the first-setup screen, the gate opened (9 by a measured probe, the rest by the press), the app answered after. seerr, outline, rallly: gated, their opening needs a media server / e-mail (not proven). **Left:** wanderer (R-714); plant-it is not installable. | **NARROWED** (2026-10-03 triage: the row's verdict was finished, but it names open work no other row carries — seerr, outline and rallly are gated, but the gate OPENING is not proven (needs a media server / e-mail)) — **CLOSED — 2026-09-29 (the rest → R-714)** | — | — | CC |
| **R-905** | Apps & catalog | P4 | **wger's collected style files (283 MB) go into every wger backup, though the app rebuilds them at every start.** Since R-762's fix (`DJANGO_DEBUG=False` + `collectstatic`, catalog `cf1ed43`) the static files sit in a named volume that the backup legs copy like data (measured 283 MB, `audits/design-build-2026-10-06/`); `collectstatic` regenerates them, so they are rebuildable bytes in every Tier-1 unit, Tier-2 copy and off-site snapshot. wger is `lifecycle: hidden` and no box runs it (hub read 2026-10-08). Options to weigh: a non-backed-up volume class for regenerable data, or an anonymous volume. Found by the R-762 helpers 2026-10-08. | **OPEN — needs a design before wger is shown** | — | Design the „regenerable volume" exclusion (catalog + controller backup legs) | CC |
| **R-995** | Apps & catalog | P4 | **Removing an app through the product can leave unnamed Docker volumes and an empty import folder behind.** MEASURED 2026-10-13 on demo-felhom after 61 removals (`documentation/audits/sizing-2026-10-13/METHOD.md` „Teardown”, `evidence/leftover-volumes-after-bench.txt`): 8 unnamed volumes (4–72 KB; immich 1, romm 2, privatebin 3, onlyoffice 2 — volumes the images declare themselves) and `userdata/import/{paperless,calibre,grimmory}` (empty, created by the deploy). The removal answered 200 and its own leftover check was clean, because it looks only at labelled volumes. No data risk; disk and tidiness only. Removed by name on the bench. | **READY** — filed 2026-10-13 | — | Make the removal account for the containers' unnamed volumes (and an empty import folder it created), with a test that deploys an image that declares a VOLUME | CC |
| **R-1043** | Apps & catalog | P4 | **Sonarr, Radarr and Prowlarr build their login redirect as an absolute `http://` URL.** They trust forwarded headers only from their „Trusted networks” (the household set `192.168.0.0/24`; traefik is `172.18.x`), so they ignore `X-Forwarded-Proto: https` and answer `Location: http:///login` to an https visitor. Since controller v0.312.0 that hop is sent back to https by traefik (a GET, no password), so it is cosmetic; a template could seed traefik's network as trusted. (`audits/https-only-2026-10-14/``1A-3-4.txt`) | **OPEN** — filed 2026-10-14 | — | Seed the docker network as a trusted proxy in the *arr templates (with the R-1030 seed), measure the redirect | CC |
-| **R-1048** | Apps & catalog | P3 | **Prowlarr into the live catalog (full new-app checklist), linked by the box.** Today it is in the drill catalog only (test, 2026-10-14): config in a named volume, no media folders; the box linked it to Sonarr and Radarr by script (Prowlarr → Settings → Apps, full sync — `audits/media-all-drives-2026-10-14/tools/wire.py`). The live catalog needs the full new-app checklist (`app-catalog-felhom.eu/REUSE.md`), Hungarian copy, the apps page, and the link made by the box at install. | **READY** — filed 2026-10-14 night | — | Add it with the checklist; the link with R-1024 | CC |
## App updates — 4 rows (P3 4)