Register: R-1022, R-1116, R-977 closed; R-1123..R-1128 filed; R-994 narrowed; duplicate ids fixed

b9c4f73b (the cc-creds session) committed this session's uncommitted register edits together with its own
R-1118..R-1122, so main carried two rows each for R-1118..R-1122. This session's five move to R-1124..R-1128
(R-1123 stays); the CLOSED-ITEMS section for the three closed rows lands here. Evidence:
audits/tester1-limits-filebrowser-2026-10-17/.

Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
2026-10-17 11:58:18 +02:00
parent b9c4f73bfa
commit fae8064557
31 changed files with 523 additions and 6 deletions
@@ -0,0 +1,12 @@
10:59:59 POST /api/sync -> 200 {'ok': True, 'data': {'ok': True, 'message': 'Sablonok naprakészek — nincs változás'}, 'message': 'Sablonok naprakészek — nincs változás'}
11:00:09 == paperless-ngx before:
compose: command: redis-server --appendonly no| command: redis-server --appendonly no|
container: 2026-10-17T02:33:00.206620166Z ["redis-server","--appendonly","yes"] Up 6 hours (healthy)
dbsize: 2 rdb_last_bgsave_status:ok aof_enabled:1
/data: appendonlydir dump.rdb
11:00:27 POST /api/stacks/paperless-ngx/restart -> 200 {'ok': True, 'data': {'state': 'starting'}, 'message': 'Stack paperless-ngx restart requested — state now: starting'}
11:01:26 == paperless-ngx after (state=running hold=None):
compose: command: redis-server --appendonly no| command: redis-server --appendonly no|
container: 2026-10-17T09:00:09.719659658Z ["redis-server","--appendonly","no"] Up About a minute (healthy)
dbsize: 4 rdb_last_bgsave_status:ok aof_enabled:0
/data: appendonlydir dump.rdb
@@ -0,0 +1,19 @@
deployed apps: [('bookstack', 'running'), ('jellyfin', 'running'), ('paperless-ngx', 'running'), ('plex', 'running'), ('privatebin', 'running'), ('prowlarr', 'running'), ('qbittorrent', 'running'), ('radarr', 'running'), ('sonarr', 'running'), ('transmission', 'running')]
storage paths: 404 {"_raw": "404 page not found\n"}
gitea.dooplex.hu/admin/felhom-controller:0.325.0
gitea.dooplex.hu/admin/felhom-controller:0.325.0 Up 30 minutes (healthy)
24: repo_url: file:///opt/docker/felhom-controller/drill-catalog.git
-rw------- 1 root root 3042 Oct 14 14:04 controller.yaml
-rw------- 1 root root 3044 Oct 4 19:41 controller.yaml.pre-media-2026-10-14
drwxr-xr-x 7 root root 4096 Oct 15 07:59 drill-catalog.git
NAME SIZE MOUNTPOINT
sda 200G
|-sda1 1007K
|-sda2 1G
`-sda3 199G
sdb 50G /mnt/felhom-drives/adatlemez
sdc 100G /mnt/felhom-drives/media_a
sdd 100G /mnt/felhom-drives/media_b
sde 50G /mnt/felhom-drives/media_c
sdf 20G /mnt/felhom-drives/media_d
@@ -0,0 +1,35 @@
== qm config 341 (before) 2026-10-17T08:50:52Z
bios: ovmf
boot: order=scsi0
cores: 4
cpu: host
efidisk0: nvme-scratch:341/vm-341-disk-0.raw,efitype=4m,pre-enrolled-keys=0,size=528K
machine: q35
memory: 8192
meta: creation-qemu=11.0.0,ctime=1791141969
name: night1004-tester1
net0: virtio=BC:24:11:AC:E3:F9,bridge=vmbr0
onboot: 1
ostype: l26
scsi0: nvme-scratch:341/vm-341-disk-1.raw,size=200G
scsi1: nvme-scratch:341/vm-341-disk-2.raw,size=50G
scsi2: nvme-scratch:341/vm-341-disk-3.raw,backup=0,size=100G
scsi3: nvme-scratch:341/vm-341-disk-4.raw,backup=0,size=100G
scsi4: nvme-scratch:341/vm-341-disk-5.raw,backup=0,size=50G
scsi5: nvme-scratch:341/vm-341-disk-6.raw,backup=0,size=20G
scsihw: virtio-scsi-single
smbios1: uuid=451c8d94-abf2-46e4-a278-b579a9f315b5
vga: std
vmgenid: acdf89db-a810-445c-9d88-7bccd688d3c1
== pvesm list nvme-scratch (before)
Volid Format Type Size VMID
nvme-scratch:341/vm-341-disk-0.raw raw images 540672 341
nvme-scratch:341/vm-341-disk-1.raw raw images 214748364800 341
nvme-scratch:341/vm-341-disk-2.raw raw images 53687091200 341
nvme-scratch:341/vm-341-disk-3.raw raw images 107374182400 341
nvme-scratch:341/vm-341-disk-4.raw raw images 107374182400 341
nvme-scratch:341/vm-341-disk-5.raw raw images 53687091200 341
nvme-scratch:341/vm-341-disk-6.raw raw images 21474836480 341
nvme-scratch:9202/vm-9202-disk-2.raw raw rootdir 34359738368 9202
nvme-scratch:9202/vm-9202-disk-3.raw raw rootdir 75161927680 9202
nvme-scratch:9401/vm-9401-disk-0.raw raw rootdir 64424509440 9401
@@ -0,0 +1,5 @@
--- saved
+++ current
@@ -24 +24 @@
- repo_url (repo_url value: https://gitea.dooplex.hu/admin/app-catalog-felhom.eu.git)
+ repo_url (repo_url value: file:///opt/docker/felhom-controller/drill-catalog.git)
@@ -0,0 +1,22 @@
RESTORED-IDENTICAL
24: repo_url: https://gitea.dooplex.hu/admin/app-catalog-felhom.eu.git
2026/10/17 08:57:35 [INFO] [sync] Updated vikunja/.felhom.yml
2026/10/17 08:57:35 [INFO] [sync] Updated wanderer/.felhom.yml
2026/10/17 08:57:35 [INFO] [sync] Updated wger/.felhom.yml
2026/10/17 08:57:35 [INFO] [sync] Updated wishlist/.felhom.yml
2026/10/17 08:57:35 [INFO] [sync] Updated zipline/.felhom.yml
2026/10/17 08:57:35 [INFO] [sync] catalog moved 6589376258d9 -> 5d9450b0660a (0 new, 64 stack dir(s) changed)
2026/10/17 08:57:35 [INFO] [sync] Catalog sync complete
2026/10/17 08:57:35 [INFO] [sync] Initial sync: Sablonok frissítve — frissítve: actualbudget, adventurelog, audiobookshelf, bentopdf, bookstack, calcom, calibre-web, claper, code-server, crafty-controller, dawarich, docmost, ghost, gitea, glance, gokapi, grafana, gramps-web, grimmory, grocy, home-assistant, homebox, homepage, immich, jellyfin, karakeep, kimai, komga, lubelogger, mealie, metube, n8n, navidrome, nextcloud, nzbget, onlyoffice, opengist, outline, paperless-ngx, papra, plant-it, plex, privatebin, prowlarr, qbittorrent, radarr, radicale, rallly, recipe-importer, romm, sabnzbd, seerr, sonarr, sparkyfitness, tandoor, termix, transmission, uptime-kuma, vaultwarden, vikunja, wanderer, wger, wishlist, zipline
24: repo_url: https://gitea.dooplex.hu/admin/app-catalog-felhom.eu.git
25: sync_interval: 15m
-rw------- 1 root root 3044 Oct 4 19:41 /var/lib/docker/volumes/felhom-controller-data/_data/controller.yaml.pre-media-2026-10-14
mirror main 65893762 DRILL media build: the seven media templates = live + the media_library marker (per-drive binds by the controller, no literal drive paths); Plex: no code at install, accept-JSON probe, ADVERTISE_IP; Transmission incomplete folder off at start — drill catalog only (Tester 1 proof, Part G)
cache HEAD 5d9450b Redis snapshots, not append-only, on five apps (R-1096); gate redis-persistence
https://gitea.dooplex.hu/admin/app-catalog-felhom.eu.git
11M /var/lib/docker/volumes/felhom-controller-data/_data/drill-catalog.git
ls: cannot access '/var/lib/docker/volumes/felhom-controller-data/_data/drill-catalog.git': No such file or directory
no-drill-left
@@ -0,0 +1,16 @@
== inside Tester 1: clean unmount of the four test mounts 2026-10-17T08:58:51Z
stopped mnt-media_a.mount
stopped mnt-media_b.mount
stopped mnt-media_c.mount
stopped mnt-media_d.mount
no /mnt/media_* mounted
== demo-hp: qm set 341 --delete scsi2,scsi3,scsi4,scsi5
update VM 341: -delete scsi2,scsi3,scsi4,scsi5
rc=0
scsi0: nvme-scratch:341/vm-341-disk-1.raw,size=200G
scsi1: nvme-scratch:341/vm-341-disk-2.raw,size=50G
scsihw: virtio-scsi-single
unused0: nvme-scratch:341/vm-341-disk-3.raw
unused1: nvme-scratch:341/vm-341-disk-4.raw
unused2: nvme-scratch:341/vm-341-disk-5.raw
unused3: nvme-scratch:341/vm-341-disk-6.raw
@@ -0,0 +1,56 @@
pvesm free nvme-scratch:341/vm-341-disk-3.raw
Removed volume 'nvme-scratch:341/vm-341-disk-3.raw'
rc=0
pvesm free nvme-scratch:341/vm-341-disk-4.raw
Removed volume 'nvme-scratch:341/vm-341-disk-4.raw'
rc=0
pvesm free nvme-scratch:341/vm-341-disk-5.raw
Removed volume 'nvme-scratch:341/vm-341-disk-5.raw'
rc=0
pvesm free nvme-scratch:341/vm-341-disk-6.raw
Removed volume 'nvme-scratch:341/vm-341-disk-6.raw'
rc=0
== qm config 341 (after free)
bios: ovmf
boot: order=scsi0
cores: 4
cpu: host
efidisk0: nvme-scratch:341/vm-341-disk-0.raw,efitype=4m,pre-enrolled-keys=0,size=528K
machine: q35
memory: 8192
meta: creation-qemu=11.0.0,ctime=1791141969
name: night1004-tester1
net0: virtio=BC:24:11:AC:E3:F9,bridge=vmbr0
onboot: 1
ostype: l26
scsi0: nvme-scratch:341/vm-341-disk-1.raw,size=200G
scsi1: nvme-scratch:341/vm-341-disk-2.raw,size=50G
scsihw: virtio-scsi-single
smbios1: uuid=451c8d94-abf2-46e4-a278-b579a9f315b5
unused0: nvme-scratch:341/vm-341-disk-3.raw
unused1: nvme-scratch:341/vm-341-disk-4.raw
unused2: nvme-scratch:341/vm-341-disk-5.raw
unused3: nvme-scratch:341/vm-341-disk-6.raw
vga: std
vmgenid: acdf89db-a810-445c-9d88-7bccd688d3c1
== pvesm list nvme-scratch (after)
Volid Format Type Size VMID
nvme-scratch:341/vm-341-disk-0.raw raw images 540672 341
nvme-scratch:341/vm-341-disk-1.raw raw images 214748364800 341
nvme-scratch:341/vm-341-disk-2.raw raw images 53687091200 341
nvme-scratch:9202/vm-9202-disk-2.raw raw rootdir 34359738368 9202
nvme-scratch:9202/vm-9202-disk-3.raw raw rootdir 75161927680 9202
nvme-scratch:9401/vm-9401-disk-0.raw raw rootdir 64424509440 9401
update VM 341: -delete unused0,unused1,unused2,unused3
disk image '/mnt/hdd_1/images/341/vm-341-disk-3.raw' does not exist
disk image '/mnt/hdd_1/images/341/vm-341-disk-4.raw' does not exist
disk image '/mnt/hdd_1/images/341/vm-341-disk-5.raw' does not exist
disk image '/mnt/hdd_1/images/341/vm-341-disk-6.raw' does not exist
rc=0
== qm config 341 (final)
efidisk0: nvme-scratch:341/vm-341-disk-0.raw,efitype=4m,pre-enrolled-keys=0,size=528K
memory: 8192
scsi0: nvme-scratch:341/vm-341-disk-1.raw,size=200G
scsi1: nvme-scratch:341/vm-341-disk-2.raw,size=50G
scsihw: virtio-scsi-single
status: running
@@ -0,0 +1,38 @@
NAME SIZE SERIAL MOUNTPOINTS
sda 200G drive-scsi0
|-sda1 1007K
|-sda2 1G /boot/efi
`-sda3 199G
|-pve-swap 7.7G [SWAP]
|-pve-root 59.8G /mnt/felhom-drives
| /
|-pve-data_tmeta 1.2G
| `-pve-data-tpool 113.2G
| |-pve-data 113.2G
| |-pve-vm--9201--disk--0 32G
| `-pve-vm--9201--disk--1 70G
`-pve-data_tdata 113.2G
`-pve-data-tpool 113.2G
|-pve-data 113.2G
|-pve-vm--9201--disk--0 32G
`-pve-vm--9201--disk--1 70G
sdb 50G drive-scsi1 /mnt/felhom-drives/adatlemez
/mnt/adatlemez
sdc 100G drive-scsi2 /mnt/media_a
sdd 100G drive-scsi3 /mnt/media_b
sde 50G drive-scsi4 /mnt/media_c
sdf 20G drive-scsi5 /mnt/media_d
/mnt/media_c /dev/sde
/mnt/media_a /dev/sdc
/mnt/media_d /dev/sdf
/mnt/adatlemez /dev/sdb
/mnt/media_b /dev/sdd
/mnt/felhom-drives /dev/mapper/pve-root[/mnt/felhom-drives]
/mnt/felhom-drives/adatlemez /dev/sdb[/felhom-data]
Name Type Status Total (KiB) Used (KiB) Available (KiB) %
felhom-pbs pbs active 0 0 0 0.00%
local dir active 61429556 19311648 38965012 31.44%
local-lvm lvmthin active 118673408 15273267 103400140 12.87%
mp0: local-lvm:vm-9201-disk-1,mp=/var/lib/felhom,backup=1,size=70G
mp8: /mnt/felhom-drives,mp=/mnt/felhom-drives
mp9: /var/lib/felhom-agent/guests/9201/bootstrap,mp=/etc/felhom-bootstrap,ro=1
@@ -0,0 +1 @@
6723057 DRILL: tree = live main 5d9450b — R-1022 teardown; no box follows the drill (2026-10-17)
@@ -0,0 +1,4 @@
hp guest 9201: repo_url: https://gitea.dooplex.hu/admin/app-catalog-felhom.eu.git
hp guest 9202: repo_url: https://gitea.dooplex.hu/admin/app-catalog-felhom.eu.git
felhom-pve guest 9201: repo_url: https://gitea.dooplex.hu/admin/app-catalog-felhom.eu.git
-J hp root@192.168.0.154 guest 9201: repo_url: https://gitea.dooplex.hu/admin/app-catalog-felhom.eu.git
@@ -0,0 +1,10 @@
== guest 9201
containers: 10 not healthy/running: none
bookstack bookstack-db cloudflared felhom-controller filebrowser paperless-postgres paperless-redis paperless-webserver privatebin traefik
gitea.dooplex.hu/admin/felhom-controller:0.325.0
== host: failed units, agent warnings since the detach
Oct 17 10:58:56 felhom felhom-agent[1278]: time=2026-10-17T10:58:56.627+02:00 level=WARN msg="storage: watchdog detected target state change" target=4ebfd36d-87d3-4b63-839e-a5a710fc799a from=attached to=disconnected
Oct 17 10:58:56 felhom felhom-agent[1278]: time=2026-10-17T10:58:56.627+02:00 level=WARN msg="storage: watchdog detected target state change" target=e15652d5-0aa7-4eb8-93a1-afb2839d527c from=attached to=disconnected
Oct 17 10:58:56 felhom felhom-agent[1278]: time=2026-10-17T10:58:56.627+02:00 level=WARN msg="storage: watchdog detected target state change" target=86f33f9c-1022-43d8-95eb-f9a6ec9eb923 from=attached to=disconnected
Oct 17 10:58:56 felhom felhom-agent[1278]: time=2026-10-17T10:58:56.627+02:00 level=WARN msg="storage: watchdog detected target state change" target=8a31a462-ff15-4be2-9aeb-9620b99c7f77 from=attached to=disconnected
dashboard /login: 200
@@ -0,0 +1,54 @@
10:52:02 deployed apps: ['bookstack', 'jellyfin', 'paperless-ngx', 'plex', 'privatebin', 'prowlarr', 'qbittorrent', 'radarr', 'sonarr', 'transmission']
10:52:06 gitea.dooplex.hu/admin/felhom-controller:0.325.0
24: repo_url: file:///opt/docker/felhom-controller/drill-catalog.git
/mnt/felhom-drives
/mnt/felhom-drives
/mnt/felhom-drives/media_a
/mnt/felhom-drives/media_a
/mnt/felhom-drives/adatlemez
/mnt/felhom-drives/adatlemez
/mnt/felhom-drives/media_c
/mnt/felhom-drives/media_c
/mnt/felhom-drives/media_d
/mnt/felhom-drives/media_d
/mnt/felhom-drives/media_b
/mnt/felhom-drives/media_b
storage paths: [('/mnt/felhom-drives/adatlemez', 'live'), ('/mnt/felhom-drives/media_a', 'live'), ('/mnt/felhom-drives/media_b', 'live'), ('/mnt/felhom-drives/media_c', 'live'), ('/mnt/felhom-drives/media_d', 'live')]
10:52:46 sonarr: stop -> 200; remove (keep data, keep backups) -> 200 {"ok": true, "data": {"removed": "sonarr", "volumes_removed": ["sonarr_sonarr_config"], "hdd_paths_removed": [], "hdd_paths_preserved": [], "userdata_kept": ["/mnt/felhom-drives/media_a/userdata/media (30G)"], "verified": true}, "message": "Stack sonarr remove
10:53:24 radarr: stop -> 200; remove (keep data, keep backups) -> 200 {"ok": true, "data": {"removed": "radarr", "volumes_removed": ["radarr_radarr_config"], "hdd_paths_removed": [], "hdd_paths_preserved": [], "userdata_kept": ["/mnt/felhom-drives/media_a/userdata/media (30G)"], "verified": true}, "message": "Stack radarr remove
10:53:58 qbittorrent: stop -> 200; remove (keep data, keep backups) -> 200 {"ok": true, "data": {"removed": "qbittorrent", "volumes_removed": ["qbittorrent_qbittorrent_config"], "hdd_paths_removed": [], "hdd_paths_preserved": [], "userdata_kept": ["/mnt/felhom-drives/media_a/userdata/media/torrents (19G)"], "verified": true}, "messag
10:54:34 transmission: stop -> 200; remove (keep data, keep backups) -> 200 {"ok": true, "data": {"removed": "transmission", "volumes_removed": ["transmission_transmission_config"], "hdd_paths_removed": [], "hdd_paths_preserved": [], "userdata_kept": ["/mnt/felhom-drives/media_a/userdata/media/transmission (12G)", "/mnt/felhom-drives/
10:55:15 plex: stop -> 200; remove (keep data, keep backups) -> 200 {"ok": true, "data": {"removed": "plex", "volumes_removed": ["plex_plex_config", "plex_plex_transcode"], "hdd_paths_removed": [], "hdd_paths_preserved": [], "userdata_kept": ["/mnt/felhom-drives/media_a/userdata/media (30G)"], "verified": true}, "message": "St
10:55:48 jellyfin: stop -> 200; remove (keep data, keep backups) -> 200 {"ok": true, "data": {"removed": "jellyfin", "volumes_removed": ["jellyfin_jellyfin_cache", "jellyfin_jellyfin_config"], "hdd_paths_removed": [], "hdd_paths_preserved": [], "userdata_kept": ["/mnt/felhom-drives/media_a/userdata/media (30G)"], "verified": true}
10:56:26 prowlarr: stop -> 200; remove (keep data, keep backups) -> 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"}
10:56:26 deployed apps: ['bookstack', 'paperless-ngx', 'privatebin']
10:56:30 gitea.dooplex.hu/admin/felhom-controller:0.325.0
24: repo_url: file:///opt/docker/felhom-controller/drill-catalog.git
/mnt/felhom-drives
/mnt/felhom-drives
/mnt/felhom-drives/media_a
/mnt/felhom-drives/media_a
/mnt/felhom-drives/adatlemez
/mnt/felhom-drives/adatlemez
/mnt/felhom-drives/media_c
/mnt/felhom-drives/media_c
/mnt/felhom-drives/media_d
/mnt/felhom-drives/media_d
/mnt/felhom-drives/media_b
/mnt/felhom-drives/media_b
storage paths: [('/mnt/felhom-drives/adatlemez', 'live'), ('/mnt/felhom-drives/media_a', 'live'), ('/mnt/felhom-drives/media_b', 'live'), ('/mnt/felhom-drives/media_c', 'live'), ('/mnt/felhom-drives/media_d', 'live')]
10:56:38 decommission media_a -> 200 {"data": {"decommissioned": true, "stopped_apps": null, "where": "/mnt/felhom-drives/media_a"}, "ok": true}
10:56:46 decommission media_b -> 200 {"data": {"decommissioned": true, "stopped_apps": null, "where": "/mnt/felhom-drives/media_b"}, "ok": true}
10:56:54 decommission media_c -> 200 {"data": {"decommissioned": true, "stopped_apps": null, "where": "/mnt/felhom-drives/media_c"}, "ok": true}
10:57:01 decommission media_d -> 200 {"data": {"decommissioned": true, "stopped_apps": null, "where": "/mnt/felhom-drives/media_d"}, "ok": true}
10:57:06 deployed apps: ['bookstack', 'paperless-ngx', 'privatebin']
10:57:10 gitea.dooplex.hu/admin/felhom-controller:0.325.0
24: repo_url: file:///opt/docker/felhom-controller/drill-catalog.git
/mnt/felhom-drives
/mnt/felhom-drives
/mnt/felhom-drives/adatlemez
/mnt/felhom-drives/adatlemez
storage paths: [('/mnt/felhom-drives/adatlemez', 'live'), ('/mnt/felhom-drives/media_a', 'decommissioned'), ('/mnt/felhom-drives/media_b', 'decommissioned'), ('/mnt/felhom-drives/media_c', 'decommissioned'), ('/mnt/felhom-drives/media_d', 'decommissioned')]
@@ -0,0 +1,3 @@
--- FAIL: TestFileBrowserAdmin_R977_DefaultBackOnANewRunIsReplaced (0.00s)
filebrowser_password_test.go:183: the default login came back on a new run and was left
FAIL
@@ -0,0 +1 @@
--- FAIL: TestFileBrowserAdmin_R977_NewRunIsWaitedForInTheSameTick (0.00s)
@@ -0,0 +1,2 @@
REFUSED: docmost: .felhom.yml mem_limit "896M" is not the sum of the compose limits 768+256+128=1152M
mem-limit-sum: 1 of 65 template(s) refused — set .felhom.yml resources.mem_limit to the sum of the compose limits (and show the arithmetic in a comment, like paperless-ngx)
@@ -0,0 +1,11 @@
POST /api/sync -> 429
before: memory: 512M
/docmost 536870912
restart -> 200
after: /docmost 536870912 healthy
/docmost-postgres 268435456 healthy
/docmost-redis 134217728 healthy state: running
POST /api/sync -> 200 {'ok': True, 'data': {'ok': True, 'updated': ['docmost', 'grafana', 'romm', 'tandoor', 'termix', 'uptime-kuma'], 'messag
applied: memory: 768M
restart -> 200
after: /docmost 805306368 healthy state: running
@@ -0,0 +1,31 @@
R-1119 — proposed mem_request per app (typical use from sizing-2026-10-13 catalog-check.json, rounded up:
under 100 MB to 10, under 500 MB to 50, else to 100). NOT applied — operator: limits now, requests wait.
app now typical new source
adventurelog 100MB 361MB 400MB telemetry
bookstack 150MB 159MB 200MB telemetry
calcom 200MB 800MB 800MB onboarding
claper 100MB 248MB 250MB onboarding
docmost 200MB 415MB 450MB telemetry
grafana 100MB 220MB 250MB onboarding
home-assistant 256MB 318MB 350MB onboarding
homepage 50MB 82MB 90MB measured
kimai 100MB 163MB 200MB telemetry
komga 200MB 442MB 450MB onboarding
mealie 200MB 273MB 300MB onboarding
nextcloud 256MB 314MB 350MB onboarding
outline 200MB 282MB 300MB onboarding
paperless-ngx 500MB 568MB 600MB telemetry
papra 256MB 266MB 300MB onboarding
privatebin 30MB 40MB 40MB telemetry
recipe-importer 30MB 63MB 70MB measured
romm 300MB 528MB 600MB telemetry
seerr 100MB 166MB 200MB measured
tandoor 512MB 868MB 900MB onboarding
termix 30MB 102MB 150MB measured
uptime-kuma 50MB 103MB 150MB onboarding
zipline 100MB 196MB 200MB onboarding
Effect on the smallest supported box (8 GB: guest 4,096 MiB, reserved 384 → 3,712 MB usable; stacks/deploy.go:1549):
household set (immich, jellyfin, nextcloud, home-assistant, vaultwarden, paperless-ngx): 3,622 MB now → 3,910 MB
whole catalog (65 apps): 15,028 MB now → 18,608 MB; the largest single new request: 900 MB (tandoor) — every app alone fits.
@@ -0,0 +1 @@
default login -> HTTP 401 | box state: generated 2026-09-15T08:16:35Z | filebrowser started 2026-10-17T06:54:56.265230678Z
@@ -0,0 +1,12 @@
volume before: 1
removed filebrowser + filebrowser_filebrowser_data at 09:08:51
+1m: default login: (filebrowser not running)
+2m: default login: (filebrowser not running)
+3m: default login: (filebrowser not running)
+4m: default login -> HTTP 200 | box state: generated 2026-09-15T08:16:35Z | filebrowser started 2026-10-17T09:12:31.362830472Z
+5m: default login -> HTTP 200 | box state: generated 2026-09-15T08:16:35Z | filebrowser started 2026-10-17T09:12:31.362830472Z
+6m: default login -> HTTP 200 | box state: generated 2026-09-15T08:16:35Z | filebrowser started 2026-10-17T09:12:31.362830472Z
+7m: default login -> HTTP 200 | box state: generated 2026-09-15T08:16:35Z | filebrowser started 2026-10-17T09:12:31.362830472Z
+8m: default login -> HTTP 200 | box state: generated 2026-09-15T08:16:35Z | filebrowser started 2026-10-17T09:12:31.362830472Z
+9m: default login -> HTTP 200 | box state: generated 2026-09-15T08:16:35Z | filebrowser started 2026-10-17T09:12:31.362830472Z
+10m: default login -> HTTP 200 | box state: generated 2026-09-15T08:16:35Z | filebrowser started 2026-10-17T09:12:31.362830472Z
@@ -0,0 +1,10 @@
default login -> HTTP 200 | box state: generated 2026-09-15T08:16:35Z | filebrowser started 2026-10-17T09:12:31.362830472Z
controller -> 0.326.0-rc.1 at 09:19:34
+30s: default login -> HTTP 401 | box state: generated 2026-10-17T09:19:35Z | filebrowser started 2026-10-17T09:12:31.362830472Z
+60s: default login -> HTTP 401 | box state: generated 2026-10-17T09:19:35Z | filebrowser started 2026-10-17T09:12:31.362830472Z
+90s: default login -> HTTP 401 | box state: generated 2026-10-17T09:19:35Z | filebrowser started 2026-10-17T09:12:31.362830472Z
+120s: default login -> HTTP 401 | box state: generated 2026-10-17T09:19:35Z | filebrowser started 2026-10-17T09:12:31.362830472Z
+150s: default login -> HTTP 401 | box state: generated 2026-10-17T09:19:35Z | filebrowser started 2026-10-17T09:12:31.362830472Z
+180s: default login -> HTTP 401 | box state: generated 2026-10-17T09:19:35Z | filebrowser started 2026-10-17T09:12:31.362830472Z
2026/10/17 09:19:35 filebrowser_password.go:121: [WARN] [infra] filebrowser: admin/admin logs in again on a new FileBrowser run (recorded state "generated") — its data was re-created; replacing it (R-977)
2026/10/17 09:19:35 filebrowser_password.go:178: [INFO] [infra] filebrowser: admin/admin replaced by a generated password (value never logged); verified new=200 admin=401
@@ -0,0 +1,14 @@
volume before: 1
removed filebrowser + filebrowser_filebrowser_data at 09:22:44
+1m: default login: (filebrowser not running)
+2m: default login -> HTTP 200 | box state: generated 2026-10-17T09:19:35Z | filebrowser started 2026-10-17T09:24:35.302615766Z
+3m: default login -> HTTP 200 | box state: generated 2026-10-17T09:19:35Z | filebrowser started 2026-10-17T09:24:35.302615766Z
+4m: default login -> HTTP 200 | box state: generated 2026-10-17T09:19:35Z | filebrowser started 2026-10-17T09:24:35.302615766Z
+5m: default login -> HTTP 200 | box state: generated 2026-10-17T09:19:35Z | filebrowser started 2026-10-17T09:24:35.302615766Z
+6m: default login -> HTTP 200 | box state: generated 2026-10-17T09:19:35Z | filebrowser started 2026-10-17T09:24:35.302615766Z
+7m: default login -> HTTP 401 | box state: generated 2026-10-17T09:29:35Z | filebrowser started 2026-10-17T09:24:35.302615766Z
+8m: default login -> HTTP 401 | box state: generated 2026-10-17T09:29:35Z | filebrowser started 2026-10-17T09:24:35.302615766Z
+9m: default login -> HTTP 401 | box state: generated 2026-10-17T09:29:35Z | filebrowser started 2026-10-17T09:24:35.302615766Z
+10m: default login -> HTTP 401 | box state: generated 2026-10-17T09:29:35Z | filebrowser started 2026-10-17T09:24:35.302615766Z
2026/10/17 09:29:35 filebrowser_password.go:121: [WARN] [infra] filebrowser: admin/admin logs in again on a new FileBrowser run (recorded state "generated") — its data was re-created; replacing it (R-977)
2026/10/17 09:29:35 filebrowser_password.go:178: [INFO] [infra] filebrowser: admin/admin replaced by a generated password (value never logged); verified new=200 admin=401
@@ -0,0 +1,16 @@
controller: gitea.dooplex.hu/admin/felhom-controller:0.326.0-rc.2 Up 40 seconds (healthy)
default login -> HTTP 401 | box state: generated 2026-10-17T09:29:35Z | filebrowser started 2026-10-17T09:24:35.302615766Z
volume before: 1
removed filebrowser + filebrowser_filebrowser_data at 09:42:54
+1m: default login: (filebrowser not running)
+2m: default login: (filebrowser not running)
+3m: default login: (filebrowser not running)
+4m: default login: (filebrowser not running)
+5m: default login -> HTTP 401 | box state: generated 2026-10-17T09:47:15Z | filebrowser started 2026-10-17T09:47:15.109818275Z
+6m: default login -> HTTP 401 | box state: generated 2026-10-17T09:47:15Z | filebrowser started 2026-10-17T09:47:15.109818275Z
+7m: default login -> HTTP 401 | box state: generated 2026-10-17T09:47:15Z | filebrowser started 2026-10-17T09:47:15.109818275Z
+8m: default login -> HTTP 401 | box state: generated 2026-10-17T09:47:15Z | filebrowser started 2026-10-17T09:47:15.109818275Z
+9m: default login -> HTTP 401 | box state: generated 2026-10-17T09:47:15Z | filebrowser started 2026-10-17T09:47:15.109818275Z
+10m: default login -> HTTP 401 | box state: generated 2026-10-17T09:47:15Z | filebrowser started 2026-10-17T09:47:15.109818275Z
2026/10/17 09:47:17 filebrowser_password.go:149: [WARN] [infra] filebrowser: admin/admin logs in again on a new FileBrowser run (recorded state "generated") — its data was re-created; replacing it (R-977)
2026/10/17 09:47:17 filebrowser_password.go:206: [INFO] [infra] filebrowser: admin/admin replaced by a generated password (value never logged); verified new=200 admin=401
@@ -0,0 +1,15 @@
=== hp
containers: 24 not healthy/running: none
2026/10/17 09:54:23 updater.go:855: [INFO] [selfupdate] Post-update startup: update successful (0.325.0 → 0.326.0)
filebrowser state: generated
=== felhom-pve
containers: 9 not healthy/running: none
2026/10/17 09:54:12 [INFO] [selfupdate] Post-update startup: update successful (0.325.0 → 0.326.0)
filebrowser state: generated
=== -J hp root@192.168.0.154
containers: 10 not healthy/running: none
2026/10/17 09:54:22 [INFO] [selfupdate] Post-update startup: update successful (0.325.0 → 0.326.0)
filebrowser state: generated
felhom.enkisfelhom.hu /login: 200
felhom.demo-felhom.eu /login: 200
felhom.enkicsifelhom.hu /login: 200
@@ -0,0 +1,4 @@
integrity: ok
('min_controller_version', '0.326.0')
('min_controller_version_declared_min_agent', '0.326.0=0.158.1')
per-box floors still set: []
@@ -0,0 +1,5 @@
global floor 2026-10-17T09:55:58Z: HTTP/1.1 303 See Other Location: /configuration?flash=floor_set
clear per-box tester-1: HTTP/1.1 303 See Other Location: /customers/tester-1?flash=floor_set
clear per-box demo-hp: HTTP/1.1 303 See Other Location: /customers/demo-hp?flash=floor_set
clear per-box demo-felhom: HTTP/1.1 303 See Other Location: /customers/demo-felhom?flash=floor_set
hub /configuration page: 5 0.158.1 3 0.326.0
@@ -0,0 +1,33 @@
control NEGATIVE (a stub answering 200 over plain http): convicted, as it must (200 -)
== tester-1 (enkicsifelhom.hu): 6 public name(s)
OK control POSITIVE http://felhom.enkicsifelhom.hu/r1033-check?q=1 -> 301 https://felhom.enkicsifelhom.hu/r1033-check?q=1
OK http://files.enkicsifelhom.hu/r1033-check?q=1 -> 301 https://files.enkicsifelhom.hu/r1033-check?q=1
OK http://no-such-name-r1033.enkicsifelhom.hu/r1033-check?q=1 -> 301 https://no-such-name-r1033.enkicsifelhom.hu/r1033-check?q=1
OK http://paperless.enkicsifelhom.hu/r1033-check?q=1 -> 301 https://paperless.enkicsifelhom.hu/r1033-check?q=1
OK http://paste.enkicsifelhom.hu/r1033-check?q=1 -> 301 https://paste.enkicsifelhom.hu/r1033-check?q=1
OK http://wiki.enkicsifelhom.hu/r1033-check?q=1 -> 301 https://wiki.enkicsifelhom.hu/r1033-check?q=1
== demo-hp (enkisfelhom.hu): 14 public name(s)
OK http://arcade.enkisfelhom.hu/r1033-check?q=1 -> 301 https://arcade.enkisfelhom.hu/r1033-check?q=1
OK http://books.enkisfelhom.hu/r1033-check?q=1 -> 301 https://books.enkisfelhom.hu/r1033-check?q=1
OK http://docs.enkisfelhom.hu/r1033-check?q=1 -> 301 https://docs.enkisfelhom.hu/r1033-check?q=1
OK http://felhom.enkisfelhom.hu/r1033-check?q=1 -> 301 https://felhom.enkisfelhom.hu/r1033-check?q=1
OK http://files.enkisfelhom.hu/r1033-check?q=1 -> 301 https://files.enkisfelhom.hu/r1033-check?q=1
OK http://gist.enkisfelhom.hu/r1033-check?q=1 -> 301 https://gist.enkisfelhom.hu/r1033-check?q=1
OK http://ha.enkisfelhom.hu/r1033-check?q=1 -> 301 https://ha.enkisfelhom.hu/r1033-check?q=1
OK http://no-such-name-r1033.enkisfelhom.hu/r1033-check?q=1 -> 301 https://no-such-name-r1033.enkisfelhom.hu/r1033-check?q=1
OK http://papir.enkisfelhom.hu/r1033-check?q=1 -> 301 https://papir.enkisfelhom.hu/r1033-check?q=1
OK http://paste.enkisfelhom.hu/r1033-check?q=1 -> 301 https://paste.enkisfelhom.hu/r1033-check?q=1
OK http://pdf.enkisfelhom.hu/r1033-check?q=1 -> 301 https://pdf.enkisfelhom.hu/r1033-check?q=1
OK http://plex.enkisfelhom.hu/r1033-check?q=1 -> 301 https://plex.enkisfelhom.hu/r1033-check?q=1
OK http://travel.enkisfelhom.hu/r1033-check?q=1 -> 301 https://travel.enkisfelhom.hu/r1033-check?q=1
OK http://wiki.enkisfelhom.hu/r1033-check?q=1 -> 301 https://wiki.enkisfelhom.hu/r1033-check?q=1
== demo-felhom (demo-felhom.eu): 8 public name(s)
OK http://felhom.demo-felhom.eu/r1033-check?q=1 -> 301 https://felhom.demo-felhom.eu/r1033-check?q=1
OK http://files.demo-felhom.eu/r1033-check?q=1 -> 301 https://files.demo-felhom.eu/r1033-check?q=1
OK http://gist.demo-felhom.eu/r1033-check?q=1 -> 301 https://gist.demo-felhom.eu/r1033-check?q=1
OK http://no-such-name-r1033.demo-felhom.eu/r1033-check?q=1 -> 301 https://no-such-name-r1033.demo-felhom.eu/r1033-check?q=1
OK http://prowlarr.demo-felhom.eu/r1033-check?q=1 -> 301 https://prowlarr.demo-felhom.eu/r1033-check?q=1
OK http://radarr.demo-felhom.eu/r1033-check?q=1 -> 301 https://radarr.demo-felhom.eu/r1033-check?q=1
OK http://sonarr.demo-felhom.eu/r1033-check?q=1 -> 301 https://sonarr.demo-felhom.eu/r1033-check?q=1
OK http://torrent.demo-felhom.eu/r1033-check?q=1 -> 301 https://torrent.demo-felhom.eu/r1033-check?q=1
== every public name redirects http -> https
@@ -0,0 +1,3 @@
per-box tester-1 2026-10-17T09:54:10Z: HTTP/1.1 303 See Other Location: /customers/tester-1?flash=floor_set
per-box demo-hp 2026-10-17T09:54:10Z: HTTP/1.1 303 See Other Location: /customers/demo-hp?flash=floor_set
per-box demo-felhom 2026-10-17T09:54:10Z: HTTP/1.1 303 See Other Location: /customers/demo-felhom?flash=floor_set
@@ -0,0 +1,22 @@
#!/bin/bash
# fbprobe.sh — R-977, run INSIDE a guest. Prints only HTTP status codes and the box's recorded state — never a password.
# The default credential is FileBrowser's public default; it goes to curl on STDIN as a header, never on a command line.
# fbprobe.sh probe the default login's status + the box's recorded state + FileBrowser's start time
# fbprobe.sh recreate remove FileBrowser AND its data volume (what a lost volume looks like), then wait up to
# 10 min for the box itself to bring FileBrowser back (no hand start), probing each minute
set -u
S=/var/lib/docker/volumes/felhom-controller-data/_data/data/settings.json
state() { python3 -c "import json;d=json.load(open('$S'));print(d.get('filebrowser_admin_state'), d.get('filebrowser_admin_decided_at'))"; }
probe() {
ip=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}} {{end}}' filebrowser 2>/dev/null | awk '{print $1}')
if [ -z "$ip" ]; then echo "default login: (filebrowser not running)"; return; fi
code=$(printf 'X-Password: admin\n' | curl -s -o /dev/null -w '%{http_code}' --max-time 10 -X POST -H @- "http://$ip:80/api/auth/login?username=admin")
echo "default login -> HTTP $code | box state: $(state) | filebrowser started $(docker inspect -f '{{.State.StartedAt}}' filebrowser)"
}
case "$1" in
probe) probe ;;
recreate)
echo "volume before: $(docker volume ls -q | grep -c '^filebrowser_filebrowser_data$')"
docker stop filebrowser >/dev/null && docker rm filebrowser >/dev/null && docker volume rm filebrowser_filebrowser_data >/dev/null && echo "removed filebrowser + filebrowser_filebrowser_data at $(date -u +%T)"
for i in $(seq 1 10); do sleep 60; echo "+${i}m: $(probe)"; done ;;
esac
@@ -0,0 +1,54 @@
#!/usr/bin/env python3
"""t1teardown.py — R-1022 on Tester 1 through its dashboard's own endpoints (operator word 2026-10-17 10:47).
Env: SC (0600 dir with .ctlpw = Tester 1's dashboard password), EV, TARGET=tester-1. Steps:
apps stop + remove each test app WITHOUT „delete data" (remove_hdd_data=false, remove_backups=false)
drives decommission media_a..media_d („anyway", type-to-confirm = the mount name), the dashboard's call
state deployed apps, storage paths, the controller image and repo_url (read-only)
"""
import json, os, sys, time
sys.path.insert(0, "/mnt/5_hdd/felhom.eu/git/app-catalog-felhom.eu/scripts")
import box_walk as w # noqa: E402
EV = os.environ["EV"]
LOG = open(os.path.join(EV, "t1-console.txt"), "a", buffering=1)
_say = w.say
def say(*a):
_say(*a); LOG.write(time.strftime("%H:%M:%S ") + " ".join(str(x) for x in a) + "\n")
w.say = say
APPS = ["sonarr", "radarr", "qbittorrent", "transmission", "plex", "jellyfin", "prowlarr"]
DRIVES = ["media_a", "media_b", "media_c", "media_d"]
def state():
c, d = w.ctl("GET", "/api/stacks")
dep = sorted(s.get("name") for s in (d.get("data") or []) if s.get("deployed"))
say(f"deployed apps: {dep}")
say(w.guest("cat /etc/felhom-controller-image; grep -n repo_url /var/lib/docker/volumes/felhom-controller-data/_data/controller.yaml; "
"findmnt -rn -o TARGET | grep felhom-drives; python3 -c \"import json;d=json.load(open('/var/lib/docker/volumes/felhom-controller-data/_data/data/settings.json'));"
"print('storage paths:', [(p.get('path'), 'decommissioned' if p.get('decommissioned') else 'live') for p in d.get('storage_paths') or []])\""))
def main():
step = sys.argv[1]
w.login()
if step == "apps":
for a in APPS:
st = w.stack(a)
if not st.get("deployed"):
say(f"{a}: not deployed — skipped"); continue
c1, d1 = w.ctl("POST", f"/api/stacks/{a}/stop")
for _ in range(36):
time.sleep(5)
if w.stack(a).get("state") != "running":
break
c2, d2 = w.ctl("POST", f"/api/stacks/{a}/remove", {"remove_hdd_data": False, "remove_backups": False})
say(f"{a}: stop -> {c1}; remove (keep data, keep backups) -> {c2} {json.dumps(d2, ensure_ascii=False)[:260]}")
state()
elif step == "drives":
for m in DRIVES:
c, d = w.ctl("POST", "/api/storage/decommission", {"where": f"/mnt/felhom-drives/{m}", "mode": "anyway", "mount_name": m})
say(f"decommission {m} -> {c} {json.dumps(d, ensure_ascii=False)[:300]}")
time.sleep(5)
state()
elif step == "state":
state()
main()
+8
View File
@@ -26,6 +26,14 @@
---
## 2026-10-17 — Tester 1 on the live catalog, decoy suites in every runner, memory limits, FileBrowser (controller v0.326.0, catalog `bff82f9`)
| Row | What | Closed | Evidence |
|---|---|---|---|
| **R-977** | **FileBrowser's default password can come back if its data volume is ever re-created, because the box checks it only once; and the tunnel can start before the box is claimed.** (P3) | CLOSED 2026-10-17 for the FileBrowser part — **controller v0.326.0**: the default login is probed once per FileBrowser RUN (StartedAt), not once per box. Measured first on scratch 9202 with 0.324.0: FileBrowser + its data volume removed, the box brought it back by itself, the default login answered 200 for 10 minutes while the box kept „generated”; with 0.326.0-rc.1 it was replaced in 1 s and verified (default 401), and again after a second re-create under the new controller. `TestFileBrowserAdmin_R977_*`, red-proved. The code comment „before a claim there is no tunnel” was false and is corrected. **The tunnel before the claim is a design question, not changed → R-1126.** | `audits/tester1-limits-filebrowser-2026-10-17/` |
| **R-1022** | **Tester 1 follows the drill catalog and carries two test drives — teardown owed (operator ruling (e), 2026-10-14).** (P3) | CLOSED 2026-10-17 — operator word „yes” 10:47. Through Tester 1's dashboard: Sonarr, Radarr, qBittorrent, Transmission, Plex, Jellyfin, Prowlarr removed WITHOUT „delete data” (their drive tags and clients went with them); bookstack, paperless-ngx, privatebin stay. Media A–D decommissioned (200 each). `repoint.py restore`: RESTORED-IDENTICAL, `repo_url` = the live catalog (`5d9450b` synced), `drill-catalog.git` removed (11 MB). demo-hp: the four test mounts stopped cleanly inside the VM, `qm set 341 --delete scsi2,scsi3,scsi4,scsi5`, `pvesm free` of `vm-341-disk-3/-4/-5/-6.raw` BY NAME, the four stale `unused` lines removed; `qm config 341`: scsi0 + scsi1 only, memory 8192. Controller 0.325.0 by the floor (no hand pin). Drill repo tree = live main (`6723057`, a normal commit — no force-push); no box follows it. paperless-ngx restarted: `aof_enabled:0`. Box walk green. **Left for the operator:** remove „plex-k6” on plex.tv (Settings → Authorized Devices). The kept mount units → R-1124. | `audits/tester1-limits-filebrowser-2026-10-17/` |
| **R-1116** | **The controller, agent and felhom.eu gate runners do not run their own decoy suites — the shape that let R-1115 fail unseen for a night.** (P4) | CLOSED 2026-10-17 — controller (`55868cb`, 53 cases, 22 s) and agent (`c52d591`, 30 cases, 21 s; script only) run their decoy suite as the full-run gate `gate-decoys`, count tests updated, each red-proved (one decoy flipped → the runner CONVICTED). felhom.eu already ran its suite through `script-tests` (R-885, 86 cases, 56 s) — the row overstated that part. Residuals → R-1127 (no automatic full run), R-1128 (the controller suite edits real files with no lock). | `audits/tester1-limits-filebrowser-2026-10-17/` |
## 2026-10-17 — burndown 3: limiters, family fingerprints, samba label, path guard, gates in a worktree, Redis RDB (controller v0.325.0, catalog `33a4b3b` + `5d9450b`)
| Row | What | Closed | Evidence |
+6 -6
View File
@@ -133,7 +133,7 @@ stopping line that lies.
| **R-981** | Apps & catalog | P3 | **The homepage app gets the Docker socket (that is root in the guest) and has no login, no setup gate and no family gate.** Fix: remove the socket mount, or put homepage behind the family gate. Security review 2026-10-12 (`audits/security-review-2026-10-12/`); detail held off-git for the operator (`/mnt/5_hdd/felhom.eu/evidence/security-review-2026-10-12-PRIVATE/`). | OPEN | — | Change the catalog template; prove on 9202 | CC |
| **R-971** | Apps & catalog | P2 | **A change pushed to the catalog's `main` reaches the installed apps on every box within about 15 minutes, and nothing on the box refuses dangerous container settings (privileged mode, the Docker socket, host mounts, host namespaces); so whoever can push to the catalog repository can take every guest.** Design-shaped: installed apps take catalog fixes on purpose. Decision for the operator in `STATUS.md`. Fix options: a privilege allow-list check on the box before any compose is written (and in catalog CI), and later signed catalog releases. Security review 2026-10-12 (`audits/security-review-2026-10-12/`); detail held off-git for the operator (`/mnt/5_hdd/felhom.eu/evidence/security-review-2026-10-12-PRIVATE/`). | WAITING-ON-OPERATOR — confirmed by a second reader | operator decision | Decide; then build the box-side check | operator |
| **R-676** | Apps & catalog | P3 | **[P3-LOW] Watch: immich's first start restarted 12 times — decision 28's crash-loop stop (6 in 10 min) would stop it.** From the 2026-09-17 chaos night (DB connection dropped during the first-start geocoding import on a 6 GB guest; it did not recover that night). No healthy app in any drill evidence restarts on a first start (1831 samples, 40 live containers), so the threshold stands; this row exists so the first immich install under v0.269.x is watched. `audits/night-2026-09-24/A3/40-first-start-restarts.txt` **2026-09-25 night (read from source, v0.271.0): a DEPLOY's first start is NOT covered by decision 28's suppression** — `Deploying` clears when `compose up -d` returns (`deploy.go` "Clear deploying flag"), and `ObserveUnhealthy` then samples the app; an automatic update's step, verify and undo ARE covered (`Updating`, pinned by `TestD28_NoCrashLoopStopDuringAnAutomaticStep`). So a first start that restarts ≥ 6 times in 10 min is stopped — which R-676 already accepts for a broken first start; a healthy slow first start would be stopped too. **-- 2026-09-30: the first-start restarts are explained.** immich's first-start geodata import OOM-kills its database at 512M on a guest with no swap (R-732, measured: 61–104 kills); the 2026-09-17 chaos-night case (DB connection dropped during the import on a 6 GB guest) fits it. Fixed in the catalog (`56c4888`, 768M). The watch itself (decision 28 on a DEPLOY's first start) is unchanged. | **OPEN — P3; owner: CC (watch)** | — | — | CC |
| **R-994** | Apps & catalog | P3 | **Seven apps peak above 80 % of a memory limit, and 23 apps' typical use is above their catalog `mem_request`.** MEASURED 2026-10-13 (`documentation/audits/sizing-2026-10-13/SIZING.md` §3, `evidence/catalog-check.json`). Near a limit — risk: the container is stopped for using too much memory: docmost (container 475 of 512 MB), romm (703 of 768), termix (117 of 128), uptime-kuma (227 of 256, tester-1 telemetry), grafana (435 of 512), immich (`immich-server` 1,665 of 2,048 during a 200-photo import), tandoor (827 of 1,024). No container was killed during the bench. Under-stated request (typical ÷ request): calcom ×4.0, adventurelog ×3.6, termix ×3.4, claper ×2.5, grafana ×2.2, komga ×2.2, docmost ×2.1, recipe-importer ×2.1, uptime-kuma ×2.1, zipline ×2.0, and 13 more ≤ ×1.8. Templates NOT changed (read-only run). | **NARROWED 2026-10-17** — the six other limits raised (catalog `bff82f9`: docmost 768M, romm 1024M, termix 256M, uptime-kuma 384M, grafana 768M, tandoor 1280M; peaks now 46–69 %; live on 9201: docmost 805306368 bytes); the 23 requests → R-1119 (operator: wait). **Left: Immich** (`immich-server` 1,665 of 2,048 MB on a 200-photo import; tester-1's real library peaked at 2.9 GB) — raise after a measurement with a larger library. | — | Measure Immich with a larger library (bench), then its limit | CC |
| **R-994** | Apps & catalog | P3 | **Seven apps peak above 80 % of a memory limit, and 23 apps' typical use is above their catalog `mem_request`.** MEASURED 2026-10-13 (`documentation/audits/sizing-2026-10-13/SIZING.md` §3, `evidence/catalog-check.json`). Near a limit — risk: the container is stopped for using too much memory: docmost (container 475 of 512 MB), romm (703 of 768), termix (117 of 128), uptime-kuma (227 of 256, tester-1 telemetry), grafana (435 of 512), immich (`immich-server` 1,665 of 2,048 during a 200-photo import), tandoor (827 of 1,024). No container was killed during the bench. Under-stated request (typical ÷ request): calcom ×4.0, adventurelog ×3.6, termix ×3.4, claper ×2.5, grafana ×2.2, komga ×2.2, docmost ×2.1, recipe-importer ×2.1, uptime-kuma ×2.1, zipline ×2.0, and 13 more ≤ ×1.8. Templates NOT changed (read-only run). | **NARROWED 2026-10-17** — the six other limits raised (catalog `bff82f9`: docmost 768M, romm 1024M, termix 256M, uptime-kuma 384M, grafana 768M, tandoor 1280M; peaks now 46–69 %; live on 9201: docmost 805306368 bytes); the 23 requests → R-1125 (operator: wait). **Left: Immich** (`immich-server` 1,665 of 2,048 MB on a 200-photo import; tester-1's real library peaked at 2.9 GB) — raise after a measurement with a larger library. | — | Measure Immich with a larger library (bench), then its limit | CC |
| **R-1018** | Apps & catalog | P3 | **The OnlyOffice links (FileBrowser, Nextcloud) have no recorded live proof since the move to Proxmox.** `controller/internal/integrations/` holds two handlers; no audit after the Proxmox move shows a document opened from FileBrowser or Nextcloud in OnlyOffice (searched 2026-10-14). The media-app links of `15` §6 will copy this code, including its revoke-on-stop rule (`lifecycle.go:10-13`). | **OPEN** — filed 2026-10-14 | — | One live walk on a Tier-0 box: install OnlyOffice + FileBrowser, open a document, save, read it back; then stop one app and record what the link does | CC |
| **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/<drive>/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/<drive label>`) without breaking the hardlink rule, which binds only the download/library apps | CC |
@@ -148,7 +148,7 @@ stopping line that lies.
| **R-1100** | Apps & catalog | P3 | **One sign-in for the dashboard and FileBrowser (proxy auth) — spike first.** Since controller 0.320.0 every app with a folder has „Fájlok ↗", and the box can show FileBrowser's password — but FileBrowser still asks for its OWN login the first time, so the household signs in twice. FileBrowser Quantum has a proxy-auth method (`auth.methods.proxyAuth`, header-trusted) that could take the dashboard session through traefik; nobody has measured it. Design: `architecture/02-controller-module-map.md` „Logins and folders". | OPEN — filed 2026-10-16 (task logins-folders). | — | Spike on demo-hp: proxy auth at the pinned tag (source + measured), a forwardAuth in traefik that answers only for a dashboard session, what a stranger reaching `files.<domain>` with a forged header gets, and what happens to FileBrowser's shares. | CC |
| **R-1099** | Apps & catalog | P4 | **The N100 may hold RomM games in the old upload place, now shown under a fake „roms” platform.** Until 2026-10-16 RomM's own upload wrote to the drive's `roms/roms/<platform>/`; after the mapping fix (catalog `fb18471`, R-1089) those files are at RomM's `library/roms/roms/…`. Measured on 9201: such a game showed as missing in its platform and again under a platform „roms” (`audits/romm-ghost-2026-10-16/B/b-after.txt`). Files put in with the file manager are not affected — they are now found. The N100 runs RomM (hub `/apps/romm`); CC does not log in to the lived-in box. | OPEN — filed 2026-10-16 | Operator: look at `roms/roms/` on the N100's drive in the file manager | If it holds platform folders: move them up one level into `roms/`, then run „Scan” in RomM; if it is empty, close | Operator |
| **R-1117** | Apps & catalog | P4 | **Immich's and Nextcloud's Redis keep a volume they do not need** (upstream runs both without one; queues and caches only). Deferred from R-1096 on purpose: removing a volume from the compose leaves the old volume on installed boxes, and the nightly dump / an old backup's restore for a volume the compose no longer declares is unchecked. The RDB switch (catalog `5d9450b`) already removed the full-disk danger. | DEFERRED — filed 2026-10-17 | — | Measure the dump and an old-backup restore without the volume on 9202; then the template change + an orphan-volume note | CC |
| **R-1119** | Apps & catalog | P3 | **23 apps' `mem_request` is below their measured typical use (R-994's second half), and the requests feed the box's install check** (`controller` `stacks/deploy.go:1549` `memoryVerdict`: committed requests + the new one > guest memory − 384 MB → refused). The measured values (rounded up) would raise the household set (Immich, Jellyfin, Nextcloud, Home Assistant, Vaultwarden, paperless-ngx) from 3,622 to 3,910 MB of the 3,712 MB an 8 GB box can use, so its sixth app would be refused on the smallest supported box. The website estimator is not affected (it reads the measurement). Values ready: `audits/tester1-limits-filebrowser-2026-10-17/P3/`. | WAITING-ON-OPERATOR — filed 2026-10-17 (operator: „limits now, requests wait”) | the operator's decision: raise the requests (the box's check gets truer; 8 GB no longer takes the full household set) or keep them | Apply the decision through the catalog | CC |
| **R-1125** | Apps & catalog | P3 | **23 apps' `mem_request` is below their measured typical use (R-994's second half), and the requests feed the box's install check** (`controller` `stacks/deploy.go:1549` `memoryVerdict`: committed requests + the new one > guest memory − 384 MB → refused). The measured values (rounded up) would raise the household set (Immich, Jellyfin, Nextcloud, Home Assistant, Vaultwarden, paperless-ngx) from 3,622 to 3,910 MB of the 3,712 MB an 8 GB box can use, so its sixth app would be refused on the smallest supported box. The website estimator is not affected (it reads the measurement). Values ready: `audits/tester1-limits-filebrowser-2026-10-17/P3/`. | WAITING-ON-OPERATOR — filed 2026-10-17 (operator: „limits now, requests wait”) | the operator's decision: raise the requests (the box's check gets truer; 8 GB no longer takes the full household set) or keep them | Apply the decision through the catalog | CC |
## App updates — 4 rows (P3 4)
@@ -210,7 +210,7 @@ stopping line that lies.
| **R-1076** | Storage & devices | P4 | **A cheap SSD reports a vendor-less WWN, so a WWN-first disk key may not be unique.** MEASURED 2026-10-15 on the N100's system SSD (AirDisk 512 GB): `ID_WWN=0x5000000123456f1f` — NAA-5 with OUI `000000`, a pattern that looks like a placeholder; its serial `QDF922W009654S30EX` looks real. The agent's wipe binding prefers `wwn-` links (A/internal/storage/durable_device.go:32). Not known whether two units share the WWN. Evidence: `audits/storage-identity-2026-10-15/B-n100.txt`. | OPEN | — | Check a second unit of the same model (or vendor data); if shared, make the agent skip OUI-000000 WWNs (the design already keys on model+serial, `architecture/16-storage-physical-identity.md` §3). | CC |
| **R-1077** | Storage & devices | P4 | **No USB enclosure that hides or fakes a disk's serial has been measured.** The storage-identity spike (2026-10-15) had none at hand and found none in earlier evidence; the design's `usb_bridge` unknown rule (`architecture/16-storage-physical-identity.md` §3) is therefore an assumption. Cheap single- and dual-bay bridges are known to report one bridge serial for any disk. Evidence: `audits/storage-identity-2026-10-15/README.md` case 4b. | OPEN | — | Buy or borrow one cheap USB enclosure (single and dual bay), run `tools/physdisk_probe.py` against it, and set the rule from what it reports. | Operator (a device) then CC |
| **R-1094** | Storage & devices | P4 | **The whole-disk format refusal tells the household to format the free part — which is refused while the other part is in use.** SEEN 2026-10-16 (controller 0.318.0): 409 „Ezen a lemezen egy használatban lévő meghajtó van, ezért a teljes lemez nem formázható. Csak a szabad részét formázhatod." — since agent 0.158.1 a part next to a mounted part can only be USED (the root wrapper trusts no „Felhom's own" claim). Evidence: `audits/storage-identity-buildB-2026-10-15/live/14-samedisk-refusal-offer.txt`. | READY | — | Reword `err.web.meghajto_hasznalatban_formazas` (hu + en): „… nem formázható. A szabad részét használatba veheted." Next controller release; the copy gates run. | CC |
| **R-1118** | Storage & devices | P4 | **A drive decommissioned and then unplugged keeps its agent mount unit enabled on the host** (`mnt-<name>.mount`, „Managed by felhom-agent”, `WantedBy=multi-user.target`), so every later boot waits for a device that is gone, and the agent's watchdog reports it „disconnected”. Decommission retires the drive logically (agent: „logical retire, data untouched”) and releases only the guest bind; no product path releases the host mount or forgets the drive. Seen on Tester 1 at the R-1022 teardown 2026-10-17 (four units left; the boot delay is read from the unit, NOT measured). | OPEN — filed 2026-10-17 | — | Decide „forget a decommissioned drive” (unit disabled + removed when the drive is absent), with a test | CC |
| **R-1124** | Storage & devices | P4 | **A drive decommissioned and then unplugged keeps its agent mount unit enabled on the host** (`mnt-<name>.mount`, „Managed by felhom-agent”, `WantedBy=multi-user.target`), so every later boot waits for a device that is gone, and the agent's watchdog reports it „disconnected”. Decommission retires the drive logically (agent: „logical retire, data untouched”) and releases only the guest bind; no product path releases the host mount or forgets the drive. Seen on Tester 1 at the R-1022 teardown 2026-10-17 (four units left; the boot delay is read from the unit, NOT measured). | OPEN — filed 2026-10-17 | — | Decide „forget a decommissioned drive” (unit disabled + removed when the drive is absent), with a test | CC |
## Security & access — 22 rows (P1 1, P2 2, P3 13, P4 6)
@@ -237,7 +237,7 @@ stopping line that lies.
| **R-1119** | Security & access | P3 | **`RESEND_API` is exported into CC's own environment from `~/.bashrc` (line 88), so every Bash call CC makes carries it, and a plain `printenv`, `env` or `set` prints it into the transcript.** MEASURED 2026-10-17 (SPIKE Q6, names only): present in the parent `claude` process environment and in the Bash tool environment. | OPEN | R-1118's broker, for the clean fix (the value lives in the store and reaches only the command that names it) | Until then: find what reads it (memory: the Resend checks run it via `bash -ic`), then move the export out of `~/.bashrc` into that one script — the operator's shell file, so the operator's word | operator |
| **R-1120** | Security & access | P3 | **`homelab-manifests/.claude/settings.json` allows `Bash(kubectl get:*)` without a prompt, and that pattern includes `kubectl get secret -o yaml`, which prints every value (base64) into the transcript.** Read 2026-10-17 at `origin/main` `e8e595a`, line 6; nothing in the file asks for Secret reads to skip the prompt. The local clone `~/git/homelab-manifests` is behind origin and has uncommitted edits to that same file (not touched). | OPEN | — | Add `Bash(kubectl get secret:*)` and `Bash(kubectl get secrets:*)` to `ask` (ask wins over allow), or a PreToolUse refusal like the spike's `kubectl-read-secret` rule. A permission change, so the operator's word (`.claude/rules/unprompted-work.md` §5) | operator |
| **R-1121** | Security & access | P3 | **`~/rotated-secrets-2026-10-09.txt` still exists on DooPlex** — 632 bytes, modified 2026-10-09 13:08 +0200, mode 600 (SPIKE Q6: `test -e` + `stat` only, not opened). Left by the R-925 rotation work. If any value in it is still valid, it is one more plaintext secrets file in the home folder, readable by every CC session. | WAITING-ON-OPERATOR | what the file holds — only the operator knows | Operator: confirm every value in it is revoked, then `shred -u` it; or move the live ones into the R-1118 store | operator |
| **R-1120** | Security & access | P3 | **The Cloudflare tunnel runs before the box is claimed, and no document says whether that is intended.** The claim needs it: the claim mail links `https://felhom.<domain>` (`hub/internal/notify/templates.go:27`); `cloudflared` is started from the token with no claim check (`controller` `stacks/infra.go:85-90`; `01-topology-and-trust.md:119`, `:248`). Reachable before the claim: the dashboard serves only the claim page (code: 72 h life, 5 tries, 15 min lockout — `web/claim.go:22-33`), and `files.<domain>` — FileBrowser on its default login from its first start until the next base-stack tick sets a password (seconds; v0.326.0 re-checks every run). Options: (A) keep the tunnel; route FileBrowser publicly only after its default is replaced — small, no promise changes; (B) start the tunnel only after a LAN claim — the claim flow and its mail change, the household must be at home. Recommended A. From R-977. | WAITING-ON-OPERATOR — filed 2026-10-17 | the operator's choice A or B | Write the choice into `01` §5; build A (or B) | CC |
| **R-1126** | Security & access | P3 | **The Cloudflare tunnel runs before the box is claimed, and no document says whether that is intended.** The claim needs it: the claim mail links `https://felhom.<domain>` (`hub/internal/notify/templates.go:27`); `cloudflared` is started from the token with no claim check (`controller` `stacks/infra.go:85-90`; `01-topology-and-trust.md:119`, `:248`). Reachable before the claim: the dashboard serves only the claim page (code: 72 h life, 5 tries, 15 min lockout — `web/claim.go:22-33`), and `files.<domain>` — FileBrowser on its default login from its first start until the next base-stack tick sets a password (seconds; v0.326.0 re-checks every run). Options: (A) keep the tunnel; route FileBrowser publicly only after its default is replaced — small, no promise changes; (B) start the tunnel only after a LAN claim — the claim flow and its mail change, the household must be at home. Recommended A. From R-977. | WAITING-ON-OPERATOR — filed 2026-10-17 | the operator's choice A or B | Write the choice into `01` §5; build A (or B) | CC |
## Box system & updates — 12 rows (P2 1, P3 7, P4 4)
@@ -343,8 +343,8 @@ stopping line that lies.
| **R-1025** | Process & tooling | P4 | **A power drill on demo-hp cuts Tester 1 too, and nothing warns the session using it.** 2026-10-14 17:25 CEST another session cut demo-hp's plug (`plugcut.py --plug hp`, the Immich drill) while this session ran downloads on Tester 1 (VM 341 runs on demo-hp); Tester 1 rebooted and came back by itself. The drill's fence checks Tester 1 for backups and package jobs only. | **OPEN** — filed 2026-10-14 | — | Add „a test runs on Tester 1” to the fence (a marker file the testing session writes), or name the rule in `runbooks/target-selection.md` | CC |
| **R-1039** | Process & tooling | P4 | **qBittorrent stalls on the LAST piece of an archive.org torrent; Transmission does not.** Seen three times on 2026-10-14 (Tester 1 S2 and S3, demo-hp 9201 live read-back): the film reaches 99.994 %, the piece shared with archive.org's side files (`__ia_thumb.jpg`, `_meta.sqlite`, `_meta.xml`) never arrives, qBittorrent's log shows „500 Internal Server Error” from the archive.org web seed, while Transmission finishes the same torrent and curl range requests on the same files answer 206. A household that uses archive.org torrents with qBittorrent hits it too; our tests finish only with a local peer. | **OPEN** — filed 2026-10-14 | — | Note it in qBittorrent's onboarding record; for test films use Transmission, or a public-domain torrent with real peers | CC |
| **R-1078** | Process & tooling | P4 | **A controller comment still describes `mp1 /mnt/sys_drive` as a separate volume.** `C/cmd/controller/main.go:2546` („the SYSTEM-DATA volume (`mp1`, `/mnt/sys_drive`)…”) — `mp1` was removed by R-165; `sys_drive` is a folder of `mp0` (measured on all three boxes, `audits/storage-identity-2026-10-15/README.md`). The same stale cell in `07-backup-architecture.md` §6.1 was corrected in this session. Not fixed here: this run allowed no product-repo change. | READY | — | Correct the comment in the next controller change. | CC |
| **R-1121** | Process & tooling | P4 | **The controller's and the catalog's decoy suites run only when someone starts a full gate run by hand** — neither the pre-push hook nor CI (`--fast`) runs them (too slow, or they edit real files), so a decoy that goes quiet is again seen only by chance (R-1115's shape). The agent's runs in CI. Found by the R-1116 helper 2026-10-17. | OPEN — filed 2026-10-17 | — | A scheduled full run (CI cron or the nightly), with a mail on failure | CC |
| **R-1122** | Process & tooling | P4 | **The controller's decoy suite edits real tracked files (`handler_debug.go`, `update.go`, the locale bundles, templates) and plants `.go` files, with no lock** — a full run while another session edits the controller tree can overwrite that session's edits. felhom.eu's suite took an `flock` after the 2026-10-08 clobber. Found by the R-1116 helper 2026-10-17. | OPEN — filed 2026-10-17 | — | Run the suite in a scratch copy of the tree, or take the felhom.eu-style lock | CC |
| **R-1127** | Process & tooling | P4 | **The controller's and the catalog's decoy suites run only when someone starts a full gate run by hand** — neither the pre-push hook nor CI (`--fast`) runs them (too slow, or they edit real files), so a decoy that goes quiet is again seen only by chance (R-1115's shape). The agent's runs in CI. Found by the R-1116 helper 2026-10-17. | OPEN — filed 2026-10-17 | — | A scheduled full run (CI cron or the nightly), with a mail on failure | CC |
| **R-1128** | Process & tooling | P4 | **The controller's decoy suite edits real tracked files (`handler_debug.go`, `update.go`, the locale bundles, templates) and plants `.go` files, with no lock** — a full run while another session edits the controller tree can overwrite that session's edits. felhom.eu's suite took an `flock` after the 2026-10-08 clobber. Found by the R-1116 helper 2026-10-17. | OPEN — filed 2026-10-17 | — | Run the suite in a scratch copy of the tree, or take the felhom.eu-style lock | CC |
| **R-1123** | Process & tooling | P4 | **`reuse_refs_check.py` treats every git directory beside the repo as a sibling repo**, including stray clones in the workspace (`felhom.eu-media`, `felhom.eu-sizing-push`, `felhom.eu-wt-sizing`), so a citation can resolve against a stale clone and pass. Found by the R-1116 helper 2026-10-17 (it also makes the agent suite 20 s here vs 5 s in CI). | OPEN — filed 2026-10-17 | — | Search only the four known repo names (or the main clones), with a decoy | CC |
<!-- DUE-CHECKS-BEGIN — machine-readable. Parsed by scripts/due_checks_gate.py.