Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5.1 KiB
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 ofFormat(refuse unless unclaimed);Binaries.MkfsGuarded;Formatnow execs the guarded wrapper;SudoHostOpsgains aHostReader.configs/felhom-mkfs-guarded.sh(new) — the root wrapper (below-the-agent gate).configs/felhom-agent.sudoers—FELHOM_FORMATdrops rawmkfs.*, allowlists only the wrapper; read-onlypvs/zpool status -Padded toFELHOM_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
5209830onmain(parent05f22a9).
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 theisSystemcheck flips it tounclaimed=true→ the test FAILS (proves the guard adds safety beyondDataBearing, which would call a blank OS disk benign). Verified fail, reverted.TestFormatGuard_{RefusesSystemDisk,RefusesLVMMember,AllowsUnclaimed}: the guard is wired intoFormat— 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 <cols> / 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/formatlocal-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/sddis now ext4 (was ntfs); unmounted, not enrolled. Safe to unplug.