Files
felhom-controller/REPORT.md
T
admin 4d349d1106
gates / gates (push) Successful in 10s
REPORT + CONTEXT for v0.203.0: the retry shape, the marker answer, R-220's shape
Records the decisions rather than only the code:
- POLL not ACK, decided on Scenario B against the ACTUAL promises — the
  no-target message gives no deadline and the card says 'within a day', so a
  5-minute tick is inside both and no text needed changing. If either promise
  tightens to minutes, go ACK-driven.
- The marker question: applied_marker lives in the guest's DataDir, which a
  rebuild destroys, so it cannot suppress a legitimate re-run. Left alone.
- R-220 candidate (b), corroborated rather than a wider prefix, reading
  /proc/mounts because the lsblk args are pinned in sudoers.

Live: Scenario C proven on demo-hp WITH a positive control — the job ran once
and logged nothing. A first reading counted 2 lines that turned out to be the
start-up reconcile, not the retry; the instrument was corrected before the
conclusion. Scenarios A and E are deliberately NOT live-proven here: both need a
rebuilt box, and that state arises naturally in Part 4.
2026-08-06 13:05:30 +02:00

5.9 KiB

REPORT — felhom-controller v0.203.0 (+ felhom-agent v0.127.0)

The two dead ends that kept the recovery journey failing are closed in code. R-218's consume half and R-220 (both halves: the host-side detection and the customer-facing refusal).

1. R-218 — which retry shape, and why (§7.1)

Poll, on a 5-minute scheduler tick, driven from the box's own published declaration (OffboxReportStatus().State) — the very statement the hub acts on, so the two cannot disagree about whether a retry is wanted.

Decided on Scenario B, measured against the actual promises:

surface what it promises
the no-target unlock message „…amint megvannak, a mentéseid listája megjelenik…" — no deadline
the backups card „…Ha egy napon belül nem áll be, jelezd az üzemeltetőnek." — within a day

A 5-minute tick is inside both by a wide margin, and it needs no hub change (which §0 expected). No text needed changing. If either promise ever tightens to minutes, the ACK-driven shape is the one to reach for.

It stops by construction (Scenario C) and the settle gate is kept (Scenario D) — the retry goes through ReconcileWhenSettled, unchanged.

2. The marker question (§7.2) — answered, and left alone

applied_marker lives at <DataDir>/offbox/applied_markerinside the guest's data dir, which a rebuild destroys. It therefore cannot suppress a legitimate post-rebuild re-run, and it is not part of this defect. Untouched.

3. R-220's shape (§7.3) — corroboration, not a wider prefix

Candidate (b), the claimed check distinguishing our own mount from a foreign one — because the host and its knowledge survive the rebuild while the guest's registry does not. Candidate (a) (a cleanup that clears the raw mounts) would have made correctness depend on a step running, and a step that does not run leaves exactly today's defect.

The discriminator is corroborated: a non-managed mountpoint is forgiven only when the same device is ALSO mounted under /mnt/felhom-drives — a pairing only our enrolment produces. /proc/mounts, not lsblk MOUNTPOINTS, because the lsblk invocation is pinned verbatim in the sudoers file and changing it would have coupled this fix to a config rollout.

The fence holds and has its own test (Scenario F): /srv/data, /media/photos, /mnt/someone-elses-disk, /var/lib/other are all still refused. Fail-safe: an unreadable mount table corroborates nothing.

4. Every changed Hungarian string

The deploy refusal (R-220, Scenario G). Was:

„A megadott tárhely nem azonosítható regisztrált meghajtóként, ezért alkalmazás adatkönyvtáraként nem használható. Válasszon a listából csatlakoztatott meghajtót."

Now:

„A megadott tárhely nem azonosítható regisztrált meghajtóként, ezért alkalmazás adatkönyvtáraként nem használható. Ha a gépet nemrég telepítettük újra, a meghajtóid megvannak, de még nincsenek újra csatlakoztatva ehhez a géphez — a Tárhely → Meghajtók oldalon csatlakoztathatod őket, és utána indítsd újra a telepítést. Ha ott sem látszanak, keresd a Felhom ügyfélszolgálatát."

No other customer-facing string changed. The NAS refusal is a different situation and is untouched.

5. Tests and red-proofs — every one demonstrated failing, then restored

Scenario Test Red-proof mutation Result
A a credential staged after start-up is collected make RetryIfDeclared return (false, nil) — the pre-v0.203.0 world FAILS: "the box declared a need and no reconcile was attempted"
C a healthy box does nothing, and logs nothing drop the !declared() stop condition FAILS: a healthy box reconciles
D the settle gate holds on the retry path call Reconcile instead of ReconcileWhenSettled FAILS: "SETTLE GATE BYPASSED"
E the customer's own drive is offered after a rebuild remove the felhomOwnedMounts exemption FAILS: "device is mounted at /mnt/adatok (sdb)"
F a genuinely foreign mount is still refused over-widen to any /mnt/* path FAILS: "/mnt/someone-elses-disk was offered for formatting"
G an empty list explains itself restore the old sentence FAILS: "the refusal tells the customer to choose from a list that may be empty"

Plus: a nil bridge is a silent no-op; the corroboration requires both mounts of the same device, and another device's managed mount does not vouch for a foreign one.

Green: controller 28 packages ok, agent 29 packages ok, both go vet clean, all gates OK in both repos.

6. Live checks (§7.4)

Deployed to demo-hp from the published bytes (agent sha verified against the artifact before installing): agent 0.127.0, controller 0.203.0, healthy.

Scenario C — PROVEN LIVE, with a positive control. The retry job is registered (Registered periodic job: offsite-credential-retry (every 5m0s)), ran once (Running job: offsite-credential-retry = 1) and produced zero log lines on a box whose tier is configured. The positive control matters: without it, silence could have meant the job never fired. (A first reading counted 2 lines and looked like noise; they were the START-UP reconcile's settle-gate lines, not the retry job — the instrument was corrected before the conclusion.)

Scenarios A and E are NOT live-proven yet, and deliberately so. Both need a rebuilt box: A needs one declaring needs_credential (no target), E needs one whose registry lost its drives while the raw mounts survived. Contriving either on a demo box means dismantling its real off-site state; the state arises naturally in Part 4, which is where they belong and where the last re-walk measured them.

7. Not changed

No hub change. No sudoers, no allowlisted command, no PVE surface. The settle gate, the marker, every other claim signal, and the NAS refusal are untouched.