# REPORT — Impl-1: format-safety foundation (agent v0.54.0) **Date:** 2026-07-01 · **Repo:** `felhom-agent` · **Class:** Risky/supervised (destructive `Format`/mkfs path + sudoers). Built/tested/deployed normally; live validation proves the guard REFUSES dangerous targets (safe) and formats only the throwaway `/dev/sdd`. Impl-1 of the drive-enrollment series (SPIKE-drive-enrollment-2026-07-01), built BEFORE the enrollment feature to harden the existing format path. ## 1. Baseline → target felhom-agent `7639ab5` (v0.53.0) → **v0.54.0**. ## 2. Root cause + files changed `Format` delegated authorization to its caller and only checked `DataBearing` (has-data) — insufficient: the OS disk is data-bearing yet catastrophic; and the sudoers permitted `mkfs.* /dev/*`. - `internal/storage/claim.go` (new) — the **unclaimed-disk filter**: `classifyClaim` (pure) + `gatherClaimFacts` (SystemDisks + lsblk member-FSTYPE + foreign-mount + RO + authoritative pvs/zpool; fail-safe → CLAIMED). - `internal/storage/hostops.go` — mandatory guard at the top of `Format` (refuse unless unclaimed); `Binaries.MkfsGuarded`; `Format` now execs the guarded wrapper; `SudoHostOps` gains a `HostReader`. - `configs/felhom-mkfs-guarded.sh` (new) — the root wrapper (below-the-agent gate). - `configs/felhom-agent.sudoers` — `FELHOM_FORMAT` drops raw `mkfs.*`, allowlists only the wrapper; read-only `pvs`/`zpool status -P` added to `FELHOM_DISK`. - `internal/storage/claim_test.go` (new), `hostops_disk_test.go` (updated), `internal/capability/manifest.go` (mkfs sample → wrapper). `CHANGELOG.md`, `README.md`, version. - Commit **`5209830`** on `main` (parent `05f22a9`). ## 3. Green gate `go build ./...`, `go vet ./...`, `go test ./...` — clean (local + build server 180). ## 4. Tests + red-proof - `TestClassifyClaim` (pure, table-driven): every claim signal (system/LVM-PV/ZFS/mdraid/member-FSTYPE/ foreign-mount/RO/undeterminable) → CLAIMED; fail-safe (gather error) → CLAIMED; clean disk + our-own- drive-re-init → unclaimed. **Red-proof:** the "system/OS disk (non-data-bearing)" case — removing the `isSystem` check flips it to `unclaimed=true` → the test FAILS (proves the guard adds safety beyond `DataBearing`, which would call a blank OS disk benign). Verified fail, reverted. - `TestFormatGuard_{RefusesSystemDisk,RefusesLVMMember,AllowsUnclaimed}`: the guard is wired into `Format` — refuses claimed devices (no mkfs), allows unclaimed (invokes the wrapper). - `TestParseLsblkNodes`; capability manifest coverage test updated + green. ## 5. Deploy + live validation (felhom-pve — SAFE, only /dev/sdd formatted) Published Gitea `felhom-agent/0.54.0` (sha `0500dd9bd15b03e67e8c93c0ac7aa8008d7413c335e6f852aeaf074d3b364eda`). Deployed to felhom-pve in order: install wrapper (0755) → swap sudoers (visudo-validated) → agent binary (backup `.bak-0.53.0`) → restart. (Note: my manual scp of the Windows working-copy sudoers had CRLF and failed `visudo`; fixed live by CR-stripping + re-install. The committed repo file is LF and the host-install `fetch_raw`-from-Gitea path is unaffected.) | Proof | Result | |-------|--------| | **P-1** wrapper on `/dev/sda` (OS) via agent sudo path | ✅ REFUSED "system/OS disk (/dev/sda backs /boot/efi)", exit 1, no mkfs | | **P-2** wrapper on `/dev/sda3` (the LVM PV) | ✅ REFUSED (system), no mkfs | | **P-3** raw `sudo mkfs.ext4 -F /dev/sda` as felhom-agent | ✅ DENIED ("a password is required" — not allowlisted; Part B) | | **P-4** wrapper on `/dev/sdd` (unclaimed throwaway) | ✅ ACCEPTED → mkfs.ext4 → `blkid /dev/sdd` = `TYPE="ext4"` | | agent-guard live reads (as felhom-agent) | ✅ `sudo pvs` / `sudo lsblk ` / `sudo zpool status -P` all OK → the guard can gather on the live host | | post-deploy health | ✅ agent 0.54.0 active; `--selftest=read` = 5 storages (3b-fix intact); 9201 running | **Part A (agent guard)** is unit-tested (logic, incl. red-proof) and its live host reads are confirmed working as the agent; **Part B (wrapper)** is live-proven on real devices (sda/sda3 refused, sdd accepted) + raw-mkfs denied. ## 6. NOT exercised / deferred - The `/disks/format` local-API endpoint was not invoked live (needs a guest local-API token). The guard it calls is identical to the unit-tested code, and its live reads + the wrapper below it are proven on real devices — so the stack is validated, just not through the HTTP entrypoint. - **Impl-3 residual:** a raw disk passed through to ANOTHER VM looks unused to the host — a host-level filter can't detect it; the shared-box operator gate (Impl-3) closes that. Impl-1 closes everything host-visible (a strict improvement over the prior no-guard state). ## 7. Observations - The guard's mount rule ALLOWS Felhom's own drives (mounted under `/mnt/felhom-drives`) for re-init; their DATA is protected by the separate DataBearing wipe-confirm, not this guard. So the spec's "refuse sdb/sdc" was not applicable to the guard (they're re-initable Felhom drives) — I did not mkfs them (customer data), per the STOP. - The throwaway `/dev/sdd` is now ext4 (was ntfs); unmounted, not enrolled. Safe to unplug.