f5a0aeb0b8
gates / gates (push) Failing after 1m16s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
105 KiB
105 KiB
Burn-down 2026-10-05 — Part A: every P4 and P3 row checked against live source
Method: 8 read-only checker agents, oldest id first (P4 then P3), each row against main source (no machine reached); every FIXED / DUPLICATE verdict re-checked by the session before closing (a sample of 22 cited lines re-grepped; one (R-274) held back as half-checked; four (R-700, R-704, R-706, R-723) moved to the operator list — their code fix is in, only the live observation the row waits for is missing). Raw per-row JSON: partA-results.jsonl.
Groups: DUPLICATE 2, FIXED-BY-LATER-WORK 29, NOT-WORTH-IT 43, STILL-TRUE-NOT-SMALL 129, STILL-TRUE-SMALL 91, UNCHECKED 23
| Row | Sev | Group | Evidence (abridged) | Min |
|---|---|---|---|---|
| R-10 | P4 | STILL-TRUE-SMALL | FIX: After the os.Rename in DumpOne, open filepath.Dir(finalPath) and call a best-effort dir.Sync() (log at DEBUG on error), mirroring atomicPromoteTar in backup.go:948. — felhom-controller@7690c27 controller/internal/appbackup/dbdump.go:364 if err := tmpFile.Sync(); err != nil { then :390 if err := os.Rename(tmpPath, finalPath); err != nil { with no directory Sync after; the twin at controlle |
4 |
| R-25 | P4 | STILL-TRUE-NOT-SMALL | felhom-controller@7690c27 controller/internal/web/storage_handlers.go:153 uuid := resolveEnrollUUID(ctx, agent, device) still resolves by device PATH after format, then AssignDisk(uuid) at the next step; FormatResult (controller/internal/agentapi/client.go:384-395) carries DurableID only for the confirmation path, not the new fs UUID. Binding resolve+assign to the format's durable-id needs the a |
6 |
| R-76 | P4 | UNCHECKED | Behaviour is FileBrowser-image runtime behaviour (mode/setgid of UI-created folders), only observable on a live box. The image has changed since the finding: controller/internal/infra/infra.go:27 FileBrowserImage = "gtstef/filebrowser:1.5.6-stable" (finding was on 1.3.3). The comment at infra.go:207-208 still asserts `umask 002 so folders the customer creates here come out group-writable (2775 w |
5 |
| R-89 | P4 | STILL-TRUE-NOT-SMALL | No retention policy object in hub: grep -rln -i 'retentionpolicy/retention_policy' felhom.eu/hub returns nothing (felhom.eu@53d8131b). Commercial per-customer policy = money/product decision + new reconciler. |
2 |
| R-91 | P4 | UNCHECKED | Whether /srv/pbs-felhom still exists on ep0 is live-only (ep0 is protected; not touched). Source-side: CONTEXT.md:3656 still reads "/srv/pbs-felhom is 13 G of dead weight on / awaiting R-91's go-ahead". Extra fact found: documentation/runbooks/offsite-endpoint.md:24 still says the datastore felhom-offsite is at /srv/pbs-felhom and :119 `proxmox-backup-manager datastore create felhom-offsit |
5 |
| R-92 | P4 | STILL-TRUE-SMALL | FIX: Add an exact-bytes value to the PBS DR view (e.g. UsedBytesExact rendered as a title= tooltip or a MB-precision string below 10 GB) without changing fmtBytesGB for other callers. — felhom.eu@53d8131b hub/internal/web/pbsdr_box.go:57 and :64 view.UsedStr = fmtBytesGB(snap.UsedBytes); hub/internal/web/offsite_box.go:54 return fmt.Sprintf("%.1f GB", float64(b)/float64(int64(1)<<30)) — still |
4 |
| R-93 | P4 | NOT-WORTH-IT | PICK close-as-accepted (operator word needed: close, or reopen as 'build a drift fixture'); also drop the dead drill-r50 fence in target-selection.md:111 at close: A row about choosing between two fixtures, neither of which exists any more. | 4 |
| R-99 | P4 | STILL-TRUE-NOT-SMALL | No phantom-snapshot cleanup in felhom.eu/hub or felhom-agent (grep -i phantom finds only agent runner/test detection code; no removal path). Deletion on a customer datastore is a separate operator ruling per the row — customer data. | 3 |
| R-104 | P4 | STILL-TRUE-SMALL | FIX: Add an OffsiteFailLocked class matched by offboxLockRe in ClassifyOffsiteFailure (before transport) and a cause line in OffsiteFailureMessage telling the operator the repository is locked by an interrupted run and how it clears. — felhom-controller@7690c27 controller/internal/backup/offbox.go:193-222 ClassifyOffsiteFailure has cases NoUnits/NoRepo/Transport and `default: return OffsiteFailUnk | 5 |
| R-124 | P4 | NOT-WORTH-IT | PICK close-as-accepted: The disaster-recovery recipe writes the PBS root namespace as the word 'root', but PBS itself uses an empty name, so a pasted '--ns root' fails. | 4 |
| R-129 | P4 | STILL-TRUE-SMALL | FIX: After one read-only ssh -o BatchMode=yes demo-hp true (and reading root's authorized_keys comment to name the key), rewrite nodes.md 'Access' section to the measured truth and drop the R-129 caveat in target-selection.md:111-112 (also update the memory index line). — Docs still say no key: felhom.eu@53d8131b documentation/operations/nodes.md:110 ### Access — there is no baked SSH key and |
4 |
| R-134 | P4 | STILL-TRUE-SMALL | FIX: Extract a pure zoneCandidates(domain) []string that yields the name and every parent down to two labels, and loop resolveZone over it (same order: most specific first). — felhom.eu@53d8131b hub/internal/cloudflare/unblock.go:117 for _, name := range []string{domain, parentDomain(domain)} { and :136-141 parentDomain strips exactly one label (strings.SplitN(domain, ".", 2)); controller stri |
4 |
| R-161 | P4 | NOT-WORTH-IT | PICK close-as-accepted (residual is a deliberate ruling; owner operator): The runtime check that app data lands on a volume is run by hand, not on every push. | 3 |
| R-162 | P4 | NOT-WORTH-IT | PICK close-as-accepted: If Docker ever ran on a storage driver where docker diff does not work, the persistence gate would refuse to report and blame the prober instead of the driver. |
3 |
| R-164 | P4 | STILL-TRUE-NOT-SMALL | Predicate still absent: felhom-controller controller/internal/appbackup/dbdump.go:544 still only WARNs its accounts table has NO rows; restore still replays dump + tar (internal/backup/restore_unit.go:114-118 hasReplayableDump). Blocked on a design (live-vs-dump per-table counts). |
3 |
| R-169 | P4 | NOT-WORTH-IT | PICK close-as-accepted (row itself says decide only if the window ever costs something): CI only reports after a push lands, because every repo pushes straight to main with no pull request. | 2 |
| R-177 | P4 | STILL-TRUE-NOT-SMALL | felhom-controller@7690c27 controller/cmd/controller/main.go:1546 sched.Daily("fill-watch", "03:30", func(ctx context.Context) error { return fillWatcher.Check() }); internal/scheduler/scheduler.go:269 has GetJobs but grep finds no RunNow/Trigger method and no run-job route in internal/web. Needs a new operator-gated trigger endpoint (auth surface) — a new mechanism, solve together with R-279. |
4 |
| R-184 | P4 | FIXED-BY-LATER-WORK | Fixed by felhom.eu b55fc17d "hub v0.102.0 — refuse to vouch a version that cannot be installed (R-273)" — exactly shape (b), validate at vouch time in the hub. felhom.eu/hub/internal/web/configs.go:1358 res := s.gitea.PackageDownloadable(ctx, t.pkg, t.version, t.file) and :1365 s.logger.Printf("[WARN] artifact vouch REFUSED: %s package %s is NOT downloadable (R-287)", ...); tag leg at :1343 Ta |
4 |
| R-194 | P4 | NOT-WORTH-IT | PICK close-as-accepted: Proxmox caches permissions, so a removed storage grant can still read as present for seconds to minutes; our self-repair notices only after the cache expires. | 2 |
| R-206 | P4 | STILL-TRUE-NOT-SMALL | homelab-manifests@87dfc29 (/home/kisfenyo/git/homelab-manifests): no daemon.json template in homelab-ansible (grep finds only a comment at roles/node_housekeeping/templates/node-housekeeping.sh.j2:17 and homelab-ansible/CLAUDE.md:54). Part (b) was superseded by fc9fbb8 ("correct the expired Docker rationale"): the script now says at :13-20 do NOT add docker calls, the GC policy in daemon.json is t | 4 |
| R-207 | P4 | FIXED-BY-LATER-WORK | Fixed by homelab-manifests fc9fbb8 "node_housekeeping: guard DRY_RUN, correct the expired Docker rationale, pin container log rotation". /home/kisfenyo/git/homelab-manifests/homelab-ansible/roles/node_housekeeping/templates/node-housekeeping.sh.j2:137 if [[ "${DRY_RUN}" == "1" ]]; then inside write_metrics, :138 logs "file left untouched". |
3 |
| R-208 | P4 | STILL-TRUE-SMALL | FIX: Move the ARG VERSION/GIT_COMMIT (controller) and ARG VERSION/BUILD_TIME (hub) declarations down to just above the final go build RUN. — felhom-controller@7690c27 controller/Dockerfile:12 ARG VERSION=dev and :13 ARG GIT_COMMIT=unknown sit above :19 RUN go mod download // true; felhom.eu@53d8131b hub/Dockerfile:3 ARG VERSION=dev, :4 ARG BUILD_TIME=unknown above :9 `RUN go mod downlo |
3 |
| R-209a | P4 | UNCHECKED | Live-only: whether DooPlex has rebooted and /var/log/felhom-store-postboot-check.log says PASS. Not read (DooPlex is Tier 2, operator ruled no reboot; this pass touches no machine). No source claim to check. | 2 |
| R-210 | P4 | NOT-WORTH-IT | PICK close-as-accepted: 193 old controller/hub images exist only on DooPlex and cannot be re-pulled; the question is whether to delete them. | 2 |
| R-213 | P4 | STILL-TRUE-NOT-SMALL | Row is a not-started design (live-vs-backup comparison, then put-back flow), operator-owned; nothing in source to verify against. | 1 |
| R-230 | P4 | STILL-TRUE-NOT-SMALL | Owed rulings, not code: (a) bulk-correction ruling on MEMORY.md staleness (MEMORY.md index still carries version literals, e.g. 'ctrl 0.224.0', 'hub 0.109.0'); (c) spec-as-failing-test pilot not started. (b) closed. Operator decision required. | 2 |
| R-246 | P4 | STILL-TRUE-NOT-SMALL | felhom.eu@53d8131b hub/internal/store/store.go:3248 func (s *Store) MarkEscrowStale(hostID string) error { still has no production caller (grep: only definition + comments at offsite.go:208,216); stale_at still read (store.go:3182 clears it). Ruling owed by operator: evidential setter or retire the column (folds R-248). |
3 |
| R-256 | P4 | STILL-TRUE-SMALL | FIX: Rewrite flash.offbox.mgr_unavailable / mgr_unreachable in both languages to say the backup service is not running yet and give a route (try again in a few minutes; if it persists, contact support). — felhom-controller@7690c27 controller/internal/i18n/locales/hu.json:1406 "flash.offbox.mgr_unavailable": "A mentéskezelő nem elérhető.", used at controller/internal/web/offbox_handlers.go:54 and |
4 |
| R-261 | P4 | STILL-TRUE-SMALL | FIX: Reword the doc comment (selfbind.go:106-110) to say it is a test accessor and name the two tests that pin the auto-mint invariant (selfbind_automint_test.go, customer_delete_test.go) — or, if the operator prefers, add one post-mint production check that logs [WARN] when count != 1. — felhom.eu@53d8131b hub/internal/store/selfbind.go:111 `func (s *Store) CountSelfBindTokens(customerID string) | 3 |
| R-263 | P4 | STILL-TRUE-SMALL | FIX: Change the comment to 'the only writer that GRANTS the role' and add a source-scanning test that finds every .BackupTarget = assignment in non-test settings code and fails if any other than SetBackupTarget can assign a non-false value. — felhom-controller@7690c27 controller/internal/settings/settings.go:1655 `// from every other. This is the ONLY writer of StoragePath.BackupTarget — registr |
3 |
| R-264 | P4 | STILL-TRUE-NOT-SMALL | felhom.eu@53d8131b scripts/wire_contract_gate.py still allowlists the six with _R264: :242 selfupdate_pending, :246 selfupdate_pending_version, :255 restore_tests.mount_parity, :258 restore_tests.mount_inventory, :281 backup.last_db_dump, :282 backup.last_integrity_check. Each reader is a design per the row. | 3 |
| R-266 | P4 | STILL-TRUE-NOT-SMALL | felhom-controller@7690c27 controller/internal/report/builder.go:94 {Mount: "/", Label: "SSD", TotalGB: sysInfo.DiskTotalGB, UsedGB: sysInfo.DiskUsedGB, Percent: sysInfo.DiskPercent}, — no disk_known on the storage entry; hub has no disk_known (grep empty). Two-repo wire change gated by wire_contract_gate.py. |
3 |
| R-279 | P4 | STILL-TRUE-NOT-SMALL | No operator/hub path to start an off-site run: grep for offbox run triggers in felhom.eu/hub/internal finds nothing; the only run entry is the customer dashboard handler (felhom-controller controller/internal/web/offbox_handlers.go:270 if !s.backupMgr.OffboxRunnable() {). Needs a new operator-authenticated trigger — sibling of R-177, not a duplicate (different job). |
3 |
| R-284 | P4 | NOT-WORTH-IT | PICK close-as-accepted (close as not-a-defect): A reported 'almost full' warning on an empty disk; the code shows the warning only below 20% free and hides it by default, so the report was a reading of unrendered HTML. | 5 |
| R-285 | P4 | STILL-TRUE-NOT-SMALL | No maintenance/expected-downtime concept in hub: grep -rln -i 'maintenance/expected_downtime/quiet_until/snooze' felhom.eu/hub/internal returns nothing. New mechanism (M). |
3 |
| R-286 | P4 | STILL-TRUE-SMALL | FIX: Add one paragraph: a positive control must come from a different channel than the measurement (different query path, snapshot, API or clock); give the 2026-08-09 stale-snapshot case as the example. Put it in ONE home (pointer elsewhere). — Lesson (a) not written anywhere: grep -i 'different channel/same channel/independent channel' over documentation/runbooks/workspace-CLAUDE.md, felhom.eu/sk | 6 |
| R-287 | P4 | FIXED-BY-LATER-WORK | Deleter established 2026-08-10 (R-267 newest-10 prune, recorded in the row itself); CI fixed by felhom-agent 53d047a "Two guards, one number: bound the published check to the retention it must live with" (R-291). felhom-agent@e06ed97 scripts/check-published-versions.py:101 RETENTION_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "retention-policy.json"), :213 `keep = retention_k |
5 |
| R-288 | P4 | STILL-TRUE-NOT-SMALL | felhom.eu@53d8131b documentation/architecture/00-capability-map.md is now 210 125 bytes / 30 937 words / 253 lines (wc), larger than the 134 642 bytes measured in the row; :38 still reads *Verified 2026-07-16 against evidence corpus @ felhom.eu tip 4b18cc5``. Restructure is an M doc surgery, operator-owned. |
3 |
| R-289 | P4 | FIXED-BY-LATER-WORK | R-182 was closed by felhom.eu ef6ac6fe (2026-08-22, register compression): documentation/backlog/CLOSED-ITEMS.md:474 / **R-182** / ... / **CLOSED — SHIPPED** (controller v0.194.0 + hub v0.90.0/.1, 2026-08-03) /. The residue (digest never seen delivering) was since observed: documentation/audits/DRILL-chaos-night-2026-09-17.md:181 backup_run_failures „1 of 12 apps failed to back up in this nigh |
5 |
| R-290 | P4 | STILL-TRUE-NOT-SMALL | Gate exists (felhom.eu scripts/check_stands.py) but the map itself still carries the claims: documentation/architecture/00-capability-map.md has 95 'PROVEN-LIVE' occurrences (grep -c); demoting 12 rows or writing walk documents is M and blocked on R-288 per the row. | 3 |
| R-291 | P4 | STILL-TRUE-SMALL | FIX: Rewrite the _comment/recorded_by to cite the operator's newest-10 rule (R-267/R-287) instead of 'observed, not a ruling', and drop or correct the non-existent registry-retention.md reader. Keep the min_agent-floor note as the recorded better bound; then close R-291. — felhom-agent/scripts/retention-policy.json still says the 10 is 'NOT a ruling anyone has been able to locate' and recorded_by: | 8 |
| R-292 | P4 | STILL-TRUE-SMALL | FIX: Make resolveArtifactSHA return a reason (not-found / unreachable / bad manual sha) and redirect to three distinct flashes (reuse artifact_unverifiable for unreachable, add artifact_version_missing, keep artifact_sha_invalid for a bad typed sha incl. the wrapper sha at :1395). — hub/internal/web/templates/configuration.html:55 still reads 'the Gitea sha lookup failed (version missing / Gitea u | 6 |
| R-310 | P4 | STILL-TRUE-SMALL | FIX: Drop the second 'The vouched golden is' sentence when GOLDEN_CHECK_WHY already names it (or drop the version from :3060); add one runbook line: --uninstall needs an interactive terminal; --force does not bypass the typed vmid confirm. — felhom.eu/scripts/felhom-host-install.sh:3060 sets GOLDEN_CHECK_WHY="it is controller $ver, but the vouched golden is $ART_GOLDEN_VER" and :3080-3081 die "... | 6 |
| R-315 | P4 | STILL-TRUE-NOT-SMALL | felhom.eu/scripts/wire_contract_gate.py:30-48 still documents the test as a repo-wide literal-tag search ('IT PROVES REACHABILITY OF A NAME'); ROOTS at :88 includes the R-311 escrow/retained root. No receiver-type field-by-field comparison exists. Fix requires resolving receiver mirror types — a new mechanism (M). | 5 |
| R-325 | P4 | STILL-TRUE-SMALL | FIX: Import RETRIEVAL_STEMS from ../felhom.eu/scripts/customer_copy_vocab.py (same sibling-path pattern as controller_gates.py:48) and delete the STEMS literal; absent sibling = INCONCLUSIVE exit 2. Follow-up (felhom.eu, separate commit): remove hub_copy_gate.py's drift check, which would then fail to find STEMS. — felhom-controller/controller/scripts/retrieval_promise_gate.py:54 still has its own | 6 |
| R-327 | P4 | STILL-TRUE-NOT-SMALL | felhom.eu/documentation/architecture/where-felhom-stands.yaml:126-130 still: id claim.code-naming, title "The same word is used for two different secrets across three surfaces; the email points at a page a rebuilt machine does not show", status: partial. Needs the operator's capability-map ruling first (dataset may not be raised on its own). | 4 |
| R-331 | P4 | STILL-TRUE-NOT-SMALL | felhom-controller/controller/internal/agentapi/diskverdict.go:34 uncorrectableFailCount = 64; :33 comment still defers 'growth-rate detection once the box keeps history'. No growth-rate rule found. New mechanism (M). | 4 |
| R-336 | P4 | STILL-TRUE-NOT-SMALL | No source change reduces the ep0 poll rate (pvestatd interval is Proxmox-side, not in our repos). Design question (does the hub need a 15-min fill reading) remains; acceptance needs an ep0 access-log measurement. Scaling item, not small. | 3 |
| R-337 | P4 | UNCHECKED | Live-only behaviour (WATCHING). From source: felhom-agent/internal/localapi/server.go:518 serves GET /backup/status and :1258 answers from s.pickLatestBackup (the in-memory store), which suggests collection cadence, but the refresh path after an out-of-schedule run was not established within the time box. | 6 |
| R-345 | P4 | STILL-TRUE-SMALL | FIX: Delete lines 21-22 (or move them behind an explicitly named opt-in target with a comment). Whether a stale :latest already sits on the registry is a separate live check for a session allowed to query it. — felhom.eu/hub/Makefile:21 'docker tag $(IMAGE):$(VERSION) $(IMAGE):latest' and :22 'docker push $(IMAGE):latest' still present; only commit touching the Makefile is 77b5a4ce (initial). |
3 |
| R-346 | P4 | NOT-WORTH-IT | PICK close-as-accepted (audit done, zero instances): A warning that a future reader might anchor an uptime slope on systemd's ActiveEnterTimestamp instead of the process start time. | 4 |
| R-348 | P4 | STILL-TRUE-SMALL | FIX: Reword the comment: the backups list IS lost on restart and refills only when a backup runs; the hub's freshness VERDICT is unaffected because it looks back 7 days (hub monitor/deadline.go backupEvidenceLookback, pinned by deadline_anchor_test.go TestCheckBackupDeadlines_RestartBlindWindow_NoEvent). — felhom-agent/internal/backup/store.go:28 still reads '// Backups are unaffected — their fres | 6 |
| R-352 | P4 | STILL-TRUE-NOT-SMALL | Placement half is an open operator ruling (SPEC-app-data-placement-2026-08-21.md, 'Viktor rules'); deploy route still has no server-side default: GetDefaultStoragePath has no caller in internal/stacks (grep returns only internal/api/router.go:1137 systemInfo). Point (2) is carried by R-368. | 4 |
| R-364 | P4 | STILL-TRUE-SMALL | FIX: A helper that, for a pattern containing a byte >= 0x80, also runs an ASCII anchor (must hit) and a negative control (must miss) and refuses to print a zero unless both behave; documented in the felhom-evidence or ui-hungarian rule as the way to search Hungarian text. — No helper exists: ls felhom.eu/scripts shows nothing grep/accent-related, and no script mentions '0x80' or 'negative control' | 4 |
| R-365 | P4 | STILL-TRUE-SMALL | FIX: Set AbandonOverdue when DueAt is past and render a new key ('a törlés esedékes, a következő napi karbantartáskor lefut' / English twin) instead of the future-tense sentence. — felhom-controller/controller/internal/i18n/locales/hu.json:368 'A kérésed szerint a korábbi távoli mentéseidet {{.AbandonDate}} napján véglegesen töröljük (még ... nap)'; handlers.go:1164-1167 sets Aban | 5 |
| R-367 | P4 | NOT-WORTH-IT | PICK close-as-accepted (or delete it the next time the box is reprovisioned): One old 312 KB paperless database dump on the demo-hp test box sits under the app's old folder name; nothing reads or deletes it. | 4 |
| R-368 | P4 | STILL-TRUE-SMALL | FIX: Reword the field comment: the deploy FORM pre-selects this path (templates/deploy.html:614); the deploy API applies no default when HDD_PATH is omitted. (The alternative — a server-side default — is a behaviour change and not small.) — felhom-controller/controller/internal/settings/settings.go:572 'IsDefault bool json:"is_default,omitempty" // new apps use this by default' (line moved from |
5 |
| R-371 | P4 | NOT-WORTH-IT | PICK close-as-accepted with one line in 07-backup-architecture saying success is silent by design because failure and staleness are alarmed: The weekly off-site backup sends no 'done' event, while the two local tiers do. Failures and an 8-day staleness deadline are already alarmed. | 6 |
| R-372 | P4 | NOT-WORTH-IT | PICK close-as-accepted: An optional idea from July: show 'this second-drive copy was never made because its source is missing' separately from 'last copy failed' in the operator screen. | 5 |
| R-373 | P4 | FIXED-BY-LATER-WORK | Premise (20G/50G two-volume mismatch, 'nothing sets SysDataGrowGB') was retired by agent v0.120.0 one-data-volume work, commit cd6e267 'v0.120.0 — one data volume (R-165...)'. felhom-agent/internal/reconcile/bringup.go:191 '// SysDataGrowGB is a COMPATIBILITY INPUT since agent v0.120.0 (R-165). There is no longer a second' and :437 'growGB := spec.DataVolGrowGB + spec.SysDataGrowGB'; installer pas | 6 |
| R-374 | P4 | NOT-WORTH-IT | PICK close-as-accepted, with one line in the audit saying the three are not recoverable: A July audit says three borderline cases were left unfiled but never named them. | 5 |
| R-375 | P4 | UNCHECKED | Requires a read-only check on ep0 (token's datastore audit permission); not verifiable from source and ssh is out of scope for this checker. | 2 |
| R-376 | P4 | STILL-TRUE-SMALL | FIX: Carry the same marker legend paragraph into the three documents written after the 2026-08-22 pass; then close the row, since 'mark as sessions touch them' is a standing practice already in the template, not a defect. — Legend present ('not yet classified') in 00..06 and 10 of documentation/architecture/, but MISSING in the newer 08-alarm-ladder.md, 09-update-architecture.md and 11-os-updates. | 5 |
| R-377 | P4 | STILL-TRUE-SMALL | FIX: Turn each ruling's opening bold line 'S-NN — TITLE (date ...).' into a '### S-NN — TITLE (date)' heading, changing no other byte; no compression, no reordering. — felhom.eu/CONTEXT.md:1537 '## Standing rulings' runs to EOF: 189,685 bytes, 0 '###' sub-headings, 153 bullets, 39 distinct S- ids; each ruling starts as a bold paragraph e.g. '**S-39 — "WE DO NOT KNOW" IS NEVER DRAWN AS "FINE".. | 6 |
| R-390 | P4 | FIXED-BY-LATER-WORK | Commit 2344589a ('... runbook pveam note'); felhom.eu/documentation/runbooks/RUNBOOK-manual-build.md:154 '2. Run pveam update first — the virgin snapshot's template INDEX is stale too, and a stale index fails as a bogus'. |
3 |
| R-391 | P4 | STILL-TRUE-SMALL | FIX: Take the row's second option: state in CLAUDE.md that the catalog REPORT.md carries no observations section by convention (findings go straight to the register), so gate 11 is not needed here. The runner refactor (first option) is the bigger alternative. — app-catalog-felhom.eu/scripts/catalog_gates.py has no SHARED_ / observations entry (grep 'SHARED_/observations' returns nothing); app-cata | 4 |
| R-392 | P4 | STILL-TRUE-NOT-SMALL | ls felhom.eu/documentation/architecture shows no agent-tooling/workflow document (00-11 are all product; plus _design-review, _hub-review, _recovery-inventory). Writing a new architecture document is more than an hour and needs the operator's view of the split. | 3 |
| R-393 | P4 | NOT-WORTH-IT | PICK close-as-accepted (superseded in practice by unprompted-work.md §2/§4): A proposed skill plus helper script to log every decision an unattended run makes. | 4 |
| R-394 | P4 | STILL-TRUE-NOT-SMALL | wc -l felhom.eu/skills/felhom-build-deploy/SKILL.md = 186 (was 179 at filing — grew); scripts/check_skills.py:45 GRANDFATHERED still holds the exemption. Trim needs a session that can verify the build/deploy commands it keeps. | 3 |
| R-402 | P4 | STILL-TRUE-NOT-SMALL | No hub Go/template reads last_integrity_ok/_depth (grep in hub/internal returns nothing); still allowlisted at felhom.eu/scripts/wire_contract_gate.py:163 and :220. Needs the operator's decision on what the screen says. | 3 |
| R-416 | P4 | STILL-TRUE-SMALL | FIX: Apply the existing RULE 3 duplicate check to CLOSED-ITEMS.md too (suffixed ids like R-88a/R-88b stay distinct), and update the closed_register_gate.py:53 hole list to point at it. — Partly covered: scripts/register_shape_gate.py:120 'RULE 3 — duplicate: {rid} already has a row at line ...' (added in 462ab4a5, R-627) now refuses a duplicate id WITHIN OPEN-ITEMS.md only (REG path at :84 = OPEN- |
7 |
| R-418 | P4 | STILL-TRUE-SMALL | FIX: Add the two missing gates to the docstring list and a test that parses the docstring's gate labels and asserts they equal [g[0] for g in GATES]. — It drifted AGAIN: felhom.eu/scripts/repo_gates.py docstring lists 1-14 (+9b) = 15 gates while GATES has 17 — 'script-tests' and 'decoy-coverage' are registered but not listed (python import: len(GATES)=17). No test compares the two. | 5 |
| R-420 | P4 | NOT-WORTH-IT | PICK close-as-accepted (add it with the first gate that needs it): The felhom.eu gate runner cannot mark a gate as advisory-only; the controller runner can. | 3 |
| R-421 | P4 | STILL-TRUE-NOT-SMALL | Deliberate class row ('stays open as the place the next instance is recorded'); its open instances R-422..R-426 are still open in this batch. Not a fixable item by itself. | 2 |
| R-422 | P4 | STILL-TRUE-NOT-SMALL | felhom.eu/scripts/reuse_refs_check.py:41 PATH_RE still ends '.(?:go/py/html/css/yml/yaml/sh)\b' — no .md. Widening it needs a false-positive walk across all four repos' REUSE.md/CLAUDE.md citations (the row says that pass is the work). | 3 |
| R-423 | P4 | STILL-TRUE-SMALL | FIX: Discover website/**/*.html and FAIL on any page not in PAGES (or glob and keep PAGES only as exceptions); flip the decoy test to expect conviction and drop the 'site' EXEMPT entry. — felhom.eu/scripts/site_gates.py:22-27 hardcoded PAGES list; website/ today holds exactly those 9 files, so nothing is missed today, but a new page is not scanned. | 4 |
| R-424 | P4 | NOT-WORTH-IT | PICK close-as-accepted (hole stays declared in the gate's docstring): The roadmap gate cannot tell a real defect filed as an 'idea' from a genuine idea. | 3 |
| R-425 | P4 | STILL-TRUE-SMALL | FIX: Scan by pattern (templates/backups*.html, offbox.go) plus internal/i18n/locales/hu.json, or assert FILES against a discovered set so an unclassified file fails; drop its decoy-coverage exemption. — felhom-controller/controller/scripts/offbox_rename_gate.py:16-20 FILES = backups.html, offbox_handlers.go, offbox.go only; templates/backups_remote.html exists and is not scanned, and customer co | 6 |
| R-426 | P4 | STILL-TRUE-NOT-SMALL | felhom.eu/scripts/decoy_coverage_gate.py EXEMPT now has 19 entries (loaded via python): hub-copy is gone, felhom-agent 'release-complete' is new; group (d) gates (hostinstall, wire-contract, due-checks, published, image-resolvable, volume-persistence) all still exempt. | 5 |
| R-427 | P4 | FIXED-BY-LATER-WORK | Commit 71b8c8c6 (Backlog triage Part B: '... closed_register_gate RULE 3 refuses a finished row in OPEN-ITEMS'); felhom.eu/scripts/closed_register_gate.py:10 'RULE 3 — (2026-10-03) no row in OPEN-ITEMS.md may carry a CLOSED-family word (CLOSED, SHIPPED,'. Of the 12 named rows, R-385/387/341/378/405/88a/88b/123 are now only in CLOSED-ITEMS.md; R-190 and R-352 remain open (partly-closed, as the ro |
5 |
| R-437 | P4 | FIXED-BY-LATER-WORK | felhom.eu 71b8c8c6 'Backlog triage Part B: 125 finished rows + 20 id-less rows moved to CLOSED-ITEMS ... closed_register_gate RULE 3 refuses a finished row in OPEN-ITEMS (decoys, seen red) ... register 444 -> 325'. felhom.eu/scripts/closed_register_gate.py:10 'RULE 3 — (2026-10-03) no row in OPEN-ITEMS.md may carry a CLOSED-family word'. Gate run today: 'closed-register gate OK — no open work fi |
4 |
| R-445 | P4 | NOT-WORTH-IT | PICK close-as-accepted: The hub's per-app memory suggestion can be built from samples of an app that no longer runs anywhere (e.g. a 15-minute test install). | 5 |
| R-451 | P4 | STILL-TRUE-NOT-SMALL | felhom-controller/controller/internal/report/types.go ContainerDetailReport still carries only Name/State/CPUPercent/MemoryMB (no image field). Ruled (09 §3 decision 18), build deferred until fleet grows; needs controller payload + hub denormalisation + fleet page across two repos. | 3 |
| R-454 | P4 | STILL-TRUE-SMALL | FIX: Add a gofmt -l gate (fails on any listed file, INCONCLUSIVE if gofmt missing) to controller_gates.py, see it red on today's tree, then one gofmt -w formatting commit for the 12 files. — The five files named are now clean (gofmt -l controller/internal/web/ prints nothing), but gofmt -l controller in felhom-controller lists 12 OTHER files today: cmd/controller/main.go, internal/agentapi/diskv |
5 |
| R-457 | P4 | STILL-TRUE-SMALL | FIX: Read the six candidates; for each date literal that feeds an assertion evaluated against time.Now(), derive it from now (as the R-457 fix did). The faked-future-date CI instrument is a separate, larger idea and should be split out or dropped. — No later commit references R-457 beyond the filing release (felhom-controller 38d28b5 v0.234.0 / 998aa31 REPORT). No faked-clock CI run exists (grep f | 4 |
| R-460 | P4 | NOT-WORTH-IT | PICK close-as-accepted: BookStack's uploaded files cannot be checked automatically after an upgrade; only its database can. | 2 |
| R-464 | P4 | FIXED-BY-LATER-WORK | Lesson homed and harness uses the correct probe. app-catalog-felhom.eu b7ef0c4 'upgrade-test.py: record the engine's own view of its datadir'; app-catalog-felhom.eu/scripts/upgrade-test.py:278 '"mariadb-upgrade --check-if-upgrade-is-needed --user=root "'. felhom.eu d6837d98 (SPIKE R-459); felhom.eu/documentation/architecture/09-update-architecture.md:1647 '1. Ask the engine, not the log. Maria |
4 |
| R-488 | P4 | UNCHECKED | The claim is a measured suite runtime (5.5 min); confirming it needs running go test ./internal/backup, which I did not run (read-only; backup tests may reach real docker on DooPlex). No commit after filing (felhom-controller 24d7c54) mentions R-488 or a test-speed change in internal/backup (git log --grep on internal/backup since 2026-09-13: empty), so it is likely still true. | 3 |
| R-492 | P4 | STILL-TRUE-SMALL | FIX: Remove Paths.HDDPath, its env binding and each reader's dead global branch, keeping the per-app/discovered fallbacks each reader already uses. — cfg.Paths.HDDPath still defined and read: controller/internal/config/config.go:167 'HDDPath string yaml:"hdd_path"', :453 envStr("FELHOM_PATHS_HDD_PATH", &cfg.Paths.HDDPath); readers internal/report/builder.go:69, internal/monitor/healthchec |
4 |
| R-494 | P4 | STILL-TRUE-NOT-SMALL | felhom.eu/hub/internal/cloudflare/ holds only unblock.go; no tunnel/DNS creation code in hub (grep cfd_tunnel: none). Building it is a new Cloudflare-API mechanism on the hub; operator ruled it non-blocking. | 3 |
| R-501 | P4 | FIXED-BY-LATER-WORK | felhom.eu a4993272 'CLAUDE.md: the CI-check recipe was wrong in two ways, both measured today'. felhom.eu/CLAUDE.md:176 'rows — a run can sit several pages earlier. Scan every page and match on head_sha; with a'; recipe at CLAUDE.md:166-168 loops every page. |
3 |
| R-502 | P4 | STILL-TRUE-SMALL | FIX: Register bootstrap-modes.sh in repo_gates.py behind a docker-available check that reports INCONCLUSIVE (never pass) when docker/the felhom-iso-assistant image is absent, plus a decoy (a broken banner must turn it red). — felhom.eu/scripts/iso/test/bootstrap-modes.sh exists; grep -rn 'bootstrap-modes/bootstrap_modes' scripts/*.py .gitea/workflows in felhom.eu returns nothing — no gate or CI |
3 |
| R-503 | P4 | NOT-WORTH-IT | PICK close-as-accepted (as DECLINED by ruling; the three measurements stay in the closed row for any future reversal): An idea, offered and not chosen: the installer would pick the disk itself when there is exactly one. | 2 |
| R-504 | P4 | UNCHECKED | The claim (iso.felhom.eu/ returns 404) is live-only; I may not curl hosts. felhom.eu/documentation/runbooks/VOLUNTEER-first-hour.md:14 still says 'iso.felhom.eu/ itself still has no index — R-504'. Fix needs a Cloudflare rule the operator owns. Cosmetic; households use felhom.eu/letoltes (website/letoltes.html exists). |
3 |
| R-507 | P4 | STILL-TRUE-NOT-SMALL | Needs measuring QEMU input-send-event or a VNC client against a live VM on felhom-pve — a live-machine spike, not a source change. No later commit references R-507. | 2 |
| R-525 | P4 | STILL-TRUE-NOT-SMALL | Row itself states it is a new unmeasured mechanism (forwardAuth / Quantum proxy auth) needing a scratch-guest spike. | 1 |
| R-526 | P4 | STILL-TRUE-NOT-SMALL | felhom.eu/hub/internal/tenantsync/client.go:110 '// Deprovision DESTROYS the customer's PBS namespace, all its backup groups, and its token — the'; no token-only op exists. Needs a new op on protected ep0 and an operator yes/no. | 3 |
| R-527 | P4 | NOT-WORTH-IT | PICK close-as-accepted (with the corrected facts: flag read into LockedFields, enforced only by uncalled UpdateStackConfig): A catalog flag that marks some settings 'locked after install' changes nothing visible: the page makes every setting read-only anyway, and the edit path that would honour the flag is never called. | 8 |
| R-532 | P4 | NOT-WORTH-IT | PICK close-as-accepted: Vaultwarden's web page shows a sign-up form even though sign-ups are off; the server then refuses it. | 3 |
| R-541 | P4 | STILL-TRUE-NOT-SMALL | Row: needs a new copy/re-key/release mechanism and a design; no later commit references R-541. Far off per re-rank (0.3% full, one pool box). | 2 |
| R-544 | P4 | STILL-TRUE-SMALL | FIX: Change the log line to state the effect, e.g. 'host deleted: %s (escrow custody demoted to retained)' when escrow existed, and drop the boolean name from the text. — felhom.eu/hub/internal/web/hosts.go:917 's.logger.Printf("[INFO] host deleted: %s (escrow deleted: %v)", hostID, deleteEscrow)'. | 3 |
| R-551 | P4 | NOT-WORTH-IT | PICK close-as-accepted (add 'walk R-546 readiness branches' to the next fresh-install checklist instead): The escrow 'waiting for the agent' screens are proven by tests but never seen on a real box in that state. | 2 |
| R-555 | P4 | STILL-TRUE-SMALL | FIX: Strip Go // and /* / comments and template {{/ */}} before TOKEN_RE in receiver_tokens; add a decoy 'tag named only in a receiver comment must convict'. Newly surfacing tags each become a finding (allowlist with reason or a row). — felhom.eu/scripts/wire_contract_gate.py:451 'def receiver_tokens(repo_root):' tokenises whole files: line 482 'toks.update(TOKEN_RE.findall(fh.read()))' — no com | 3 |
| R-564 | P4 | STILL-TRUE-SMALL | FIX: Add split-form Hungarian patterns (állíthatók? vissza, (hoz/szerez/nyit)\w* vissza), register the Hungarian occurrences found (the seven already reviewed in English), and add a planted split-verb decoy. — felhom-controller/controller/scripts/retrieval_promise_gate.py:54 'STEMS = ["visszaállíthat", "visszaszerezhet", "visszahozhat", "visszanyit"]' — joined forms only, no split-verb pattern. | 3 |
| R-567 | P4 | STILL-TRUE-SMALL | FIX: Add (eq .Page "storage_init") (eq .Page "storage_attach") to $storageOpen and mark the Meghajtók link active for them. — controller/internal/web/templates/layout.html:83 '{{$storageOpen := or (eq .Page "storage") (eq .Page "storage-network")}}' — storage_init/storage_attach not included; storage_handlers.go:351 'data := s.baseData(tmpl, title)' passes the template name as Page. | 4 |
| R-568 | P4 | STILL-TRUE-SMALL | FIX: Sort rows by diskKey(d) (durable id, falling back to name) before returning. — controller/internal/web/disk_health.go:124-152 diskHealthRows appends rows in resp.Disks order; no sort in the file (grep 'sort.' in disk_health.go: none). | 3 |
| R-569 | P4 | STILL-TRUE-SMALL | FIX: Add KindErrorf-style sentinels in internal/stacks (protected, not found, not deployed/still running, not orphaned), a statusFor helper per handler family replacing the three Contains blocks. — controller/internal/api/router.go:742 'if strings.Contains(err.Error(), "protected") {', also :745, :1018, :1021, :1024 ('not deployed'/'still running'), :1102, :1105, :1108 ('not orphaned'). | 3 |
| R-570 | P4 | STILL-TRUE-NOT-SMALL | Fallback still present: controller/internal/web/handlers.go:1050 'offboxStaleWarningMarker = "nincs mentésre jelölt alkalmazás"'; producer internal/backup/offbox.go:1168. Closing depends on a fleet condition (every box one off-site run on >=0.251.0) — a watch, not a fix. | 3 |
| R-571 | P4 | STILL-TRUE-SMALL | FIX: Add a short section to 07 listing the six failure classes, what each means for the customer, and that restic/ssh signatures are external; add an alert-placement paragraph (inline under storage bars vs top banner) to 02. — grep ClassifyOffsiteFailure/PageOnly/Inline in felhom.eu/documentation/architecture/07-backup-architecture.md and 02-controller-module-map.md: no hit. Classifier lives at fe | 3 |
| R-574 | P4 | STILL-TRUE-NOT-SMALL | controller/internal/web/handler_debug.go still carries 40 lines with accented Hungarian string literals (grep -cP count); last touched by 0c702f8 v0.279.0, not converted. Labelling ~40 literals page-copy vs payload, adding en/hu keys and parity fixtures exceeds an hour. | 3 |
| R-576 | P4 | STILL-TRUE-NOT-SMALL | felhom-controller/controller/scripts/i18n_go_parity.py has no call-site argument-count or '+'-adjacency check (grep verb/argument: only VERB_RE/strip_verbs for text equality, lines 76-78, 196-199). Parsing multi-line Go call arguments reliably from Python with decoys is likely >1 h. | 4 |
| R-577 | P4 | STILL-TRUE-NOT-SMALL | Waiting on an operator decision (what the share feature promises a stranger); felhom.eu/documentation/architecture/10-localisation.md table row 'the two guest share pages, the catch-all / a stranger / nobody / no globe / — (R-577, the operator's)'. | 2 |
| R-579 | P4 | STILL-TRUE-NOT-SMALL | Gate deliberately deferred until R-554 deletes the first-boot wizard; R-554 is still OPEN (OPEN-ITEMS.md:131). Versionless links remain in controller/internal/setup/templates/setup_*.html:8 '' (8 files). | 5 |
| R-588 | P4 | STILL-TRUE-SMALL | FIX: Name the single home documentation/tests/iso-release--/ in the Result-recording section, and add a pointer dir/README for 1.28.0 to its audit record (evidence-backup-promise-2026-09-16/phaseD-iso-gate.txt). Optional existence check left out. — felhom.eu/documentation/runbooks/iso-release-gate.md:319-322 'Result recording' says only 'in the release report' — names no home. documenta | 4 |
| R-591 | P4 | STILL-TRUE-SMALL | FIX: Deep-copy Meta.I18n in deepCopyStack (map plus nested values). — The copy is deepCopyStack in controller/internal/stacks/manager.go (row says Copy()); it deep-copies AppConfig (:1137-1148), DeployFields (:1162), OptionalConfig (:1174), Integrations (:1186) and has no I18n line (grep I18n in manager.go: none). Meta.I18n defined at internal/stacks/metadata.go:94. | 4 |
| R-594 | P4 | STILL-TRUE-SMALL | FIX: Add ALLOWLIST_EN of (app, path, reason); registered occurrences pass, unregistered convict, and any entry matching nothing is itself a failure. — app-catalog-felhom.eu/scripts/check-copy-i18n.py: grep ALLOWLIST/allowlist — no hit; no way to register a true occurrence. | 3 |
| R-599 | P4 | STILL-TRUE-SMALL | FIX: Make both 409 bodies say when the last report arrived and when deletion opens (last report + configured stale threshold), and name the wait in target-selection.md's drill section. — felhom.eu/hub/internal/web/hosts.go:898 'http.Error(w, "Host is ONLINE — deletion is refused (a live agent would receive 401s permanently).", http.StatusConflict)' — no last-report age or opening time. target-sele | 4 |
| R-602 | P4 | FIXED-BY-LATER-WORK | felhom.eu e02bc038 'hub v0.119.0 — ... R-596/R-598 closed' added the finding; felhom.eu/documentation/architecture/10-localisation.md:809-812 'the felhom_lang cookie and got the Hungarian page for en. ... The cookie is the right instrument for the anonymous claim page and the wrong' and :509 'langFor's order is fixed: ?lang= → the household's setting when a session exists'. Onl |
4 |
| R-603 | P4 | STILL-TRUE-SMALL | FIX: Add a test helper that compares against html.EscapeString(want) and use it in the render tests that assert English copy; the bundle gate with a 27-entry allowlist is the larger alternative. — No gate or helper: grep for html.EscapeString(want/'/R-603 in felhom-controller/controller scripts+internal: none. controller/internal/i18n/locales/en.json has 27 lines containing an apostrophe today | 4 |
| R-605 | P4 | STILL-TRUE-SMALL | FIX: Give harness-level refusal its own exit code (e.g. 3 = REFUSED) in both scripts and map it to a distinct label in catalog_gates.py. — app-catalog-felhom.eu/scripts/catalog_gates.py:122 'VERDICT = {0: "OK", 1: "FAILED", 2: "INCONCLUSIVE"}' — harness refusal and per-app undetermined both exit 2 and print the same word. | 3 |
| R-610 | P4 | NOT-WORTH-IT | PICK close-as-accepted: A power cut landing inside the sub-second starting phase has never been measured; all three live cuts landed in verifying, which runs the same recovery code. |
5 |
| R-617 | P4 | FIXED-BY-LATER-WORK | felhom.eu@462ab4a5 (2026-09-22) documentation/architecture/09-update-architecture.md:1969 "POST /api/v1/repos/migrate is the route that works (the project's Gitea tokens carry" - continues at :1970 "write:repository but not write:user, so POST /user/repos answers 403"; recipe at :1979. The one-line note the row asked for exists (in the architecture doc rather than operations/). The optiona |
4 |
| R-618 | P4 | STILL-TRUE-NOT-SMALL | Remaining open work = the controller-side idea (let verifying accept docker's own healthy). grep for docker health status in felhom-controller@7690c27 controller/internal/stacks/update.go returns nothing; no R-618 reference in Go source. It is an undecided design question (operator), not a defect; the three probe fixes (app-catalog@793c4fb) and the gate scripts/check-probe-matches-compose.py a |
4 |
| R-619 | P4 | STILL-TRUE-SMALL | FIX: In getDeployFields, copy meta.DeployFields and set Required=true for every field with Type=="password" before writing the response (copy, do not mutate the shared metadata; the web deploy page uses GetDeployFields separately and is untouched). — felhom-controller@7690c27 controller/internal/api/router.go:395 meta, appCfg, err := r.stackMgr.GetDeployFields(name) then :402 `"metadata": meta |
6 |
| R-621 | P4 | STILL-TRUE-NOT-SMALL | Capture is done: felhom-controller@7690c27 controller/internal/stacks/update.go:1054 outDir := filepath.Join(dir, "hold-logs", ts). The open part (show it on the app page's hold panel / logs fallback) is not built: grep for hold-logs/holdLogs in controller templates and handlers returns only update.go:1050-1082 and undo.go:535,550 (writers). Surfacing needs a page change with HU/EN copy and a de |
4 |
| R-624 | P4 | STILL-TRUE-NOT-SMALL | Row's own latest update: remaining class is vaultwarden (closed sign-up by design) and code-server; the open decision is whether the harness may hold an app's admin secret (operator). Not verifiable further from source; needs a decision, not a fix. | 2 |
| R-644 | P4 | UNCHECKED | About the live state of gokapi on scratch guest 9202 (crash-loop, deployed:true). Only the box shows it; no ssh allowed. | 1 |
| R-652 | P4 | STILL-TRUE-NOT-SMALL | app-catalog@917a779 templates/romm/.felhom.yml:249 still carries "memory_peak_pct": 80.9 with "memory_tight": true and no memory_basis: anon (contrast paperless-ngx/.felhom.yml:249 "memory_basis": "anon"). Needs a live re-measure of romm plus an undecided cache-thrash rule. |
4 |
| R-654 | P4 | NOT-WORTH-IT | PICK close-as-accepted: opengist 1.15 moved its pages under /-/; an old /login bookmark answers 404. The front page redirects correctly. | 3 |
| R-687 | P4 | NOT-WORTH-IT | PICK close-as-accepted: Three live proofs a scratch box cannot give (a 3-hour leg, a failing off-site leg, a files_may_change step without a whole copy) plus one log text that names the window's deadline instead of a manually started leg's deadline. | 5 |
| R-688 | P4 | NOT-WORTH-IT | PICK close-as-accepted: Deleting a customer does not remove their Cloudflare tunnel and DNS records; the dialog now says so and lists what to remove by hand. | 4 |
| R-691 | P4 | STILL-TRUE-NOT-SMALL | Open work = the Tier 2 (second-drive) path of Use/Load is not live-proven; needs a two-drive Tier-0 box (9202 has one drive). Live-only gap, not a source defect; not checkable from source. | 2 |
| R-693 | P4 | STILL-TRUE-NOT-SMALL | grep for memory_scales_with_limit / scales_with_limit across app-catalog-felhom.eu, felhom-controller/controller and felhom.eu/scripts returns nothing - no basis that tells growth-to-fill from pressure exists. Needs a design (new harness signal). | 3 |
| R-705 | P4 | FIXED-BY-LATER-WORK | The remaining half (manual whole-guest backup) EXISTS and predates the row: felhom-controller bbed5af (v0.47.0, 2026-06-12) 'backups page — whole-guest backup visibility + manual trigger'. Live source @7690c27: controller/internal/web/backup_handlers.go:324 case r.URL.Path == "/api/guest-backup/trigger" && r.Method == http.MethodPost:; :340 if err := s.backupTrigger.TriggerNow(); err != nil {; |
8 |
| R-707 | P4 | STILL-TRUE-NOT-SMALL | Open work = live proof that the gate OPENS for seerr, outline and rallly (needs a media server / e-mail on a test box). Live-only proof gap; the gating itself is in source (catalog 6faf432 per row). | 2 |
| R-718 | P4 | STILL-TRUE-SMALL | FIX: Add a key app_info.close_signup_restart ("The app restarts once for this." / HU twin) and render it under the close card when the app has an after_setup env switch (the same SignupNative fact); add the same sentence to the gate-open confirmation where after_setup.env exists. — felhom-controller@7690c27 controller/internal/web/templates/app_info.html:112 ` {{T "app_info.close_signup_text"}}< |
6 |
| R-719 | P4 | STILL-TRUE-NOT-SMALL | Built: felhom.eu hub/internal/web/selfbind.go:160 "// R-719 (v0.126.0): „Új linket kérek" on an expired or used link." Open part is the operator's review of the changed shape and a live mint+send proof (unit-proven only) - an operator decision, not a CC fix. | 3 |
| R-725 | P4 | STILL-TRUE-SMALL | FIX: Reword bind.invalid.body to point at the button below (e.g. 'Ha lejárt, kérj újat lent.' / 'If it has expired, ask for a new one below.'), keeping the operator alternative; optionally drop the ✔ glyph the console font renders as 'V' and update the golden. — felhom.eu hub/internal/i18n/locales/hu.json:79 `"bind.invalid.body": "A hivatkozás 7 napig érvényes. Ha lejárt, kérj újat az ügyfélszolgá | 6 |
| R-731 | P4 | STILL-TRUE-NOT-SMALL | The shape-switch control lives only in audit tools: felhom.eu/documentation/audits/catalog-currency-2026-09-30/00-currency.py, 04-analyse.py; no standing currency script in app-catalog-felhom.eu/scripts or felhom.eu/scripts (ls/grep for currency/shape returns only golden_currency_gate.py, which is unrelated). Making it standing means promoting a registry-reading tool with tests - more than an hour | 4 |
| R-734 | P4 | STILL-TRUE-NOT-SMALL | grep for '.immich' / hash ignore list in app-catalog-felhom.eu/scripts/*.py and templates/immich/.felhom.yml returns nothing - no exclusion exists. The row says the rule change needs an operator word; calibre-web shows the mark is sometimes right, so the rule needs design. | 3 |
| R-739 | P4 | STILL-TRUE-NOT-SMALL | app-catalog@917a779 templates/wanderer/docker-compose.yml:117 image: getmeili/meilisearch:v1.36.0; grep MEILI_UPGRADE_DB in the compose returns nothing. Remaining: the template switch, a fixture (PocketBase create refused) and a measured step on the bench - live work. |
3 |
| R-759 | P4 | STILL-TRUE-NOT-SMALL | Five checklist rows of wger need live measurement on 9202 (2.5, 3.7, 6.3, 8.2, 9.1); not verifiable from source. | 2 |
| R-760 | P4 | STILL-TRUE-SMALL | FIX: Read the vikunja 2.6.0 image config for a HEALTHCHECK/shell; if none and the image has no shell, add a comment saying why there is no compose healthcheck (like adventurelog-frontend's R-655 comment); otherwise add a healthcheck of the family the image supports (REUSE.md §2). No image: line moves, so no catalog_since. — app-catalog@917a779 templates/vikunja/docker-compose.yml: service vikunja | 4 |
| R-761 | P4 | STILL-TRUE-SMALL | FIX: Change the comment to name {slug}-logo.svg (preferred) and {slug}-logo.png (fallback), matching config.go AppLogoURL/AppLogoPNGURL; comment-only. — app-catalog@917a779 templates/paperless-ngx/.felhom.yml:22 # Logo: {assets.base_url}/assets/{slug}-logo.webp vs felhom-controller controller/internal/config/config.go:511 return fmt.Sprintf("/static/assets/%s-logo.svg", slug) and |
3 |
| R-764 | P4 | STILL-TRUE-NOT-SMALL | grep smtp/mail in app-catalog templates/wger/.felhom.yml and docker-compose.yml finds only first_steps text (.felhom.yml:74 'Add meg az email címedet a beállításokban'); no smtp_mapping. A mapping needs a live boot proof with mail off (REUSE.md §2) - more than an hour; wger is hidden. | 3 |
| R-766 | P4 | FIXED-BY-LATER-WORK | Hub releases after the assets push (felhom.eu 40f07429, 2026-10-01): hub v0.131.0 (2026-10-04) .. v0.136.0 (d4be9f6f, 2026-10-05). The build copies website assets: felhom.eu scripts/build-hub.sh:98 cp "${WEBSITE_ASSETS_DIR}"/*-logo.svg "${BUILD_DIR}/assets/" 2>/dev/null // true, and the hub build workspace /mnt/5_hdd/felhom.eu/build/felhom-hub/workspace/assets/ holds radicale-logo.svg + 3 screen |
8 |
| R-768 | P4 | NOT-WORTH-IT | PICK close-as-accepted: Grimoire is not built because upstream rules out public exposure and ships no image for v1.x; the row only watches for that to change. | 1 |
| R-769 | P4 | STILL-TRUE-NOT-SMALL | New-app idea waiting on an operator decision (a fork as new upstream, after R-767). No source to check. | 1 |
| R-770 | P4 | STILL-TRUE-NOT-SMALL | New-app idea waiting on the operator's go/no-go (CC recommends not building). No source to check. | 1 |
| R-771 | P4 | STILL-TRUE-NOT-SMALL | New-app idea waiting on the operator's go/no-go. No source to check. | 1 |
| R-779 | P4 | STILL-TRUE-NOT-SMALL | Live proof gap on the real Cloudflare tunnel needing the operator's phone off wifi; not checkable from source. | 1 |
| R-781 | P4 | STILL-TRUE-SMALL | FIX: After the clone, delete the real onboarding/.md records (all but _TEMPLATE.md and the exempt wger.md the cases use) from the scratch clone, so genuine cases judge only the records they build; alternative: point the stand-in sibling at the real felhom.eu documentation tree read-only. — app-catalog@917a779 scripts/test_gate_decoys.py:498 `sh(["git", "clone", "-q", "file://" + ROOT, cat], c | 6 |
| R-786 | P4 | STILL-TRUE-NOT-SMALL | app-catalog@917a779 onboarding/sparkyfitness.md has 8 '/ open' rows, incl. :18 0.5, :20 0.7, :28 1.6, :29 1.7, :58 5.4, :68 8.3 (plus 0.1 licence = R-784, 2.1 = R-807). Most need live measurement (runtime internet, phone sign-in, second memory watch). | 3 |
| R-793 | P4 | NOT-WORTH-IT | PICK close-as-accepted: Four apps ship enterprise/BUSL code that is off as Felhom runs them; the row reminds us never to enable EE features or the -enterprise meilisearch image. | 2 |
| R-794 | P4 | STILL-TRUE-NOT-SMALL | app-catalog@917a779 seven redis 7 images: dawarich/docker-compose.yml:164 image: redis:7.4-alpine, docmost:86, immich:123, outline:88, nextcloud:103, paperless-ngx:125, romm:136 image: redis:7-alpine. Moving each needs a harness-proven ladder step (7 apps). |
3 |
| R-796 | P4 | NOT-WORTH-IT | PICK close-as-accepted: MeTube's browser/phone 'send to MeTube' helpers cannot pass the family gate; households paste links in the page. | 2 |
| R-797 | P4 | NOT-WORTH-IT | PICK close-as-accepted: CI's single-repo clone cannot check rule 3 of the family-gate gate; it says NOT CHECKED, and the pre-push hook checks it. | 2 |
| R-798 | P4 | STILL-TRUE-SMALL | FIX: Remove the dead SWAGGER_ENABLED line (or rename to API_DOCS_ENABLED=false, which v3.5.0 reads and defaults to false). No image: line moves. — app-catalog@917a779 templates/grimmory/docker-compose.yml:29 - SWAGGER_ENABLED=false still present. |
2 |
| R-799 | P4 | STILL-TRUE-SMALL | FIX: Add "download_type": "video" to the POST /add body. — app-catalog@917a779 scripts/upgrade_fixtures_box.py:2183 data=json.dumps({"url": self.URL, "quality": "best", "format": "any", "auto_start": True}), method="POST") - no download_type. |
2 |
| R-804 | P4 | NOT-WORTH-IT | PICK close-as-accepted: plant-it's image repository does not exist; the template is already abandoned and not installable, and no box runs it. | 2 |
| R-805 | P4 | STILL-TRUE-NOT-SMALL | app-catalog-felhom.eu scripts/check-volume-persistence.py:342 'if m["class"] == "named-declared" and m.get("files", 0) == 0:' — only named volumes judged empty; binds not. Last change 917a779 (R-788). The rule change itself is small, but it flips Grimmory/komga/paperless-ngx/radarr/sonarr to UNDETERMINED and needs a live re-sweep to regenerate the verdict tables; the row also asks for a decision. | 6 |
| R-806 | P4 | STILL-TRUE-SMALL | FIX: Make routed_ports return the traefik loadbalancer.server.scheme (reuse upgrade_boxport LB_SCHEME_RE) and have the GET exercise use that scheme with curl -k for https. The gramps-web :5000 non-answer stays a separate live look (narrow the row to it). — app-catalog-felhom.eu scripts/check-volume-persistence.py:586 'code = _sh(a + [f"http://{ip}:{port}{path}"], timeout=40)' — plain http always; | 6 |
| R-807 | P4 | STILL-TRUE-NOT-SMALL | Per-app upload seeds for 13 apps (claper, crafty-controller, dawarich, docmost, gramps-web, immich, outline, sparkyfitness, tandoor, vikunja, wger, wishlist, zipline) + plex/wanderer; each needs a live fixture run. Gate rule at scripts/check-volume-persistence.py:342 still makes empty declared volumes UNDETERMINED (917a779). | 3 |
| R-814 | P4 | UNCHECKED | Live Hetzner console state (box 611421 status); not visible in source. Operator action only. | 2 |
| R-815 | P4 | UNCHECKED | First GC completion on felhom-offsite is PBS server-side live state; grep of documentation found no GC completion record (DIAG-backup-missed-2026-07-26.md:43 'prune/GC history NOT COLLECTED'). | 3 |
| R-816 | P4 | STILL-TRUE-NOT-SMALL | Needs a live exercise of six failure classes on a scratch guest; no source change can close it. | 2 |
| R-817 | P4 | STILL-TRUE-SMALL | FIX: Add a dated correction under decision 56: the swap rolls back to the image running when the swap began (controllerswap.go Swap/rollback); the kept previous image is for a hand roll-back. Do not rewrite the ruling itself. — felhom.eu documentation/architecture/09-update-architecture.md:619 '56. A box keeps the controller image it runs and the one before it (the self-update's roll-back targ | 8 |
| R-818 | P4 | STILL-TRUE-SMALL | FIX: Add a dated correction note under the v0.109.0 entry (and the hub CHANGELOG mentions at :695/:701) naming the real closed rows from CLOSED-ITEMS.md. Also present in felhom-controller/CHANGELOG.md:3107 and :3234 (R-330/R-331 for v0.224.0/v0.225.0) — a second repo; either note it there too or narrow the row. — felhom.eu hub/CHANGELOG.md:759 '## v0.109.0 — the Backup card told every operator tha | 6 |
| R-819 | P4 | STILL-TRUE-SMALL | FIX: Let rule 3 accept an id found in CLOSED-ITEMS.md (and check the stand's status agrees), fix the R-273/R-356 dangling ids, register the gate in repo_gates.py with a decoy. — Ran python3 scripts/check_stands.py (read-only): still convicts e.g. 'fail.stolen-machine: register id R-281 is not in OPEN-ITEMS.md', 'fail.customer-self-restore: register id R-356 ...'. grep 'stands' in scripts/repo_gate | 6 |
| R-832 | P4 | STILL-TRUE-NOT-SMALL | Deferred roadmap item: a third-location copy of ep0 is money + operator decision (decision 71). Nothing in source to change. | 1 |
| R-844 | P4 | STILL-TRUE-NOT-SMALL | Needs a household timeline on the controller, which does not exist (row: 'when the box gets a household timeline'). A new surface, not a fix. | 2 |
| R-855 | P4 | STILL-TRUE-SMALL | FIX: Add a small helper (e.g. osSvc.DockerNightsEffective()) mapping negative→0 and 0→2, and print that in the start log. — felhom.eu hub/cmd/hub/main.go:450 'logger.Printf("[INFO] osupdates: the Docker engine set is approved only by the operator, after %d healthy ring-0 night(s)", osSvc.DockerNights)' prints the raw value; internal/osupdates/service.go:169 'negative means none'. | 4 |
| R-856 | P4 | STILL-TRUE-NOT-SMALL | Row is marked an operator design question (crash-restart suppression for app mails); not a defect yet. | 1 |
| R-857 | P4 | STILL-TRUE-SMALL | FIX: Have newest_baked accept an optional suffix after the date and, for equal versions, prefer the newest bake-log timestamp (or refuse two dirs for one version); add 're-vouch at once after a same-version re-bake' to the runbook. — felhom.eu scripts/golden_currency_gate.py:146 'EVIDENCE_RE = re.compile(r"^golden-(\d+).(\d+).(\d+)-\d{4}-\d{2}-\d{2}$")' and :237-238 'found.sort() / return found[ | 7 |
| R-878 | P4 | STILL-TRUE-NOT-SMALL | Next action is 'measure a large volume first' — a live measurement; the fix direction is a behaviour change to the catch-up. | 2 |
| R-881 | P4 | STILL-TRUE-SMALL | FIX: Add an rm -f of /usr/local/sbin/felhom-priv-apply to the uninstall step (tolerate-absent, like felhom-pbs-apply at :1161) and fix the :1679 comment; ships at the next installer tag. — felhom.eu scripts/felhom-host-install.sh: grep 'felhom-priv-apply' → no hit anywhere in the installer (uninstall does not remove it); :1679 '+ guest-hook snippet under /var/lib/vz/snippets/ (agent-installed at r | 4 |
| R-884 | P4 | UNCHECKED | Live ArgoCD diff on DooPlex (forbidden to touch here). Related: homelab-manifests mon-system/monitoring.yaml:399-426 is the same prometheus Deployment R-211 concerns. | 2 |
| R-885 | P4 | STILL-TRUE-SMALL | FIX: Finish and push the in-progress script_tests_gate.py (walks scripts/ for test_.py, exit-code verdict, nesting guard) registered in repo_gates.py; coordinate with the session that owns the dirty tree. — On main (b018ca90) scripts/repo_gates.py runs no test_.py suite. NOTE: the felhom.eu working tree holds UNCOMMITTED work for exactly this row by another session: '?? scripts/script_tests_gate |
6 |
| R-30 | P3 | STILL-TRUE-NOT-SMALL | Design change (presence from the Dir-2 long-poll instead of the report clock), size M; no commit with R-30 after aa9c08f0 (filing). |
3 |
| R-31 | P3 | STILL-TRUE-NOT-SMALL | felhom.eu hub/internal/web/configs.go:1594 'd, err := s.offsite.ProvisionOffsite(ctx, cfg.CustomerID, in)' still in-request; :1584 detaches from the request context (mid-cancel fixed) but no async/status card. | 5 |
| R-35 | P3 | STILL-TRUE-NOT-SMALL | felhom-controller controller/internal/report/config_refresh.go:65 'config-refresh: applied config_version=%d — self-restarting to load it'; sessions are in-memory only: controller/internal/web/auth.go:259-260 's.sessions[token] = &session{'. Hot-apply or persisted sessions is a design change with security weight. | 6 |
| R-49 | P3 | STILL-TRUE-NOT-SMALL | app-catalog-felhom.eu templates/immich/.felhom.yml:28-34 backup block has no cache/volume exclusion; row itself says a capture-set exclusion needs its own ruling (data-loss-shaped). | 4 |
| R-50b | P3 | FIXED-BY-LATER-WORK | Claim 'fetched via fetch_raw from raw/branch/main — no tag, no pin' no longer true: bee68484 (installer v1.23.0, R-110/R-183) pinned fetch_raw to the vouched agent tag — felhom.eu scripts/felhom-host-install.sh:533 '"$GITEA_BASE/$GITEA_OWNER/$AGENT_REPO/raw/tag/v$ART_AGENT_VER/$path" ' (leg b). Leg (c)-like signed delivery: felhom-agent c9fa2e7 (R-840 config bundle) and configs/test_felhom_config |
7 |
| R-78 | P3 | STILL-TRUE-NOT-SMALL | An owed operator decision + spike (local_api authority); not a code defect. | 1 |
| R-79 | P3 | STILL-TRUE-NOT-SMALL | felhom-controller controller/internal/monitor/healthcheck.go:100 'fmt.Sprintf("SSD disk usage critical: %.0f%%"', :213 'Protected container not running: %s'; rendered raw at controller/internal/web/alerts.go:241 'Message: issue, // ON THE WIRE ... not ours to translate; slice 3'. Whole-surface, seam needs a spike. | 5 |
| R-118 | P3 | STILL-TRUE-SMALL | FIX: Only statfs the mount when s.devicePresent(d.MountPath) is true (else leave capacity zero/unknown); put statfsCapacity behind a seam var for the test. — felhom-agent internal/localapi/disks.go:401 'if total, used, okc := statfsCapacity(d.MountPath); okc {' — no device-presence guard on the union path; devicePresent exists (disks.go:985) and is used just above (:381) for BoundUnderParent. | 6 |
| R-121 | P3 | FIXED-BY-LATER-WORK | 3d7a2761 (hub v0.135.0, R-530/R-604 'boxes left behind listed and alarmed'): felhom.eu hub/internal/osupdates/service.go:79 'EventAgentBehind = "agent_behind" // warning, operator' with :180 'AgentBehindAfter: a box runs an agent older than the vouched one this long → an operator alarm' (7 d window, the staleness window the row asked for). |
5 |
| R-126 | P3 | STILL-TRUE-SMALL | FIX: Skip IsNetwork() paths in the export-destination list and refuse them in isValidDrivePath for the export POST (keep scanning for import if wanted, via a separate list). — felhom-controller controller/internal/web/handler_export.go:377-386 storageDriveList() appends every s.settings.GetStoragePaths() entry with no IsNetwork() filter; the predicate exists at controller/internal/settings/setting | 6 |
| R-127 | P3 | STILL-TRUE-NOT-SMALL | Leg (a) still true: grep 'data_key: true' in app-catalog-felhom.eu templates → only adventurelog, dawarich, homebox, papra, sparkyfitness; n8n N8N_ENCRYPTION_KEY, wanderer POCKETBASE_ENCRYPTION_KEY, calcom CALENDSO_ENCRYPTION_KEY, bookstack APP_KEY unflagged (templates/n8n/.felhom.yml:38 etc.). Leg (b) (regenerated DB password vs restored PGDATA) needs a design choice. Leg (a) alone is a ~45-min c | 6 |
| R-130 | P3 | STILL-TRUE-SMALL | FIX: Take the cheap honest branch: rename to RECOMMENDED_MIN_LVM_GIB and reword the warning to 'below the recommended …' (making it refuse would change install behaviour and needs a ruling). — felhom.eu scripts/felhom-host-install.sh:348 'HARD_MIN_LVM_GIB=120 # a useful appliance won't fit below this on local-lvm' and :1760 '... // log_warn "local-lvm free ~${free_gib} GiB < hard min ${HARD_MIN_ | 4 |
| R-132 | P3 | UNCHECKED | Whether HUB_PW was rotated is out-of-band operator state; not visible in source. | 1 |
| R-136 | P3 | STILL-TRUE-SMALL | FIX: Introduce a const sessionCookieName = "__Host-hub_session" and use it at all five sites (Path=/, Secure, no Domain already hold). Every operator logs in once more; plain-HTTP browser access stops (Basic auth unaffected). — felhom.eu hub/internal/web/server.go:857 'Name: "hub_session",' and readers at server.go:806, :896, :918 and apps.go:351. | 4 |
| R-137 | P3 | STILL-TRUE-NOT-SMALL | felhom-controller controller/internal/cloudflare/waf.go:18 'globalRuleDesc = "[felhom-geo] Global"', :21 'appRuleDescPrefix = "[felhom-geo] app:"' — still not namespaced. Two-repo M change. | 3 |
| R-138 | P3 | STILL-TRUE-NOT-SMALL | felhom-controller controller/internal/infra/infra.go:157-159 writes CF_DNS_API_TOKEN when d.CFAPIToken != ""; no shared-zone guard in hub (grep shared.zone: none). Needs a policy decision first; no shared zone exists today. | 4 |
| R-179 | P3 | STILL-TRUE-SMALL | FIX: In uninstall step 4c, before the umount loop: stop+disable every mnt-felhom\x2ddrives-*.automount/.mount unit, rm their files from /etc/systemd/system, daemon-reload (tolerate-absent; still never umount -l/-f). — felhom.eu scripts/felhom-host-install.sh uninstall section :1121-1157 handles felhom-shared-parent and umounts under /mnt/felhom-drives, but grep 'x2ddrives/automount' → no hit: the | 6 |
| R-180 | P3 | STILL-TRUE-SMALL | FIX: In the same pre-flight block, die (byo) / die (appliance) if ARCHIVE_STORAGE is not in PVE_STORAGES, with a message naming --acl-storages. — felhom.eu scripts/felhom-host-install.sh:1800 'if pvesm status --storage "$ARCHIVE_STORAGE" ...' checks existence only; PVE_STORAGES=(local local-lvm felhom-pbs) at :322; no ARCHIVE_STORAGE ∈ PVE_STORAGES assertion. | 5 |
| R-190 | P3 | NOT-WORTH-IT | PICK close-as-accepted: A storage permission vanished once on demo-felhom in August and nobody knows why. Since agent 0.124.1 the agent puts it back by itself and mails the operator when it happens. | 4 |
| R-200 | P3 | FIXED-BY-LATER-WORK | The remaining half (customer-facing recovery-code form: yell → R form → preview) shipped as the recovery screen: felhom-controller 636c51e 'R-193: the recovery screen — unlocking, and only unlocking (v0.200.0)'; controller/internal/web/templates/recovery.html:82 '', routed at internal/web/server.go:602. Plumbing half | 8 |
| R-211 | P3 | STILL-TRUE-NOT-SMALL | homelab-manifests (/home/kisfenyo/git/homelab-manifests @87dfc29) mon-system/monitoring.yaml:420 'image: prom/prometheus:v3.15.0', :426 '--web.enable-lifecycle'; grep 'reload/checksum/config' → none. The manifest edit is small, but it rolls the production Prometheus on DooPlex (operator territory) and the same Deployment is OutOfSync per R-884 — do the two together. | 6 |
| R-231 | P3 | STILL-TRUE-NOT-SMALL | Owner operator; DooPlex /opt/backup/scripts remains host state. Partially touched by cea8502f (scripts/hub-db-backup versioned in felhom.eu, cites R-231) but that covers only the hub-DB push, not /opt/backup/scripts or the same-disk/no-off-site facts. |
4 |
| R-235 | P3 | FIXED-BY-LATER-WORK | felhom.eu c033b3b6 'ISO 1.28.0 source: the console stops showing the pairing code once bound (R-535)'. scripts/iso/felhom-bootstrap.sh:538: print_bound_banner # R-535: replace the pairing code on the console with the truth. Same defect already CLOSED twice in CLOSED-ITEMS.md as R-535 (line 232) and R-214 (line 200, 'proven on a fresh install'). |
4 |
| R-240 | P3 | STILL-TRUE-SMALL | FIX: Replace the producer string at offbox.go:1168 with wording that drops 'Sikeres' but keeps the lowercase marker substring, e.g. 'Ez a futás semmit nem mentett: nincs mentésre jelölt alkalmazás'; update the tests that pin the literal. — felhom-controller/controller/internal/backup/offbox.go:1168: warns = append(warns, "Sikeres — nincs mentésre jelölt alkalmazás"); web/handlers.go:1068-1069 re |
8 |
| R-242 | P3 | STILL-TRUE-NOT-SMALL | felhom.eu/scripts/golden_currency_gate.py:23-24: 'It does NOT check that the golden was VOUCHED, because the vouched version lives ONLY in the hub's hub_settings table'; :40 'That vouch half is STILL open after 2026-09-13'. Last gate commits 5ef0f52b/ae59c31a did not add a vouch check. |
5 |
| R-244 | P3 | STILL-TRUE-NOT-SMALL | felhom.eu/hub: no cascade leg touches app_log_issues — only writers are internal/store/telemetry.go:176-209 (upsert), :537 DELETE FROM app_log_issues WHERE last_seen < ?, :556/:575 operator deletes by app/id. cmd/hub/main.go:1004: if n, err := s.PruneStaleIssues(time.Now().Add(-30 * 24 * time.Hour)) (since a757bee0, hub v0.4.0). |
7 |
| R-250 | P3 | STILL-TRUE-NOT-SMALL | felhom.eu/hub/internal/offsite/offsite.go:71-72: var defaultScanBackoff = []time.Duration{2 * time.Second, 4 * time.Second, 8 * time.Second, 16 * time.Second, 30 * time.Second}; scanner.go:40 dials plain "tcp" (no A-record preference); no R-250 commit. |
7 |
| R-251 | P3 | STILL-TRUE-SMALL | FIX: In offsiteNewestPerTag skip the 'felhom-offbox' marker tag (move the constant into package backup and reuse it from web); consider whether '_shares' should render as a named row or be skipped. — felhom-controller/controller/internal/backup/offbox_inventory.go:102-108: loops for _, tag := range sn.Tags and adds every non-empty tag to newest — no filter for 'felhom-offbox'. The marker filte |
9 |
| R-255 | P3 | STILL-TRUE-NOT-SMALL | felhom-controller: still no page-wide runtime secret-sentinel test — grep -l sentinel internal/web/*_test.go hits only edge_safe_status_test.go, i18n_parity_test.go, recovery_test.go; controller/scripts/secret_in_markup_gate.py remains the only all-template net. No commit cites R-255. |
7 |
| R-257 | P3 | STILL-TRUE-SMALL | FIX: Rewrite flash.offbox.not_orphaned (hu + en) to say what the customer tried, that it does not apply now, and where to look, without 'offsite'/'elárvult', e.g. 'A távoli mentés rendben van, nincs mit félretenni. Ha gondod van vele, írj nekünk.'; wording sign-off from the operator (owner Viktor). — felhom-controller/controller/internal/i18n/locales/hu.json:1409: `"flash.offbox.not_orphaned": "Az | 5 |
| R-262 | P3 | STILL-TRUE-SMALL | FIX: One-repo fix: narrow the comment to say hostBackup is field-for-field and hostRestoreTest is a deliberate SUBSET (lists mount_parity/mount_inventory as not modelled), and add a hub test that names the two agent fields as known-unmodelled so a future addition must edit it. Adding the fields + fixture is a two-repo change (byte-identical golden) and stays a separate choice. — felhom.eu/hub/inte | 7 |
| R-269 | P3 | STILL-TRUE-SMALL | FIX: On a map hit, also stat the store and reload when its size differs from loadedSize before answering (one cheap stat per auth), so a rotated-out token is rejected without depending on an unrelated miss. — felhom-agent/internal/localapi/tokenstore.go:173-176: if vmid, ok := s.byHash[want]; ok { if subtle.ConstantTimeCompare(...) == 1 { return vmid, true } } — a superseded token's hash is stil |
6 |
| R-270 | P3 | STILL-TRUE-NOT-SMALL | felhom-controller/controller/internal/bootstrap/bootstrap.go:255: if cfg == nil // cfg.LocalAPI.Endpoint != "" { (fill-only, never refreshes); DetectEndpointDrift (bootstrap.go:369-399) compares only the endpoint. No R-270 commit. |
5 |
| R-271 | P3 | STILL-TRUE-NOT-SMALL | felhom-controller/controller/internal/channelhealth/checker.go:152: if prev != "" && prev != "up" { (unseeded->up is silent); checker.go:87 alert text still says '(re-bootstrap)'. No R-271 commit. |
4 |
| R-274 | P3 | FIXED-BY-LATER-WORK | felhom.eu eb600872 'R-297: installer compares a local golden against the manifest before using it'. scripts/felhom-host-install.sh:3074: if golden_local_matches_manifest "$GOLDEN_VOLID"; then (digest vs ART_GOLDEN_SHA, else baked marker vs ART_GOLDEN_VER; otherwise ignores the local golden and fetches, or dies if the operator named it, :3080). Line numbers differ from the triage note (2855-2905) |
5 |
| R-275 | P3 | STILL-TRUE-SMALL | FIX: Purge every sibling "${agent_cfg}".* (and then rmdir/rm the config dir) instead of .bak*; fix the WIPED line wording. — felhom.eu/scripts/felhom-host-install.sh:1059: for _cfgbak in "${agent_cfg}".bak*; do [[ -e "$_cfgbak" ]] && run rm -f "$_cfgbak"; done — glob still misses agent.json.campaign8-before, .campaign9-prev, .pre-e-target-move, .pre-prunegate.bak; :814 still claims 'config ( |
6 |
| R-276 | P3 | STILL-TRUE-SMALL | FIX: In run_uninstall (full scope): stop+disable wg-quick@wg-felhom and remove /etc/wireguard/wg-felhom.conf via run(); add it to WIPED, and add a KEPT line 'the hub-side WireGuard peer registration — remove it in the operator UI'. — felhom.eu/scripts/felhom-host-install.sh: no reference to wg-felhom/wg-quick anywhere (grep 'wg-quick/wg-felhom' empty); _uninstall_statement (:807-845) lists neithe | 6 |
| R-277 | P3 | STILL-TRUE-SMALL | FIX: For UsageStr use fmtBytesAuto when the usage is below 1 GB (keep GB for the quota and the bar), so a non-empty repo never renders as 0.0 GB. — Part (a) FIXED by felhom.eu f5c9411e 'R-331 (hub half): the Backup card reads offsite, not the dead backup fields (v0.109.0)' (hub/internal/web/backup_card.go uses fmtBytesAuto :135-142). Part (b) still true: hub/internal/web/offsite_box.go:54 `ret |
8 |
| R-282 | P3 | FIXED-BY-LATER-WORK | felhom.eu 4d6ec7c 'hub v0.104.0: ... the hub half of the naming (R-295)' + controller v0.211.0 (R-295 CLOSED, CLOSED-ITEMS.md:207) + R-323 hub v0.105.0. hub/internal/notify/templates.go:204: '// R-295, HUB HALF (2026-08-13). ONE NAME PER SECRET, and it is „Beállító kód".'; hub/internal/claim/engine.go:51 EmailReenroll EmailKind = "reenroll" (mail names the setup page a rebuilt box shows). |
5 |
| R-283 | P3 | STILL-TRUE-NOT-SMALL | felhom.eu/hub/internal/claim/engine.go:7: '// engine: a rotation bumps the generation (single active code) and NEVER clears claimed_at.'; ReissueForReenroll (engine.go:195-212) rotates and mails but leaves the claim set — the hub still shows the customer as claimed after a guest rebuild. No R-283 commit. | 5 |
| R-298 | P3 | UNCHECKED | The template gate is still there: felhom-controller/controller/internal/web/templates/storage.html:364 if(d.role==='user-data'){ else protected (:368). BUT the agent no longer reclassifies a backup-target drive: felhom-agent/internal/localapi/disks.go:1230-1236 ('WHY THIS IS NOT A ROLE RECLASSIFICATION ... the drive that now holds the whole-guest archives is ALSO the enrolled user-data drive') a |
10 |
| R-306 | P3 | STILL-TRUE-SMALL | FIX: Make _state_put (and _state_mark) return 0 when PREFLIGHT_ONLY is true, so a preflight-only run writes nothing; the real run's preflight records ownership again. — felhom.eu/scripts/felhom-host-install.sh:418: $DRY_RUN && return 0 (only DRY_RUN short-circuits _state_put); :1851/:1854 _state_put dnsmasq_preexisting yes/no run unguarded in preflight, while :226 says '--preflight-only: ... n |
6 |
| R-314 | P3 | STILL-TRUE-NOT-SMALL | felhom-controller: StopAbandon is called only from cmd/controller/main.go:244 (CLI) — grep -rn StopAbandon shows internal/backup/offbox_abandon.go:374 and that CLI call, no web handler. |
4 |
| R-317 | P3 | STILL-TRUE-SMALL | FIX: Probe the dnsmasq unit (e.g. /usr/lib/systemd/system/dnsmasq.service or /lib/systemd/system/dnsmasq.service) behind a small stat seam instead of /usr/sbin/dnsmasq. — felhom-agent/internal/lanresolver/lanresolver.go:107: if _, err := os.Stat("/usr/sbin/dnsmasq"); err != nil { // metadata read, no privilege needed — still probes the dnsmasq-base file. No R-317 commit. |
4 |
| R-330 | P3 | STILL-TRUE-NOT-SMALL | felhom-agent/internal/hub/report.go:406-425 SmartSummary carries reallocated/pending/offline_uncorrectable + NVMe set only — no 187/188/199 fields. Wire change across agent + hub (+ controller), declared M. | 3 |
| R-332 | P3 | STILL-TRUE-NOT-SMALL | Closing condition is live-only (a real degrading disk or an injection through agent /disks -> controller -> hub). Last related commits ea16a21b/2fa1efc narrowed the restart half only; no commit records a live Hiba-from-counters verdict. | 3 |
| R-333 | P3 | STILL-TRUE-NOT-SMALL | (b) felhom-agent/internal/storage/hostops.go:374: out, stderr, err := h.runner.Run(ctx, h.bins.Smartctl, "-a", "-j", device) — no -n standby. (a) still an operator decision (Viktor decides). |
5 |
| R-338 | P3 | UNCHECKED | felhom.eu/documentation/operations/nodes.md:86-88 now says demo-hp 'Agent config shape (R-50 island): local_api on 169.254.253.1:8443/vmbr9, guest eth1 169.254.253.2/30', and :84 records demo-hp was reprovisioned (address 192.168.0.87 -> 192.168.0.104, read 2026-09-21). Whether the reprovisioned box is actually on the island is a live-box fact (agent.json, pct config) not provable from source. | 5 |
| R-340 | P3 | STILL-TRUE-NOT-SMALL | felhom.eu/scripts/felhom-tenantsync.sh: no health op and no 8007 probe (grep '8007/health)' empty). Needs an ep0 (protected) script version bump + hub signal (M). | 3 |
| R-349 | P3 | STILL-TRUE-NOT-SMALL | felhom-agent/internal/hub/report.go:282-292 reports only WrapperSHA256; no agent binary sha field in the report (grep AgentSHA256 finds only the hub's manifest entry, hub/internal/api/handler.go:2726). R-349 commits 40d857b/910fd911 are the manual correction only. | 4 |
| R-350 | P3 | UNCHECKED | Whether the hub operator password was rotated after 2026-08-20 lives only in the hub DB / operator; git log shows no rotation record (only 910fd911 filing it). Not determinable from source. |
3 |
| R-362 | P3 | STILL-TRUE-SMALL | FIX: When MkdirAll/write of the restore destination fails with EACCES/ENOENT, check whether the destination's drive is disconnected/decommissioned or no longer a mountpoint, and return a Hungarian error naming the drive instead of the raw permission error. — felhom-controller/controller/internal/backup/offbox_restore.go:380, offbox.go:1929, shares_restore.go:116: `return fmt.Errorf("restore dir: % | 6 |
| R-363 | P3 | STILL-TRUE-SMALL | FIX: Replace sched.Daily("fill-watch", "03:30", …) with sched.Every("fill-watch", time.Hour, …) (scheduler.go:104), keep the startup check. — felhom-controller/controller/cmd/controller/main.go:1546: sched.Daily("fill-watch", "03:30", func(ctx context.Context) error { return fillWatcher.Check() }). Watcher emits on escalation only with a persisted band (internal/fillwatch/fillwatch.go:133, :231) |
6 |
| R-388 | P3 | STILL-TRUE-NOT-SMALL | Product direction, operator's call; recorded as [DESIGN — DIRECTION] in documentation/architecture/08-alarm-ladder.md §8 per the row. Nothing in source to fix. | 2 |
| R-401 | P3 | STILL-TRUE-NOT-SMALL | Event-triggered watch row: felhom-controller/controller/internal/backup/offbox_integrity.go:63 const integrityCheckTimeout = 30 * time.Minute, :78 var integritySlowNoticeThreshold = 5 * time.Minute — unchanged; the trigger (slow WARN on a large store) has not been recorded. |
3 |
| R-409 | P3 | STILL-TRUE-NOT-SMALL | felhom-controller/controller/internal/backup/recovery_unit.go:58 Checksums map[string]string json:"checksums" // sha256 of captured compose/ files; writers at :147, :152, :202 hash only compose/.felhom.yml/app.yaml — no db_dumps or volume_dumps hash. |
4 |
| R-412 | P3 | NOT-WORTH-IT | PICK close-as-accepted: A narrow race: if a recovery unit is destroyed inside an off-site run after its own dump leg, the push ships the just-rebuilt hollow unit; the next run repairs it and the WARN line now says it carried no data. | 4 |
| R-433 | P3 | STILL-TRUE-NOT-SMALL | Hetzner answered (ticket per the row): file-level snapshot access is a MAIN-account capability. hub/internal/hetznerapi/hetznerapi.go still has no snapshot read method (only size_snapshots usage, :83-87). The owed proof (read a file from a snapshot with the main account; forced-command append-only key) is a live, credential-bound operator act. | 4 |
| R-435 | P3 | STILL-TRUE-NOT-SMALL | felhom.eu/hub/internal/monitor/offsite.go:255: snapshotDropFraction = 0.5 // more than half the history gone in one step — no per-tag second signal exists. |
4 |
| R-440 | P3 | STILL-TRUE-NOT-SMALL | app-catalog-felhom.eu @917a779: 15 templates still have no update_ladder: in .felhom.yml — bentopdf code-server glance gokapi gramps-web homebox homepage jellyfin onlyoffice plant-it plex recipe-importer seerr vaultwarden wanderer (calibre-web got its first step in 53a4a1d). For these, pins float with no recorded digest. |
8 |
| R-444 | P3 | STILL-TRUE-NOT-SMALL | No fstrim anywhere in felhom-agent or felhom.eu/scripts (grep 'fstrim' over .go/.sh empty). Needs a new periodic host job (agent, privileged, sudoers/bundle) and possibly an operator surface. | 3 |
| R-446 | P3 | DUPLICATE | of R-440 — felhom-controller/controller/internal/stacks/updateorder.go:96: if len(s.CatalogDigests) == 0 // s.CatalogTestedAt.IsZero() { return false } — blind only for apps with no ladder entry, i.e. the same 15 templates R-440 lists (app-catalog has no update_ladder for them). Both rows close by the same act: each app's first proven ladder step (R-462). |
6 |
| R-450 | P3 | FIXED-BY-LATER-WORK | The row's only remainder was 'the other ten PostgreSQL apps need two-venue proof'. R-463 CLOSED 2026-09-30 by felhom.eu 25cb3eb9 ('The last six PostgreSQL apps decided'): 8 of 11 moved by the box's own conversion, 3 (zipline, adventurelog, immich) stay by decision 42; CLOSED-ITEMS.md:223. Source proof: app-catalog templates/docmost/docker-compose.yml:62 'image: postgres:18-alpine' (also rallly:67, |
8 |
| R-458 | P3 | NOT-WORTH-IT | PICK close-as-accepted: A frozen (pinned-behind) app can receive a newer health check from .felhom.yml. The only result is a false 'degraded'/dead-app alarm, never data loss, and only for type: api probes with an expect block. | 12 |
| R-462 | P3 | STILL-TRUE-NOT-SMALL | Ongoing multi-session work (fixtures and ladders per app). Last progress: catalog e6f3ec2 (2026-09-30), audits/more-night-apps-2026-09-30/. 21 apps still have no ladder (per the row). Not checkable as done from source. | 3 |
| R-468 | P3 | STILL-TRUE-NOT-SMALL | A standing pre-customer arrangement, not a defect. The mechanism is live: felhom.eu/scripts/golden_currency_gate.py:137 reads documentation/tests/golden-waiver.yml. The waiver file is currently ABSENT: deleted in felhom.eu 5efe6dae (2026-10-04, 'golden 0.292.0 vouched ... golden waiver deleted'). The row retires only at the first external install, so it stays as a watch. |
4 |
| R-469 | P3 | STILL-TRUE-SMALL | FIX: Reword the rule heading at CLAUDE.md:103 and the 'What is NOT lifted' paragraph (:112-114) to say that PostgreSQL crosses a major one app at a time with engine_conversion + both-venue proof (decision 35) and that MySQL stays refused. Then close R-469 citing R-463's closure. Do not delete the gate: it is now the per-app enforcement. — What stood between this row and its close was R-463, now CL | 8 |
| R-489 | P3 | FIXED-BY-LATER-WORK | The residual (a unit-restore-recreated volume has no compose label, so the remove answered []) was fixed in felhom-controller 206b035 (v0.268.0, R-658). controller/internal/stacks/delete.go:1089-1090: '// appVolumeSet is every volume the removal accounts for: the ones carrying the project label AND the // ones the app's definition declares that Docker holds by name (R-658, v0.268.0).' delete.go:70 | 5 |
| R-498 | P3 | STILL-TRUE-SMALL | FIX: When building the app info view, rewrite each first_steps entry: replace '.DOMAIN' with the stack's real address (installed SUBDOMAIN + customer domain when installed, else the template default subdomain + customer domain). Use the same approach as known_login.go:67. — Still literal: grep -l '.DOMAIN' over app-catalog templates/*/.felhom.yml -> 58 of 58; e.g. templates/bookstack/.felho | 8 |
| R-516 | P3 | STILL-TRUE-NOT-SMALL | By its own text it now waits for a Hungarian walk on a box with a second drive (items 4, 7, 8, 9, 10) and needs a separate row for item 11. That is live-box work, not source. No commit after 2026-09-20 names R-516 as closed. | 3 |
| R-521 | P3 | STILL-TRUE-NOT-SMALL | No storage-disconnect suppression of app_start_failed: controller/cmd/controller/main.go:2796 'down := (stacks.IsDownState(st.State) // crashLooping) && !userStopped && !quiesced[st.Name]' (only user-stop/quiesce suppress), and controller/internal/notify/notifier.go:718 emits app_start_failed per newly-down app. It also needs the hub cooldown semantics changed (per-key cooldown outliving storage_r | 6 |
| R-522 | P3 | STILL-TRUE-NOT-SMALL | No tunnel-connection signal in the controller: grep for TunnelConnected/cloudflared connection state in controller/internal -> none. The tile comes from container metadata: controller/internal/web/inframeta.go:21-22 '"cloudflared": { DisplayName: "Cloudflare Tunnel"'. Fixing it needs a new state source (cloudflared metrics or the hub-push result) wired into the tile, plus a live internet-cut valid | 5 |
| R-531 | P3 | STILL-TRUE-NOT-SMALL | Both measurements are done (audits/evidence-drill-0243-2026-09-16/). What remains is an operator design question about the crash-loop budget (a slow loop every 20 min is never paused). That is an operator decision, not code. | 2 |
| R-540 | P3 | STILL-TRUE-NOT-SMALL | Still a single pool box: felhom.eu/hub/cmd/hub/main.go:367 'poolBoxID, _ := strconv.ParseInt(os.Getenv("HETZNER_POOL_BOX_ID"), 10, 64)'. It needs a selection-rule design and eventually a second box (money). No risk today (0.3 % full per the row). | 3 |
| R-542 | P3 | UNCHECKED | The controller passes the agent's 'initialize' list through untouched: controller/internal/web/agent_disk_handlers.go:160-162 mergeAttachCandidates only appends to Attach. The agent puts every candidate under initialize: felhom-agent internal/localapi/disks.go:438 'initialize = append(initialize, c) // every unclaimed disk can be initialized'. Whether a REGISTERED in-guest drive still counts as 'u | 8 |
| R-545 | P3 | STILL-TRUE-NOT-SMALL | Still no un-configure route: controller/internal/web/server.go:744-783 lists /backup/offbox/{config,toggle,enable-all,offer-dismiss,run,reset,status,restore,place,reconstitute,verify-copy/delete,confirm-escrow,inject-password}; nothing removes a target. The fix is a new destructive customer action (shred data/offbox/) with a hub-escrow refusal check (R-241 rule), Hungarian/English copy and a UI. T | 4 |
| R-547 | P3 | STILL-TRUE-SMALL | FIX: Also schedule the fill-watch on an interval (e.g. sched.Every("fill-watch-fast", 15*time.Minute, ...) calling the same fillWatcher.Check) next to the daily run, and log the cadence. Alternative if the operator prefers: state in 08-alarm-ladder.md that a transient full disk is out of scope. — Still daily: controller/cmd/controller/main.go:1546 'sched.Daily("fill-watch", "03:30", func(ctx conte | 8 |
| R-548 | P3 | STILL-TRUE-NOT-SMALL | The row's original fix shape SHIPPED: felhom-agent 0722b2c (2026-09-24, R-685) checks before start, internal/backup/runner.go:279 '... so a new one needs about %s (old archives are removed only after a successful backup)'. Shown in the UI by controller 44ae4de (v0.272.0). The 2026-09-30 addendum is still true and is the open part: the local tier is refused for ever (10 refusals on demo-hp) because | 6 |
| R-552 | P3 | STILL-TRUE-SMALL | FIX: Add Manager.ClearInterruptedRestore(stack) (delete from opInterrupted + persistRestoreRecordLocked under m.mu). Call it in removeStack next to ClearUpdateHold, and log when it cleared something. — The interrupted-restore notice is cleared only at controller/internal/backup/opstatus.go:61 'delete(m.opInterrupted, stack)' inside BeginRestoreOp. removeStack (controller/internal/api/router.go:955 | 6 |
| R-554 | P3 | STILL-TRUE-NOT-SMALL | Still present: controller/internal/setup/ (setup.go, handlers.go, csrf.go, network.go, templates/), and controller/cmd/controller/main.go:328-330 'if setup.NeedsSetup(cfg) { ... runSetupMode(cfg, logger)'. The fix deletes a package and adds a new waiting page (HU+EN copy) with a red-proof. It also needs a check of drill/golden reliance on .needs-setup (controller/internal/web/handler_debug.go refe | 5 |
| R-562 | P3 | STILL-TRUE-NOT-SMALL | Needs an operator word on the Hungarian number/date format (the row says so) and a deliberate Hungarian-byte change release with parity re-capture. Not checked further. | 2 |
| R-565 | P3 | STILL-TRUE-SMALL | FIX: Add an ASCII Hungarian word regex to TestI18nEnglishPages (seeded from i18n_extract.py ASCII_HU plus the words releases B/C found: mp, db, FIGYELEM, jelenlegi, majd a(z), Konfig, Megtartva, helyi, Befejezve, automatikus, kedd/szerda/szombat, szint), applied after the data mask. — The English page test detects only accented letters: controller/internal/web/i18n_parity_test.go:563 'func huLette | 6 |
| R-573 | P3 | FIXED-BY-LATER-WORK | felhom-controller 7c4a33b (v0.258.0, 'the last four Hungarian things an English household met ... R-573 the two channel banners'). controller/internal/web/alerts.go:113 'func (am *AlertManager) SetAgentChannelAlert(down bool, msgKey, msg string) {' and :136 'func (am *AlertManager) SetEndpointDriftAlert(drift bool, msgKey, msg string) {'. Both set MessageKey with msg only as a fail-open fallback. | 4 |
| R-575 | P3 | STILL-TRUE-SMALL | FIX: Make memoryVerdict return (refusal error, warningKey string, warningArgs []any) instead of a msgHU string, and render the warning at the deploy answer with the request's language (the Alert/UpdateRefusal pattern). — Still a plain string: controller/internal/stacks/deploy.go:1456 'func (m *Manager) memoryVerdict(newReqMB, newLimitMB, releasedReqMB, releasedLimitMB int) (refusal error, warning | 5 |
| R-578 | P3 | STILL-TRUE-NOT-SMALL | The lock-reentrancy guard is still one test in one package: controller/internal/backup/offsite_diag_test.go:190 'TestNoteHelpersAreNotCalledUnderTheSettingsLock'. No other package has one, and there is no gate (grep for R-578 in controller -> none). The fix needs a cross-package AST gate that knows which methods read settings (or a re-entrant read path in Settings). That is a new mechanism, likely | 5 |
| R-581 | P3 | STILL-TRUE-SMALL | FIX: In GetCustomers, join on MAX(id) per customer_id instead of MAX(received_at), and add ', id DESC' to the ORDER BY at store.go:1393 and :1446. — Still no tie-break: felhom.eu/hub/internal/store/store.go:1329 'SELECT customer_id, MAX(received_at) as max_time' joined on 'r.received_at = latest.max_time' (:1333). A same-second tie returns BOTH rows (a duplicate customer in GetCustomers), not just | 6 |
| R-584 | P3 | NOT-WORTH-IT | PICK close-as-accepted: Helper scripts with the shared DEMO controller password inline were left in a demo guest's /tmp. The cleanup rule exists, but no mechanism enforces it. | 5 |
| R-585 | P3 | STILL-TRUE-NOT-SMALL | Still finished Hungarian from callers: controller/internal/notify/notifier.go:408 'n.PushEvent("backup_failed", "error", message, BackupDetails{Error: errMsg})', :487 offbox_enlarge_blocked, :497 db_dump_failed. None of the six types is in convertedProducers (controller/internal/notify/message_customer_test.go:39). The hub still has no customerMessages entry for offbox_enlarge_blocked (felhom.eu/h | 5 |
| R-586 | P3 | NOT-WORTH-IT | PICK close-as-accepted: The ISO bootstrap harness runs only at each ISO release gate (G16), not on every push. | 6 |
| R-587 | P3 | STILL-TRUE-SMALL | FIX: At the start of build-felhom-iso.sh, refuse (non-zero exit, named reason) when any *.rootpw.txt exists in the output dir. In the SKILL publish block, add a pre-check line that aborts the rclone copy if a *.rootpw.txt is present in the publish source. — The files are gone (ls /mnt/5_hdd/felhom.eu/felhom-iso/out / grep -c rootpw -> 0). The guard is still not built: the publish still relies on t | 6 |
| R-593 | P3 | STILL-TRUE-SMALL | FIX: Move 'Az alkalmazás aldomainje' to SUBDOMAIN, give AUTH_SECRET its own description (e.g. 'A munkamenetek aláírásához használt kulcs — ne generáld újra'), add the two English i18n.en descriptions, and re-capture papra's entries in copy_freeze/hu.json with the reason in the commit. — Still wrong: app-catalog-felhom.eu/templates/papra/.felhom.yml:47 ' description: "Az alkalmazás aldomainje"' | 5 |
| R-600 | P3 | STILL-TRUE-SMALL | FIX: Call the wgsync reconciler's Trigger() before the COMPLETE log line (nil-safe), and make the line say 'wg peer removal pushed' or 'queued for the next wgsync push' depending on whether a syncer is wired. — Log line unchanged: felhom.eu/hub/internal/web/customer_delete.go:310 's.logger.Printf("[INFO] customer DELETE cascade COMPLETE for %s (journal #%d) — full teardown", customerID, journalID) | 6 |
| R-607 | P3 | UNCHECKED | The row asks first for a live reproduction loop (push a tag, sync, read catalog_images on a timer) and has no diagnosis. Why the sync reports 'nincs változás' while the cache moved, and when CatalogImages refreshes, are live-box behaviour I could not settle from source in the time box. No commit after d19f07ea (filing) names R-607 as fixed. |
6 |
| R-612 | P3 | STILL-TRUE-NOT-SMALL | The memory half is fixed (catalog a5a729a, 'wishlist 512M (R-612)'). The open half, making a failed first-boot seed visible, needs a new detection mechanism (read the seed's exit/log, or a probe that checks the Role/Group rows). No commit addresses it. | 4 |
| R-613 | P3 | STILL-TRUE-NOT-SMALL | uptime-kuma is fixed (catalog a5a729a). The open half is a sweep of all 58 templates for probes that pass on a setup wizard. That needs per-app live inspection, so it is not small. No commit names it. | 3 |
| R-615 | P3 | STILL-TRUE-SMALL | FIX: Before the fetch, run 'git remote set-url origin <buildRepoURL()>' (or read origin and re-clone on mismatch), and log at INFO, masked, when the remote changed. The appended drill-folder residue (stack folders the live catalog lacks) is a separate drill-teardown item and is not part of this fix. — Still inert: controller/internal/sync/sync.go:279 clones only 'if _, err := os.Stat(gitDir); os.I | 7 |
| R-616 | P3 | STILL-TRUE-SMALL | FIX: Clone and fetch with the credential-free RepoURL, and supply credentials per command via '-c http.extraHeader=Authorization: Basic ' (or GIT_ASKPASS env) only when username+token are set. Pairs naturally with the R-615 set-url fix (set-url to the bare URL). — Still true: controller/internal/sync/sync.go:327-331 buildRepoURL injects 'https://%s:%s@' and the clone at :283-288 passes that U | 5 |
| R-622 | P3 | FIXED-BY-LATER-WORK | adventurelog v0.13.0 was diagnosed, fixed and promoted with a two-venue test record in app-catalog-felhom.eu 06ea7da (2026-09-27, 'adventurelog: v0.12.1 -> v0.13.0 with its health and world-data fixes in the same commit (R-655, 09 decision 41)'; bench healthy in 217 s, box 9202 through the guarded Update in 204 s). templates/adventurelog/docker-compose.yml:13 ' image: ghcr.io/seanmorley15/adven | 6 |
| R-635 | P3 | FIXED-BY-LATER-WORK | The open remainder (app_oom fires once per container run, no escalation) was built in felhom-controller 0054d4b (v0.265.0, 'OOM storm alarm', R-636). controller/internal/notify/notifier.go:746 '\t\tn.emit("app_oom_storm", "error",' fires once per run when 20 or more kills land in 30 min (:754-764, oomStormKills=20, oomStormWindowMin=30; pinned by TestR636_*). The 79 % headroom and the method lesso | 6 |
| R-645 | P3 | STILL-TRUE-NOT-SMALL | Still true for the operator CLI: controller/internal/settings/settings.go:1923-1929 ClearRestoreHold deletes ANY hold reason (including update-failed) with no pin restore, and the flag is in controller/cmd/controller/main.go:94/198. The row lists three candidate shapes with 'none chosen'. Picking one changes operator-path semantics and the capture logic, so it is not a one-hour fix. (The automatic | 6 |
| R-675 | P3 | STILL-TRUE-SMALL | FIX: In missingFileLegsRefusal, when the second drive holds a whole copy of the app (the decision-26 whole-copy check the backup manager already exposes for the restore page), name that whole restore action instead of 'Fájlok visszaállítása'. Keep the existing branch otherwise. — Unchanged: controller/internal/web/handlers.go:1745 'return head + "A fájlok a második meghajtó másolatából állíthatók | 5 |
| R-676 | P3 | STILL-TRUE-NOT-SMALL | A watch row, still true: controller/internal/stacks/unhealthy.go:116 skips only 'if st.Deploying // st.Updating // st.HoldReason != "" // st.updateHeld {', so a deploy's first start (after Deploying clears) is sampled by decision 28's crash-loop stop. The immich cause is fixed in the catalog (56c4888, 768M, per the row). Covering a slow first start would need a first-start grace decision. | 5 |
| R-682 | P3 | STILL-TRUE-NOT-SMALL | felhom-controller 7690c27 (v0.296.0): no remove journal in source — grep -rni 'remove.journal/removeJournal/remove_intent/interrupted remove' controller/.go returns nothing; git log --grep R-682 empty. Needs a new boot-time journal mechanism. | 3 |
| R-683 | P3 | UNCHECKED | Watch item about a power-cut drill outcome; behaviour only a live box shows; git log --grep R-683 empty in controller. | 1 |
| R-698 | P3 | NOT-WORTH-IT | PICK close-as-accepted (option a), operator to confirm: A backup records the image name/digest, not the image; restoring a version the maker deleted from the registry fails at the pull. | 2 |
| R-700 | P3 | FIXED-BY-LATER-WORK | felhom-controller 820e8ef (v0.276.0, R-697/R-700). controller/internal/stacks/migrate.go:789: 'm.logger.Printf("[INFO] [stacks] %s: data moved %s -> %s — app.yaml keeps its pin (%d service(s)) and records"' — persistDriveFlip (migrate.go:763) loads app.yaml and changes only HDD_PATH. Only a live proof on a two-drive box remains (row's own residue). | 3 |
| R-704 | P3 | FIXED-BY-LATER-WORK | felhom-controller 7cba0bf (v0.278.0). controller/internal/api/router.go:918 'func (r *Router) dropLeftoverHold(name, why string) {' calling r.sett.ClearUpdateHold(name); pinned by TestR704_AFreshInstallDropsALeftoverHold. Residue: live proof of the install-time drop only. | 2 |
| R-706 | P3 | FIXED-BY-LATER-WORK | felhom-controller 0c702f8 (v0.279.0). controller/internal/api/router.go:946 'if err := r.backupMgr.DeleteOffsiteRestoreCopy(name); err != nil {' inside removeVerificationCopy (R-706); pinned by TestR706_RemovalWithBackupsDeletesTheVerificationCopy. Residue: not seen live. | 2 |
| R-717 | P3 | STILL-TRUE-NOT-SMALL | app-catalog templates/opengist/.felhom.yml:42 and templates/wishlist/.felhom.yml:42 carry only signup_block; no after_setup/after_install in either .felhom.yml (grep empty). Fix needs per-app DB writes (opengist sqlite with app stopped) plus live proof. | 3 |
| R-723 | P3 | FIXED-BY-LATER-WORK | felhom.eu 80aeac71 (hub v0.126.0). hub/internal/monitor/staleness.go:174 '// R-723 (v0.126.0): a customer's NEW box is not a recovery.'; hub/internal/notify/dispatcher.go:540 '"suppressed", "first hour of a new box (R-723)", "operator"'. Residue: live proof at a real first install. |
2 |
| R-724 | P3 | STILL-TRUE-NOT-SMALL | Text parts fixed in controller 6be6c53 (v0.283.0). Remaining LAN/gateway read still goes only through the samba container: controller/internal/stacks/guestnet.go:47 'out, err := dockerexec.Command("docker", append([]string{"exec", sambaContainer}, args...)...).Output()' — the comment (guestnet.go:18) accepts that reads fail while sharing is off. Needs another read path (design). | 3 |
| R-728 | P3 | STILL-TRUE-SMALL | FIX: Add a per-customerID in-flight guard (sync.Map/mutex set) around the create handler from the duplicate check to the self-bind mint, so a second concurrent submit for the same ID gets the 'already exists' form; optionally disable the submit button on submit in the template. — No commit fixes R-728 (git log --grep in felhom.eu only the filing commit 11591f3a). hub/internal/web/configs.go:705 'e |
5 |
| R-729 | P3 | STILL-TRUE-NOT-SMALL | No route clears the off-site target: controller/internal/web/server.go:744-783 lists /backup/offbox/{config,toggle,enable-all,offer-dismiss,run,reset,status,restore,place,reconstitute,verify-copy/delete,confirm-escrow,inject-password}; /reset (offbox_handlers.go:311) only resets an orphaned repo. New press needs handler + settings clear + template + HU/EN copy + escrow/hub-managed-target interplay | 4 |
| R-733 | P3 | STILL-TRUE-NOT-SMALL | Harness/golden-evidence change plus a decision whether proofs run with swap off; no commit references R-733. Not a source-verifiable single fix. | 1 |
| R-738 | P3 | NOT-WORTH-IT | PICK close-as-accepted (wger defect fixed; the generic gap is a design note): The guarded Update's health check sees only an app's front page, so an app that serves its front page while its data is broken passes as done. | 3 |
| R-747 | P3 | STILL-TRUE-NOT-SMALL | Lockout shortened: app-catalog a4597cd; templates/mealie/docker-compose.yml:27 ' - SECURITY_USER_LOCKOUT_TIME=1'. Residue still open: hourly lock renewal by a stranger (needs decision 57 option d) and page copy; needs decision + live proof. | 2 |
| R-755 | P3 | DUPLICATE | of R-762 — Still true: templates/wger/docker-compose.yml has no WGER_USE_GUNICORN (grep empty). R-762 (open, read) states 'Owner decides together with R-755 (same server question)' and its fix names 'the gunicorn switch of R-755'. | 2 |
| R-756 | P3 | UNCHECKED | Depends on whether 9202's scratch drive is a registered drive — live box state; the row itself says not measured which. Not verifiable from source. | 1 |
| R-757 | P3 | STILL-TRUE-NOT-SMALL | No commit references R-757. controller/internal/stacks/deploy.go:1339-1349: 'case "secret":' ... 'value, err := generateValue(field.Generate)' ... 'appCfg.Env[field.EnvVar] = value' for any missing field of a deployed app, with no exception for fields consumed only by after_install. Fix needs a design (a marker for given-at-install fields or an ask path). | 3 |
| R-758 | P3 | STILL-TRUE-NOT-SMALL | Still true: templates/bookstack/.felhom.yml:18 ' mem_limit: "512M"' vs compose limits docker-compose.yml:42 '512M' + :79 '256M'; onboarding/EXISTING-APPS-GAPS.md:26 still lists all 8. No gate (only scripts/onboarding_gaps.py:171 reports it). Not small: raising 8 figures changes the capacity check (decision 22) — which apps fit a box — plus a gate with decoy and a publish. | 4 |
| R-762 | P3 | STILL-TRUE-NOT-SMALL | templates/wger/docker-compose.yml sets no DJANGO_DEBUG and no static/media server (grep empty); templates/wger/.felhom.yml:18 'lifecycle: hidden' (catalog 55b8c8a). Needs a server design decision (nginx sidecar vs gunicorn+static) and bench+box proof. | 2 |
| R-763 | P3 | STILL-TRUE-NOT-SMALL | templates/wger/docker-compose.yml sets neither ALLOW_REGISTRATION nor ALLOW_GUEST_USERS (grep empty); wger hidden (.felhom.yml:18 'lifecycle: hidden'). The env change is tiny but its proof needs a working wger on 9202 (blocked by R-762); best done in the same session as R-762. | 2 |
| R-774 | P3 | STILL-TRUE-NOT-SMALL | templates/karakeep has no Sentry/phone-app sentence (grep -i sentry empty); mail-ON proof needs a hub-enabled live box (demo-hp) — live work. | 2 |
| R-775 | P3 | STILL-TRUE-NOT-SMALL | Narrowed (Grimmory published behind the family gate). Residue: per-name 15-min lock is hard-coded upstream (no setting) and the reinstall-over-kept-books finding is uninvestigated — needs live investigation. | 2 |
| R-776 | P3 | STILL-TRUE-NOT-SMALL | Only bookstack has it: templates/bookstack/docker-compose.yml:32 ' - APP_PROXIES=172.16.0.0/12'; grep for TRUSTED_PROXIES/CORE_TRUST_PROXY/IPEXTRACTION/N8N_PROXY_HOPS in kimai, zipline, vikunja, nextcloud, n8n compose returns nothing. Five apps, each needing a live 3.6 re-measure on 9202. | 3 |
| R-778 | P3 | NOT-WORTH-IT | PICK close-as-accepted: If a box rolls back to a controller older than 0.286, the dashboard's login counter trusts the leftmost forwarded address and can be dodged until the box moves forward. | 2 |
| R-782 | P3 | STILL-TRUE-NOT-SMALL | Source agrees: templates/glance/docker-compose.yml:27 seeds glance.yml with no auth: block (grep 'auth' in templates/glance empty); templates/homepage has no HOMEPAGE_ALLOWED_HOSTS (grep empty). Needs live measurement on 9202 and a decision whether a public glance dashboard is intended. | 3 |
| R-783 | P3 | NOT-WORTH-IT | PICK close-as-accepted (re-open if upstream exposes the setting): Three wrong SparkyFitness sign-ins by anyone block every visitor's sign-in for about 10 seconds. | 2 |
| R-785 | P3 | STILL-TRUE-NOT-SMALL | templates/sparkyfitness/docker-compose.yml:45 ' image: codewithcj/sparkyfitness_server:v0.17.3' and :89 'codewithcj/sparkyfitness:v0.17.3'. Major-version ladder walk (bench + box), gated on R-784. | 1 |
| R-831 | P3 | NOT-WORTH-IT | PICK keep (rotation is the operator's call; do not close a leaked-secret row silently): The Hetzner storage API token was printed into one session transcript. | 1 |
| R-836 | P3 | STILL-TRUE-NOT-SMALL | Live host boot-loader work needing operator-approved reboots and measurement (GRUB env block on ESP, sp5100_tco arming). | 1 |
| R-839 | P3 | STILL-TRUE-NOT-SMALL | Gate behaves as described: controller/cmd/controller/main.go:2397 'return false, "drive " + hdd + " is not a live mountpoint"' with hdd = cfg.Env["HDD_PATH"] (main.go:2379). Which writer put a per-app path in HDD_PATH is undiagnosed — a diagnosis task, not a one-hour fix. | 4 |
| R-853 | P3 | NOT-WORTH-IT | PICK close-as-accepted: After a boot the box's versions and crash facts reach the hub up to about 15 minutes late. | 4 |
| R-862 | P3 | UNCHECKED | Waiting on the operator's by-hand bootstrap on Tester 2 through his tunnel; whether done is live-box state. No commit records it (felhom.eu log since 2026-10-04). | 1 |
| R-870 | P3 | NOT-WORTH-IT | PICK keep (operator's call; close when Tester 1 is retired): Tester 1's two Cloudflare tokens (disposable test customer) were printed into one session transcript. | 1 |
| R-879 | P3 | STILL-TRUE-NOT-SMALL | hub/internal/store/store.go:166 'retrieval_password TEXT NOT NULL,' and store.go:1586/1592 write retrieval_password and api_key as given; no seal on them (grep seal near these fields empty). Sealing/hashing three tables with migration is a security change, more than an hour. | 3 |
| R-882 | P3 | UNCHECKED | Longhorn instance-manager state on DooPlex (Tier 2, forbidden to touch); live-only, owner operator. | 1 |
| R-883 | P3 | UNCHECKED | homelab-manifests repo is not in this workspace (ls /mnt/5_hdd/felhom.eu/git shows only app-catalog-felhom.eu, drills, felhom-agent, felhom-controller, felhom.eu); live DooPlex check (kubectl) is out of scope. | 1 |
| R-886 | P3 | UNCHECKED | DooPlex Alertmanager volume ownership; homelab-manifests not in this workspace and live check not permitted. | 1 |