Measured four boxes, the hub's five host reports, every catalog image's registry size and one whole-box copy's
thin-pool use. Proposal: mp0 50/100/130 GiB, reserve max(16 GiB, 10 %) capped at 48 GiB -> the internal place
about 42/182/590/1,510 GB for 256 GB/512 GB/1 TB/2 TB. STATUS D10 asks for the operator's ok.
Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb
The operator ruled D1-D6 as recommended. Build A shipped (agent v0.157.0, controller v0.317.0 MinAgent 0.157.0,
hub v0.154.0): live on Tester 1 (unknown/vm, the "cannot check" notice, copies made not counted), demo-hp and
the N100 (proven, different, unchanged). NAS notice and the no-drive sentence are unit-proven only.
STATUS: D10 removed; vouch agent 0.157.0 and rule on R-1082 added. Poster: the Tier-2 line, text only.
Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb
0.316.3 joins 0.315.0 in the row rather than becoming a near-duplicate of it: same cause shape (a
guard that was not on the path the work takes), same consequence (a published tag whose content is
not what its number says), same answer (leave it; a version number is pushed once, including one
CC spoiled). The root fix — build.sh refusing a dirty or unpushed tree — is named in the row.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0117kRTSgs3rJWUFGxyoWN6Y
02-controller-module-map.md "The app page" gains the layout rules [DESIGN] — one column of one
width, a section is a hairline not a card, a box means something (blue = the app is waiting for
you, amber = something is risky, nothing else), the hero is not a box, and a success is not a
banner. Plus the asset-tag rule: every shell's stylesheet address is derived from the BUILD, not
the version, because the origin sends no validator and a cached copy can therefore only expire or
be addressed differently.
09-update-architecture.md gains §0 [DESIGN]: a version number is pushed once. It belongs at the TOP
of that document because everything below it compares versions — the floor moves a box by comparing
a number, the button offers the highest tag, and a box re-pulls a tag only when the tag changes.
Two images under one number is therefore not untidiness; it is a box running the wrong code that
can never be told.
R-1080 filed and closed: 0.315.0 was pushed three times from three different commits. Closed rather
than left open because no box is stranded — exactly one guest ran it and it ran the registry's
current digest, and the floor was 0.314.0 so nothing else could have taken it.
audits/app-page-2026-10-15b/P0/ carries the measurement and its honest caveat: the stale Cloudflare
object is no longer reproducible, because the first probe of the session forced its revalidation.
What is shown is every precondition, the proof an aged entry existed (cf-cache-status EXPIRED), and
the elimination of the only other candidate. The six stylesheet bodies are reduced to their sizes,
sha256s and rule counts — one 99 KB file does not need six copies in git to make the point.
.claude/rules/unprompted-work.md item 6, all four versioned copies: a version number is pushed once,
stated as a FACT about what the build now enforces rather than as a new rule.
STATUS: the operator's one look, through the public address.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0117kRTSgs3rJWUFGxyoWN6Y
Spike (read-only probe, tools/physdisk_probe.py): the agent-side walk (partition -> disk, dm/LVM
slaves, loop -> backing file) names the right physical disk for one-disk boxes, two disks, two
partitions of one disk and a pass-through USB bridge; inside a VM (Tester 1) every disk is "unknown".
Today's agent lists whole disks only and calls an empty partition table "data-bearing"; the
controller's Tier-2 "different disk" is st_dev. sys_drive is a folder of mp0 (backup=1), so the
design gives one-disk boxes a separate internal data place outside the whole-guest copy instead.
Draft only; waits on the operator's rulings D1-D6 (16 section 12). 07 section 6.1's stale mp1 cell
corrected. Register 163 -> 169. Scratch loop disk and Tester 1 scratch disk removed.
Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb
On demo-hp: OMV 8.5.11-1 + openmediavault-kvm 8.3.4 in a VM, every OMV step done in its web pages
(headless browser). Public ISO 1.29.0 on the whole passed NVMe, BIOS firmware, bound and claimed as
throwaway customer Tester4, Vaultwarden + Jellyfin, local backups, two OMV restarts (clean guest
shutdown, AutoStart back in 1 min 52 s). Guest memory 7,863 MiB of 12 GiB.
Traps for the guide: the bridge changes OMV's IP; the plugin boots the disk first (wipe the NVMe);
the host-disk list offers OMV's own disk. Rows: one-disk Jellyfin refusal (R-1068), virtio disk not
formattable (R-1069), tunnel-less OS-update alarm (R-1070), NAS films for Jellyfin (R-1071, operator),
mixed formal/informal backup text (R-1072), no SMART in a VM (R-1073, operator). Register 157 -> 163.
Everything removed; Tester 1 back ONLINE. Customer Tester4 waits for the operator's delete.
Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb
02-controller-module-map.md gains "The app page" under web/: the URL map, why the default tab is
RENDERED at the bare URL and not redirected to, why the tabs are links and not panels, the
302-never-301 rule for the old /stacks/{name}/... GETs and the untouched POSTs, the after-start
registry (and why its actions are Go, never catalog data), and the guide's checked_version gate.
Each marked [DESIGN]. There was no document covering the app page at all, which is why the six-page
sprawl and the "Vissza goes to the list" behaviour were never called wrong — R-1066, filed and
closed by the same change.
10-localisation.md §7 gains the guide block, including the one exception it has to state out loud:
guide sections and FAQ entries are matched BY INDEX, the only lists in the copy model that are,
because a section's title is the thing being translated and so there is no key to match on. Safe
only because the copy gate requires equal counts AND the fallback stays field by field.
R-1067 (P4, BLOCKED): the catalog still carries pi_compatible: and nothing reads it. Left on
purpose — a box on 0.314.0 would show "csak x86" on every app — and gated on the fleet floor
reaching 0.315.0.
STATUS.md: one line asking the operator to look at the new app page on demo-hp, and the controller
version line.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0117kRTSgs3rJWUFGxyoWN6Y
- 09 §3 decision 254 (operator decisions 240/243 written down); target-selection: a "lived-in" tier, Tier 0 = demo-hp
alone; nodes.md role + drive; 11-os-updates ring 0 wording; CLAUDE.md + docs.md: the diary.
- documentation/lived-in/n100.md (new diary); audits/n100-lived-in-2026-10-15/ (state, drive read, Part C capture sets,
installs, wiring, stranger probes, demo-hp clean-up, the operator's SHEET.md).
- Register: R-1062 (the split, operator decides), R-1063 (decommission half-state on an agent refusal), R-1064 (path
removal silent about cross-drive copies), R-1065 (a claimed Plex gets no libraries until a wiring run).
- demo-hp: /mnt/sizing-bench removed through the dashboard; the hub shows demo-hp OK (14:56 UTC).
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
- audits/prowlarr-2026-10-15/box9201: Sonarr then Prowlarr — no link until „Bekötés most"; Radarr after Prowlarr —
linked by itself ~60 s later; Prowlarr's connection test 200 for both, its sync command completed; all removed
keeping data. The first run's key-quoting defect in the tool is recorded and fixed.
- R-1058 (Apps & catalog, P3): the wiring does not start when Prowlarr itself comes up.
- R-1048 closed (CLOSED-ITEMS). STATUS, CONTEXT. REPORT-release-rule-prowlarr-2026-10-15.md.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
- Configuration → Access tokens: named, scoped (group read/write), expiring (≤365 d), shown once,
stored SHA-256 only, every use logged by name. Bearer fhp_… on the web surface only; /api/v1 refuses it.
- Route table = the code's single source (web/routes.go), pinned to ServeHTTP's switch; session-only:
secrets shown/minted, deletes/resets, password, tokens.
- R-952 closed: /api/v1 route table names each caller, pinned to the switch; no-credential refusal test.
- Fail-open fixed: an empty operator password served the UI open (main skipped RequireAuth). Live hub never open.
- 05 §17, 04 §6.2, 13, 09 §3 251; register 155→157 (+R-1054, R-1055, R-1056, −R-952); STATUS.
- website: prowlarr-logo.svg (byte copy from felhom.eu-media) — the site gate refused every push.
Not deployed — waits for the operator's yes.
Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb
- 15-media-library.md §10: what the box does on each drive event, per app, with the measured call; the guards
that ARE needed and the ones that are NOT (K1: nothing lost while a drive is gone).
- Evidence K4 (dead-drive check: mountinfo `shutdown`, stat unreliable), K5 (restart), K6 (unclaimed Plex),
K7 (old Sonarr/Radarr repair on the bench), K8 (hub received the drive-return events and mailed none), K9 (files identical).
- nightly-rotation.md runs scripts/https_only_check.py first every night; scripts/CHANGELOG.md entry.
- STATUS, CONTEXT (decisions 244-246), REPORT-night-2026-10-14.md.
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
Another session filed R-1033 (Security & access, P2, plain http on the public
names) in 6e0643f6 while this session was working; I minted mine against the
register as it stood before that, rebased onto it without re-checking, and the
push put two R-1033 rows in OPEN-ITEMS.md — register_shape_gate red on main.
Theirs landed first and keeps the number. The apps-page-lag row (Apps & catalog,
P3) is now R-1036, with the references in the website CHANGELOG, STATUS.md and
REPORT-seo-felho-tarhely-2026-10-14.md moved with it. Register and site gates
green again. This clone's pre-push hook is unarmed (core.hooksPath unset), which
is why nothing refused the push locally; said so in the report.
Search Console (3 months, read 2026-10-14): 48 impressions, 1 click, average
position 73.6; the top query is „felhő tárhely" (19). No page on the site used
the phrase — Google was showing the home page by accident.
New pair /sajat-felho-tarhely + /en/own-cloud-storage: what cloud storage is and
the three ways to have one; what to do when the Google or iCloud storage is full
(the free clean-up first, linked to Google's and Apple's own help; the paid
options second); a five-year cost table; where the data sits; who should NOT
choose this; the closed test. Registered in site_gates.py TWINS/URL/SHELL, both
URLs in sitemap.xml (22 -> 24). FAQPage JSON-LD derived from the visible text.
Prices each read 2026-10-14 on the provider's own Hungarian page, with the URLs
and the date in an HTML comment and a visible „Árak" line: Google AI Plus (2 TB)
— Google One's 2 TB plan — 35 990 Ft/év (behind the „Éves" toggle; a plain fetch
sees only the monthly 3 590 Ft), iCloud+ 2 TB 4 490 Ft/hó, Microsoft 365 Családi
(2 TB shared, no longer 1 TB per person) 46 499 Ft/év.
Felhom's own cost follows what the site already said (operator ruling): machine
and install one-off, power, off-site storage monthly by volume, operation
OPTIONAL, no fee during the closed test. Power is stated as an idle measurement
(nyugalmi állapotban 7-9 W, ~75 kWh/év, from audits/night-power-2026-10-13) and
the page says a year with daytime use is more; no daytime figure and no
electricity tariff are given, because neither is measured or sourced.
FAQ corrected (both languages, JSON-LD re-derived): the cost answer carried
unsourced, undated prices and summed Spotify and a password manager into a
storage comparison; and the page contradicted itself on electricity („havi
néhány ezer forint" vs „évi 5.000–15.000 Ft"). App count 60 -> 62 in the four
places that were stale.
Three defects found on the rendered page and fixed: a .vs-row link fell back to
the browser-default blue (contrast 1.99 -> 7.17); 24px of horizontal scroll at
390px because .method-pros li is a nowrap flex row and the new items contain
links (each item's content wrapped in one span); .info-card and .method-pros
were scoped to the pages that first used them. site.css ?v=31 on all 26 pages.
The shared .content-section padding was NOT changed — it is identical on every
page; the new page only lacked the alt-bg alternation, and now has it.
R-1033 the apps page lags the catalog by two apps (plant-it, wger); R-1034 gate
17 checks the FAQ JSON-LD on two hard-coded pages only; R-1035 the SEO result,
with dated checks on 2026-11-11 and 2026-12-09.
Docs 02/05/07/13 and capability F12 (PROVEN-LIVE); the audit's C and D sections; R-1020 (the
duration reads 0) and R-1021 (the hub build builds a stale checkout) filed; STATUS one screen.
Register 133 -> 140 (this session: opened 2, closed 1; another session added 6). Both plugs ON.
Report: REPORT-immich-repair-2026-10-14.md.
Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb
Read-back: live sizing-data.json?v=4 byte-equal to the commit; the presets keep their verdicts,
Immich alone on 8 GB still tight; only the set without Immich changed. Spike B2 on 9202:
POST /api/assets/jobs regenerate-thumbnail rebuilt exactly the 10 broken assets (1.55 s, 5.3 s CPU),
0 of the other 20 photos' 40 files rewritten (control: all rewrote 40 of 40); an empty file maps to
its asset by the first 36 characters of its name. Immich removed through the product, no leftovers.
Register 134 -> 133 (opened 0, closed 1). STATUS D9/D10 ruled.
Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb
demo-hp 12:06:52 UTC, 1.53 GB written: at boot the dead task was judged dead, the partial and its .tmp
removed by the root helper, the next backup finished (5.65 GB), host root back below its pre-cut use.
Orphan thin device 4 repaired first (operator B2 - A); R-1012 P2 -> P3, detection stays open.
Delivered by signed jobs to Tester 1 and the N100 (probe 71/71, real sudo checked). Controller 0.310.0
everywhere after the operator cleared the per-customer floors. Register 134 -> 134 (opened 4, closed 4).
Report: REPORT-power-cut-fixes-2026-10-14.md. Both plugs ON.
Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb
noindex and the robots Disallow lines removed; both URLs in the sitemap with their hreflang pair; the pair
moves from UNLISTED to TWINS in site_gates.py. The explaining sentence's base figure was already the drawn
box's base; a test now pins it (red-proved).
A household ticks apps and sees, for an 8, 16 and 32 GB box: fits well / fits, but
tight / does not fit, the totals, and the apps that burst on CPU. One rule in
assets/sizing.js, every number from assets/sizing-data.json (built by
scripts/build_sizing_web.py from the 2026-10-13 N100 measurement; test: 7 cases,
red-proofed). Unlisted: noindex, robots Disallow, not in the sitemap, linked from
nowhere — site_gates.py gate 25 enforces it (UNLISTED twin pairs keep every twin
check). SIZING.md §5 corrected: the 8 GB line contradicted its own x1.5 rule; guest
sizes 4.0/11.4/27.4 GB with the measured 612 MiB MemTotal shortfall. R-993 gains the
fact that the installer accepts a host below any minimum.
Measured on demo-felhom (N100, 16 GB): 61 apps deployed and removed through the
product, sampled every 5 s; heavy apps with one real action (Immich 200 photos,
Jellyfin transcode, Paperless OCR, Nextcloud 500 MB, ...). sizing.json for the
estimator (tools/build_sizing.py), SIZING.md with the proposed minimum machine,
METHOD.md. Power is RAPL CPU-package only (no meter). R-993 asks the operator to
approve the minimum machine; R-994 lists catalog limits/requests that are too low;
R-995 records leftover unnamed volumes after removal. R-231's dated check measured:
dooplex-backup.service success, journal green.
The catalog published SABnzbd and NZBGet today (app-catalog 8ee687e). Here:
- two cards in the media category on both language sets, each with the project's own logo and
each saying IN BOLD that a paid Usenet subscription is the household's own
- the published count 60 -> 62 everywhere it is stated; the category badges are derived from
the cards now (media read 15 with 17 cards, otthon/home read 14 with 16 — both stale)
- documentation/audits/usenet-2026-10-12/: both bench runs, both box steps and verdicts, the
nine defects with their measurements, what a missing provider left unmeasured, the teardown
- R-988 closed (moved to CLOSED-ITEMS in this commit); R-989 filed: the drill-catalog route of
09 §6.5 cannot be followed — that repo is private and no box has catalog credentials, so the
templates were staged in the box's own catalog cache instead
- walk.app_env: a SECRET field in app.yaml is stored ENC:, so that helper returns ciphertext —
the docstring says so now, measured the hard way
- STATUS.md and REPORT-usenet-2026-10-12.md
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0117kRTSgs3rJWUFGxyoWN6Y
Read-only. fetch.py (polite, 5 s apart, 34 pages, all 200), parse.py (own text only; four parser
defects found by the controls and fixed), build.py + spotcheck.py (stdlib). tags.csv holds post
numbers and tags only - no username, author id, salt or post text in git. FINDINGS.md (2,908 posts,
195 people, 82 beginner threads in 7 clusters), FELHOM.md (catalog gap, hardware fit, 15 website
questions, objections, ten ranked recommendations), METHOD.md (controls, spot-check: role and
hardware below 85 % after two rounds, the table-driving splits 92.5 % and 97.3 %), REPORT.md.
R-990: operator rules on the recommendations. R-991: no buyer-readable hardware floor.
Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb
Read-only. fetch.py + tables.py (stdlib), TABLE.md (45 charts, % of
respondents), FELHOM.md (apps, features, reasons, hardware, trends, ten
ranked recommendations), METHOD.md (hashes, counts, matching, MIT licence,
limits). Survey files are not committed. One register row (R-989) and one
STATUS line ask the operator to rule on the recommendations.
The catalog published qBittorrent and Transmission today (app-catalog 9081a47). Here:
- two cards in the media category on both language sets, each with the project's own logo,
each saying what a closed peer port costs (slower swarms, no incoming peers)
- the published count 58 -> 60 on every page that states it, FAQ JSON-LD with its visible twin
- documentation/audits/qbittorrent-2026-10-12/: both bench runs, both box walks and verdicts,
verify-fixes.json, teardown-newapps.json, and the README brought to its final state
- the 2026-09-30 walk harness: a `type: path` deploy field is filled with the drive ROOT —
the controller refuses a path inside a drive (409), so the walker could not install any app
with a drive field at all
- R-988: the Usenet pair (SABnzbd, NZBGet), operator request, not started
- STATUS.md and REPORT-newapps-2026-10-12.md
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0117kRTSgs3rJWUFGxyoWN6Y