# REPORT — raw-drive first-class support (agent v0.55.0 → v0.58.0)

**Date:** 2026-07-01 · **Repo:** `felhom-agent` · **Class:** Risky/supervised (drive health/enroll path).

Surfaced by the first live raw-drive enrollment (controller Impl-2b): the agent's enroll + tracking
machinery assumed every drive is a PVE storage (visible in `Observe()`). A raw (non-PVE-storage) drive
enrolled via the new wizard was therefore mounted+bound but not intent-tracked, not health-tracked, and
shown "disconnected". This slice makes raw drives first-class end-to-end.

## 1. Baseline → target

felhom-agent `91f6a26` (v0.55.0, Impl-2a) → **v0.58.0**. Companion: controller v0.95.0 (Impl-2b).

## 2. Changes (all `internal/localapi/disks.go` + wiring), newest first

- **v0.58.0** — the `/disks` registry-union row (Impl-2a) now reports `GuestPath` (`StablePathForRaw`) +
  `BoundUnderParent` (`boundUnderParent`), like the Observe path — a registry-only drive read as
  "Leválasztva" despite being bound live. Commit `3825664`.
- **v0.57.0** — `ReassertGuestBinds` builds its durable-id→mount map from `Observe()` only → a raw drive's
  guest-bind was never re-asserted (post-reboot/re-mount). Augment from the mount table (raw `/mnt/<name>`
  → device fs-UUID via `HostReader`, skipping the `/mnt/felhom-drives` bind); Observe failure no longer
  aborts. **Plus a latent wiring fix:** `buildLocalAPIServer` never passed `Options.HostReader`, so
  `s.host` was nil in production — the v0.56.0 fallback + the role gate's host classification silently
  no-op'd; now wired to `NewProcHostReader()`. Commits `67e2144` + `6448b80`.
- **v0.56.0** — `durableIDForMount` was `Observe()`-only, so a raw drive's enroll/eject **intent** +
  **guest-bind** went unrecorded ("durable-id unresolved"). Fall back to resolving the mount's device
  fs-UUID (`HostReader.Mounts`+`ResolveUUID`) → `uuid:<fs-uuid>` (same scheme as Observe). Commit `e593fb2`.

## 3. Green gate + tests

`go build ./...`, `go vet ./...`, `go test ./...` — clean at each version. New tests:
`TestDurableIDForMount_RawFallback` (+ red-proof: Observe-only → ""). The `ReassertGuestBinds` +
`/disks`-row changes are covered by the live end-to-end (§5).

## 4. Published + deployed

Gitea `felhom-agent/0.58.0` (sha `5ea7f63bb1617fa8412c1977b57369cd184bc1d6c1e6d6cf4f723835ebc06078`);
deployed to felhom-pve (backup `.bak-0.57.0`), active. (0.56/0.57 also published; rollback binaries kept.)

## 5. Live validation (felhom-pve + the real controller UI)

The raw `/dev/sdd` SD card, enrolled via the wizard (controller Impl-2b), ends up fully first-class:

| Property | Evidence |
|----------|----------|
| Mounted + bound | `/mnt/teszt_enroll` (raw) + `/mnt/felhom-drives/teszt_enroll` (bind) live. |
| Intent recorded | `drive-intents.json` → `uuid:f2236136… = enrolled`; journal `drive intent recorded … durable_id=uuid:f2236136…` (no "unresolved" — the v0.56.0 fallback fired once HostReader was wired). |
| Guest-bind recorded | `guest-binds.json` → `9201: […, uuid:f2236136…]`; journal `guest-bind recorded`. |
| Health-tracked | watchdog (RegistryKnownTargets) detected a drop + self-healed (re-mounted). |
| `/disks` status | row reports `state=attached`, `guest_path=/mnt/felhom-drives/teszt_enroll`, `bound_under_parent=true`. |
| Controller UI | shows **"Aktív"** (USB), alongside felhom-usb + felhom-flash — all Active, no false detach. |

## 6. NOT done / follow-ups

- The raw drive's `.mount` unit is named by its UUID (assign sets `MountSpec.Name = uuid`), so the
  agent-view Name is the UUID; the controller shows its own label ("teszt_enroll"). Cosmetic.
- Init slow-format completion is a controller concern (`runStorageInit` should poll
  `/disks/format/status`) — see controller REPORT.
- **Impl-3** — shared-box operator gate for self-serve format.

## 7. Observations

- Root theme: making a drive first-class without a PVE storage touches every seam that keyed off
  `Observe()` — candidates (Impl-2a), watchdog Known (Impl-2a), UUID resolution, intent + guest-bind
  recording, guest-bind re-assert, and the `/disks` status row. All now resolve raw mounts via
  `HostReader` (mount table + by-uuid), consistent with the `uuid:<fs-uuid>` scheme Observe derives.
