# REPORT — slice 8C (controller half): de-privileging + disk management via the agent (v0.37.0) (2026-06-10) > Overwrite-latest report. Cumulative history: [CHANGELOG.md](CHANGELOG.md). Implements the in-guest > controller half of `TASK — Slice 8C` (closes slice 8). Pairs with `felhom-agent` v0.12.0. ## Outcome The disk-execution subsystem moved to the host agent. The in-guest controller is now **Docker-only with no disk/Proxmox privileges** and drives disk management through the agent's local API. **~12.3k LOC retired.** The controller-side re-platform milestone — **slice 8 CLOSED**. ## What landed - **Disk management via the agent** (`internal/web/agent_disk_handlers.go`, `ServeDiskAPI`): thin proxies `GET /api/disks` / `POST /api/disks/{assign,eject,format}` over the slice-8A `agentapi` client (leaf-pinned, own token). Execution is the agent's; the UX stays here. A **data-bearing format refusal** (`agentapi.ErrFormatRefused`) surfaces as **HTTP 409 "operator authorization required"** — the agent inspects the device; the controller's claim is irrelevant. - **`internal/agentapi`**: `Disks`/`AssignDisk`/`EjectDisk`/`FormatDisk` + `ErrFormatRefused`. ## Retired (→ agent / obsolete) - **`internal/storage/`** (whole package: scan/format/attach/migrate/safety, DriveMigrator). - **`internal/backup/`**: restic, crossdrive, restore_drives, disk_layout, local_infra, restore_scan, drive-restore, restic paths. **`backup.Manager` surgically split to app-data only** (DB dumps + Docker-volume tars + per-app restore kept; restic/cross-drive/snapshot-history/integrity dropped; `RestoreApp` now restores from on-disk volume-tar dumps — snapshot restore is the agent's domain). - **`report/infra_backup*` + `infra_pull`** (kept the setup fresh-install config download), **`setup/scanner`** + the wizard's drive-recovery flows, **`monitor/watchdog` + `pinger`** (watchdog → agent; Healthchecks pinging → the Hub owns monitoring), **`web/storage_handlers` + `handler_restore`**. Wiring dropped from main/router/web (CrossDriveRunner, DriveMigrator, watchdog, infra push, restic scheduler jobs; kept the db-dump job). ## De-privileged `scripts/docker-setup.sh` controller compose: dropped `privileged: true`, `/mnt` rshared, `/sys`, `/dev`, `/etc/fstab`, `/run/udev`. The golden's bootstrap `docker run` was already minimal (8A). ## Tests / build `go build ./...` + `go test ./...` green (app-data backup / stacks / quiesce / bootstrap / agentapi / disk-client tests pass). The data-bearing-format refusal is proven in `agentapi` tests. ## Live validation (demo-felhom) A provisioned controller v0.37.0 from the refreshed golden: **`Privileged=false`**, container mounts ONLY bootstrap + data + docker.sock (no `/dev`/`/etc/fstab`/`/sys`/`/mnt`), **healthy + configured** (not setup). It drove the agent disk API: `GET /disks` (data-bearing flags) and a **data-bearing format → refused** (the agent inspected the device, the gate returned `pending_signature`, nothing formatted). The de-privileged controller runs app management normally (8A bootstrap / 8B quiesce unaffected). ## Deferred / note The operator-signed completion of a data-bearing wipe → slice 10. `RestoreApp` restore semantics changed (volume-tar dumps, not restic) — restic/snapshot restore is the agent's domain now. Unused `config.Backup` restic/retention fields left in place (harmless; out of scope). No secrets committed.