E-2 complete: wrapper, installer Case A/B, offer flow, degraded banner

Live: hub 0.81.0, agent 0.113.0, controller 0.185.1 on both demo boxes;
host-install 1.22.0 (script; no reinstall performed).

E-2a wrapper proven live as root on demo-hp: F-1 subdirectory refused, F-2
unmounted path refused, root device refused, idempotent re-apply is a no-op,
repointing refused -- 0 stray storages. The agent PVE role was NOT widened.

Scenario E proven live on BOTH boxes: healthy renders nothing, no message key.

Records three defects I introduced and caught: unreachable routes (mounted
outside /api/storage/, caught by the first live call), a hollow test exposed by
its own red-proof, and another gofmt-realignment no-op.

Not live-proven: the degraded banner and offer acceptance (both boxes healthy),
backup_target_absent end-to-end, Case A/B on a real install, drive-loss recovery.
This commit is contained in:
2026-07-29 09:16:59 +02:00
parent f6aed82940
commit bcbe2707d6
2 changed files with 74 additions and 2 deletions
+72
View File
@@ -109,3 +109,75 @@ mock, because the failure class is "nothing arrives".
two identically-exposed boxes, so demo-felhom was rolled to the same proven artifacts.
- `StorageTarget.Role` carries a documented vocabulary including `vzdump-target` and is always `""`.
Checked — it is a deliberate unpopulated field ("hub-owned, slice 10"), **not** a sixth dead seam.
---
# E-2 increment 2 (same day): the wrapper, the installer, the offer and the banner
**Live fleet:** hub **0.81.0**, agent **0.113.0**, controller **0.185.1**, host-install **1.22.0**
(script; no reinstall performed). Both demo boxes. `peti-felhom` untouched.
## E-2a — the guarded wrapper
`configs/felhom-backup-target-apply` behind a literal `FELHOM_BACKUPTARGET` sudoers alias. **The
agent's PVE role was not widened** — it still holds neither `Datastore.Allocate` at `/storage` nor
`Permissions.Modify`.
All five laws proven live as root on demo-hp, with **0 stray storages created**:
| Probe | Result |
|---|---|
| F-1 subdirectory (`/mnt/nvme-1tb/dump`) | REFUSED — "must be the drive's OWN mountpoint" |
| F-2 unmounted path | REFUSED — "would silently retarget onto the system drive" |
| root device (`/`) | REFUSED |
| idempotent re-apply on the real target | no-op, exit 0 |
| repointing an existing id | REFUSED |
`POST /backup/target` drives it **create → grant → config**, and deliberately does **not** restart the
agent: it returns `restart_required` so the restart happens behind the caller's own immediate
in-flight check. That is E-1's spurious-tier-failure mistake encoded as a contract, and a test asserts
the handler never restarts.
## Part 2 — the installer (v1.22.0)
Case A creates the target through the same wrapper; Case B records DEGRADED in two warning lines and
**still succeeds** — a single-drive appliance is valid. Scenario F returns early with **0 wrapper
calls**; the red-proof (guard removed) shows **2**, i.e. it would have "corrected" a correct box.
**Installer-logic-tested, NOT install-tested** — the harness runs the extracted functions with
stubbed `pvesm`/wrapper. No reinstall was performed.
## Parts 3+4 — the offer and the banner
`POST /api/storage/backup-target/assign` is the **only** writer of the role. `GET
/api/storage/backup-target` drives the banner. Hungarian copy is FACT → CONSEQUENCE → REMEDY.
**Scenario E proven live on both boxes** — healthy renders nothing:
```
demo-hp {"degraded":false,"known":true,"label":"NVME 1TB","target":"felhom-backup"}
demo-felhom {"degraded":false,"known":true,"label":"USB HDD 1TB","target":"felhom-backup"}
```
No `message` key at all. Red-proofed: adding a reassurance to the healthy branch fails Scenario E.
## Three defects I introduced and caught
1. **The offer endpoints were unreachable.** Registered as `/api/backup-target` inside
`ServeStorageAPI`, which `main.go` mounts only at `/api/storage/`. Every unit test passed because
they called the handlers directly; the **first live call** returned `endpoint not found`. Fixed in
v0.185.1 with a test that asserts the dispatcher's own source contains both routes.
2. **A hollow test.** `TestUnknownStateRendersNothing` used `{Known:false}` with `Degraded` left
false, so it passed even with the `!Known` guard deleted. Its own red-proof exposed it; the
fixture is now `{Known:false, Degraded:true}`.
3. **A gofmt-realignment no-op** (again): a `sed`-style replace silently matched nothing because the
formatter had changed the spacing. Every mutation is now verified to have landed before its result
is trusted.
## Still not live-proven
- The **DEGRADED banner** and the **offer acceptance** — both boxes are healthy, so neither state
occurs naturally. Unit- and red-proofed only.
- **`backup_target_absent` end-to-end** — needs a live enrolled drive to go absent.
- **Case A/B on a real install** — installer-logic-tested only.
- **Full drive-loss recovery** — physical access.