Files
felhom.eu/REPORT.md
T
admin f7cc6a720e GL-4: uninstaller gap-closure + operator-key day-0 fold (host-install v1.11.0)
Uninstall: NEW 4b4 removes the self-update artifacts (guarded wrapper,
.prev/.new.* A/B slots, rollback unit, limits drop-in — derived from
configs/felhom-selfupdate-guarded); enrolled drives under /mnt/felhom-drives
unmounted plain-umount-only (busy = warn+guidance, never -l/-f; root bind
guarded); both modes end with a KEPT-vs-WIPED statement (drives/PBS/hub
record/escrow/vaulted recovery credential live on); guest-only mode prints
the vmid's bind-store drives.

Key-pin: OPERATOR_KEY_* constants (empty until the operator ceremony) +
--operator-pubkey-file (argv-validated; comment=key_id required; file
overrides constants) -> authz.signers per the agent SignerKey schema;
no-keys-resolved KEEPS preserved signers; verify reports armed/dormant WARN.

Harness: +13 static cases + GL4-D parity + GL4-INV + PVE-tier GL4 H-U
(full-uninstall dry transcript vs live 9201). 28/28 on felhom-pve;
red-proofs RP-1..3 run->fail->revert. GO-LIVE-PACKAGE.md ABSENT AGAIN ->
status in CONTEXT.md. Live teardown/armed-pin = GL-6.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-08 08:14:07 +02:00

81 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# felhom.eu — task reports
> **Overwrite** this file with a summary of the most recent task only (uniform with the other repos; not cumulative). The cumulative hub history lives in [hub/CHANGELOG.md](hub/CHANGELOG.md); the scripts history lives in [scripts/CHANGELOG.md](scripts/CHANGELOG.md).
## TASK GL-4 — uninstaller gap-closure + operator-key day-0 fold — host-install v1.11.0 (2026-07-08)
**Baseline confirmed:** felhom.eu @ `a63cc715`, `SCRIPT_VERSION="1.10.0"`**`1.11.0`**;
felhom-agent reference @ `4c408467` (read-only — authz schema from `internal/config/config.go`
SignerKey, self-update paths from `configs/felhom-selfupdate-guarded`, drive root from
`internal/storage/{claim,netmount}.go`, bind store `/var/lib/felhom-agent/guest-binds.json` from
`cmd/felhom-agent/main.go:514`). §12 STOP honored: zero live install/uninstall runs anywhere.
**Part 0 — GO-LIVE-PACKAGE.md was ABSENT AGAIN.** The spec said the operator attaches it; it is
not in the repo, not anywhere under `E:\git`. Per the spec's own fallback: G6/G1 status recorded
in CONTEXT.md, no Commit 1. Third task in a row without the doc — flagging it loudly.
### Files modified
- `scripts/felhom-host-install.sh` → v1.11.0 (Parts 13; feature detail in scripts/CHANGELOG.md)
- `scripts/hostinstall-mode-harness.sh` — +13 static cases + PVE-tier GL4 H-U (extended, not forked)
- `documentation/runbooks/day0-install.md` — §C.5b key-pin section; Part E teardown additions
- `scripts/CHANGELOG.md`, `REUSE.md` (parity-pattern row), `CONTEXT.md`, this file
### Per-scenario results
| Scenario | Result | How |
|---|---|---|
| A — full uninstall dry covers everything | **PASS (live dry)** | GL4 H-U on felhom-pve vs the real guest 9201: selfupdate-artifact removals + kept-vs-wiped statement present, no `umount -l/-f`, no destructive op on any `/mnt/felhom-drives/` path (no drives currently mounted there → per-mount umount lines correctly conditional) |
| B — guest-only | **static** | branch adds `_guest_drive_note` (bind-store best-effort, generic fallback) + guest-scoped statement; not transcript-runnable on felhom-pve (no second Felhom guest) — GL-6 |
| C1 dormant WARN | grep-shape PASS (GL4-C1) + verify code path | |
| C2 keys written | **runtime PASS** (GL4-C2: valid file passes resolution, dies later at preflight, never at key parse) + write-shape in GL4-C4 | |
| C3 malformed file | **runtime PASS ×5** (unknown role / non-key line / missing key_id comment / empty file / missing file — each dies at argv naming the line) | |
| C4 preserve rule | grep-shape PASS (`if signers:` guard + pin-rotation notice) + red-proof RP-2 | |
| C5 file overrides constants | grep-shape PASS (notice + constant reset) — not runtime-testable while the shipped constants are empty (deliberate); the notice fires only when both sources are set | |
| D parity | **PASS** (curated token list over the uninstall section; every disclosure artifact covered by a removal or an explicit KEPT line) | |
**Red-proofs (run→fail→revert on scratch copies; repo file never mutated):**
RP-1 dropped the 4b4 block → GL4-D FAILED (24/28). RP-2 made the signers write unconditional →
GL4-C4 FAILED. RP-3 dropped the unknown-role die → GL4-C3a FAILED. All reverted (scratch deleted).
**Gates:** `bash -n` clean; shellcheck 0.10.0 `--severity=warning` clean on both scripts (the two
pre-existing SC2015 infos on untouched v1.9.1 lines remain triaged); harness **25/25 static
locally, 28/28 on felhom-pve** (H-A/H-B still cred-gated by demo-felhom's empty git credentials —
unchanged since GL-2). GL-2's Scenario-A contract re-verified: all v1.10.0 cases still pass.
### Implementation notes / judgment calls
1. **4b4 inventory** (from the guarded script, not spec memory): wrapper +
`felhom-agent.prev` + `felhom-agent.new.*` + `felhom-agent-rollback.service` + the
`felhom-agent-limits.conf` drop-in (+dir). `pending.json` + the staging dir live under
`$AGENT_STATE_DIR` — already removed in step 4 (noted in the block comment).
2. **Root-bind guard**: with a busy child mount, v1.10.0's `run umount /mnt/felhom-drives` would
have DIED mid-teardown (set -e); the root umount is now skipped with a warn when children stayed
busy — the statement lists them as "retry".
3. The statement's conditional lines: PBS (any `pbs`-type storage present), recovery credential
(`_state_has break_glass`, snapshotted BEFORE the state file is deleted); hub record + escrow
always printed (escrow phrased "if one exists" — there is no cheap local detector).
4. Key-file validation happens at argv time (before the passphrase prompt) so all C3 cases run on
any machine; options-prefixed authorized_keys lines (e.g. `command="…"`) are rejected as
"bad key type" — the pin format is deliberately plain `<type> <b64> <key_id>`.
5. H-U initially FAILED on felhom-pve because the naive assertion flagged the legitimate
`rm -f /usr/local/sbin/felhom-mkfs-guarded` line as "contains mkfs" — fixed to Scenario A's
real invariant (destructive ops on `/mnt/felhom-drives/` paths only).
### NOT live-validated — awaiting supervised GL-6
- The real (non-dry) full uninstall: drive umounts incl. a genuinely busy mount, the statement on
a real teardown, residue re-diff at v1.11.0.
- Guest-only mode on a multi-guest host (Scenario B transcript).
- An armed key-pin install end-to-end (needs the operator's real keys — the pin CEREMONY, incl.
pinning felhom-pve, is the operator's; the constants ship empty).
- C7-class verify-drift firing.
### Follow-ups
- **OPERATOR:** the key ceremony (offline keypairs → fill `OPERATOR_KEY_*` or keep a pubkey file);
the GL-1 manifest bump is still pending too (agent 0.74.0 / golden 0.103.0).
- **OPERATOR:** actually attach/commit GO-LIVE-PACKAGE.md (absent for the third task running).
- Observation: `install-v191.sh` (v1.9.1) is what `~/drill` still carries; GL-6 should fetch the
served v1.11.0 from felhom.eu (git-sync auto-deploys this push in ~12 min).