Files
felhom-controller/REPORT.md
T

3.9 KiB

REPORT — felhom-controller v0.44.0: role-aware drive management + customer type-to-confirm wipe

Repo: felhom-controller · Version: 0.44.0 · Date: 2026-06-11 · pairs with felhom-agent v0.23.0

What this implements

The controller half of the storage-authorization redesign (CC SPEC, Part B). The drive UI is driven by the agent's authoritative role (system | backup | user-data): system/backup are visibly protected with no destructive controls; the customer manages their own data drives with informed consent (type-to-confirm + named app impact).

B0 — agentapi client

  • DiskInfo += role, total_bytes, used_bytes, used_fraction.
  • FormatResult += role, needs_confirmation, durable_id.
  • FormatDisk(ctx, device, fstype, confirmed, durableID) — new ErrNeedsConfirmation (user-data, awaiting the customer's confirmation) vs ErrFormatRefused (system/backup, operator signature).

B1 — Role-aware overview (no destructive controls on protected drives)

  • settings.html "Meghajtók (ügynök nézet)" restyled from a raw <table> to cards (house style): name prominent, mono device/mount sub-detail, badges for class / data / role (🔒 lock for system & backup) / registered, and a capacity bar reusing the monitoring system-bar (green→amber→red). Eject/Wipe controls render only for user-data drives mounted under /mnt.

B2 — Customer wipe/eject flow

  • Name the apps: GET /api/storage/impact?where=appsUsingPath → the deployed apps (by display name) whose HDD_PATH is that mount. Shown in the modal before any destructive action.
  • Type-to-confirm: a modal with a text field; the destructive button stays disabled until the typed value equals the mount name exactly (enforced client-side AND server-side in /api/storage/wipe).
  • Wipe (POST /api/storage/wipe): eject (unmount + deregister) → server-side two-step customer-confirmed format (learn the agent's durable id via the NeedsConfirmation response, then re-submit confirmed:true bound to it). Deregisters the StoragePath.

B3 — Init/attach role-gated + restyled

  • storage_init.html: data-bearing path now uses the customer-confirmation flow (type-to-confirm → re-submit confirmed) instead of the felhom-opsign instruction; selector restyled to cards, lists only user-data targets (system/backup are not offered). The opsign surface remains as a fallback if a protected device somehow reaches it.
  • storage_attach.html: restyled to cards, user-data only.

B4 — UI polish

  • New CSS appended to style.css (reusing existing tokens): .drive-card / .drive-badges / .drive-cap, the missing .badge-ok / .badge-lock / .badge-muted / standalone .mono, and the type-to-confirm .confirm-overlay / .confirm-box. No new design system; no raw table left.

Tests

  • internal/agentapi/disks_test.go — blank → ok; system/backup → ErrFormatRefused (+pending op); user-data → ErrNeedsConfirmation (+durable id + role); confirmed → formatted.
  • internal/web/storage_handlers_test.go — init on a user-data data-bearing device returns NeedsConfirmation and does NO mount/register; confirmed init forwards the confirmation+durable id and proceeds to register; system/backup init still surfaces the opsign; appsUsingPathIn names the right deployed apps (dependency-impact). Plus TestTemplatesParse (all templates parse).

go build ./... && go vet ./... && go test ./... all green (Go 1.26, local).

Version

v0.43.0 → v0.44.0 (build-time ldflags Version).

Live validation / deploy

Pending in this session: build+push the image, deploy to guest 9201, rebake the golden, and run the live checks (overview tiers, the hand-issued confirmed:true refusal on a system/backup device, a user-data confirmed wipe binding to the durable id, and the audit-log entry).