# REPORT — v0.95.0: SMART coverage (spike fixes B+A) + device model (2026-07-25) **Overwritten** per the standing rule. Part of the SMART-coverage task (agent v0.95.0 + controller v0.171.0); the R-50 island-bridge spike lives in felhom.eu. ## Baseline → target felhom-agent `643899c` (v0.94.0) → committed **`ed97232`** (v0.95.0). Deployed to felhom-pve. ## What shipped (additive; MinAgent unchanged; hub untouched) Implements `SPIKE-smart-coverage-2026-07-25.md` (both demo disks answer `smartctl -a -j` PASSED, but the agent never asked): - **Fix B — union-path SMART:** `storage.SmartReader.SMARTForBacking` (reuses `smartDeviceFor`) wired into the `/disks` union path via a localapi `Smart` seam (+ a `resolveStorageDevice` seam for testability). Registry/USB drives now get a real read. The watchdog `Known` path stays enrich-free (asserted: zero smartctl calls). - **Fix A — LVM/dm resolution:** `smartDeviceFor` resolves `/dev/dm-N` / `/dev/mapper/X` to the single backing whole disk via `/sys/block//slaves` (recursive; **skips** on >1 physical disk). The builtin `local` dir on the LVM root gets a **SMART-only** device from its containing filesystem (`containingMountDevice`), gated to `catDir && backing=="" && reachable` — never touching `backing_device`/`durable_id` (the removable-safety guard stays intact). - **Model:** `SmartSummary.ModelName` captured from smartctl's `model_name`. - Fix C (`-d sat`) stays rejected — no sudoers/manifest change. ## Files `internal/hub/report.go` (ModelName), `internal/storage/smart.go` (parse model), `internal/storage/smartdev.go` (NEW: dm resolution + SmartReader + containingMountDevice), `internal/storage/observe.go` (smartDeviceFor dm branch, enrich smartHint, build hint), `internal/localapi/{server.go,disks.go}` (Smart seam + union read + resolve seam), `cmd/felhom-agent/main.go` (wire), CHANGELOG/CONTEXT/REUSE. New tests: `smartdev_test.go`, `observe_smart_test.go`, union-path test in `disks_smart_test.go`. ## Tests + red-proofs (all recorded) `go build/vet/test ./...` — **29 packages pass, 0 fail.** Red-proofs verified then restored: - dm multi-disk guard (`len(disks)!=1`) → mirror-over-two-disks resolves instead of skipping → FAIL. - enrich `smartHint` fallback → system disk stays UNKNOWN → FAIL. - Fix-B union routing removed → union drive carries no SMART → FAIL. - Known-path-never-SMARTs asserted (zero calls; the "route Known through enrich" mutation would break it). ## Deploy + LIVE acceptance (felhom-pve — REAL N100 hardware, not virtualized) Built `0.95.0` (ldflags), backed up `.bak-0.94.0`, installed, restarted → **active, 68/68 capabilities, listening**. `/disks` payload now carries real SMART + model for BOTH physical disks: - `local` (system SSD): `backing=''` yet **smart=PASSED, model="AirDisk 512GB SSD"** — Fix A resolved `/`→`pve-root`(LVM)→`sda`. - `47a3361a` (USB): `backing=/dev/sdb`, **smart=PASSED, model="TOSHIBA MQ04ABF100"** — Fix B. - `felhom-pbs`/`local-lvm`: UNKNOWN (logical; correctly excluded by the controller). The controller v0.171.0 card on 9201 shows both with **real verdicts + human labels**: **"AirDisk 512GB SSD" → Rendben (34°C)** and **"TOSHIBA MQ04ABF100" → Rendben (30°C)** — the operator's "Nincs adat on a raw UUID" complaint is reversed. (A live FAILING/Figyelmeztetés verdict still needs a genuinely degrading disk — unit+red-proof covered.) ## Observations - The earlier assumption that demo-felhom is "virtualized (no real SMART)" was WRONG — it is a real N100 (SATA SSD `sda` + USB HDD `sdb`); the capability-map row is corrected accordingly.