# REPORT — controller v0.72.0: FileBrowser converges on boot-recreate (2026-06-16) **Deployed:** controller **v0.72.0** on guest 9201 / felhom-pve (bootstrap-managed; healthy). **Commit (trunk):** `6ea2538` (Task B) + `c8d…`-era REPORT update. **Live-accepted:** two REAL host reboots of felhom-pve — FileBrowser re-synced after the drive-backed apps were recreated, both times; all drive-backed apps recovered with zero manual intervention. ## Task B — the gap Follow-up to v0.71.0's guest-reboot recovery. A host-reboot test found `processGuestBootChange` recreated the drive-backed app stacks (so their `${HDD_PATH}` binds re-resolved against the now-live drives) but **never re-synced FileBrowser**. FileBrowser is base-infra: it binds each drive's `userdata` directory but has no `HDD_PATH`, so it is **not** in the boot-recreate set — its mounts went stale after a reboot (the early first-boot bring-up bound them before the drives were live). ## Fix In `processGuestBootChange` (`internal/web/intermediary.go`), **after** `pollLiveBinds` confirms the live binds and the drive-backed apps are recreated, the boot-recreate path now triggers `go s.SyncFileBrowserMounts()` so FileBrowser converges against the now-live drives. The recreate loop was refactored into a pure, seam-testable helper: ```go func recreateDriveBackedApps(stacks []bootStack, presentStable map[string]bool, recreate func(bootStack), syncFB func()) (recreated, skipped int) ``` `syncFB` is invoked exactly once, AFTER all recreates — the FileBrowser sync can never run before the drive-backed apps are back. ## Tests (non-hollow, seam = the FB sync) - `TestRecreateDriveBackedApps_SyncsFileBrowserAfterRecreate` — records the call sequence; asserts `syncFB` runs exactly once and strictly AFTER every `recreate`. Red-proofed (stubbing out the `syncFB()` call makes it fail). - `TestRecreateDriveBackedApps_SyncsEvenWithNoRecreate` — FileBrowser still converges when nothing needed recreating (e.g. binds already present). `go build`, `go vet`, `go test ./...` all green on the build server (192.168.0.180). ## Live acceptance — real host reboot ×2 on felhom-pve Both reboots: `processGuestBootChange` fired on the new boot-id, confirmed the live binds, recreated every drive-backed app, **then** ran the FileBrowser sync. Captured controller logs: ``` [gate] boot 1781625729-1612: live bind confirmed — recreating drive-backed app … onto /mnt/felhom-drives/felhom-flash (×8 apps) [gate] boot 1781625729-1612: re-syncing FileBrowser mounts against the live binds [web] FileBrowser mounts synced — 3 storage path(s), config updated ``` (reboot #2 identical on boot-id `1781625955-1516`.) Post-reboot FileBrowser binds all three drives non-stale — `felhom-usb`, `felhom-flash`, `felhom-data` → `/srv/felhom-*` — and the underlying agent tolerated a `/dev/sdb`↔`/dev/sdc` reshuffle by mounting each drive by UUID (agent v0.37.0, Task A). The earlier first-boot `Failed to recreate FileBrowser` line (drives not yet live) is the exact pre-fix symptom; the boot-recreate path now recovers it. Demo dashboard has no password set → controller API is open on the in-guest path; no secrets committed.