GL-6 Gate-0 ruling (G3): v1.11.2 — anonymous artifact fetch supported

Operator ruling at the GL-6 drill's Gate 0: the Felhom artifacts are
world-readable by design; an EMPTY git.username/git.token in the customer
config now WARNS and fetches anonymously instead of dying at step 5/8
(the hub-vouched sha256 stays the integrity root; a configured credential
is still used when present; curl auth args are conditional because -u with
an empty token 401s even on public content). All 12 installer fetch
targets validated 200 anonymously before shipping. Harness: +GL6-ANON
shape case; GL4-C2 assertion updated for the v1.11.1 pinned constants
(the benign overrides-notice is not a die). Drill record carries the
deviation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
This commit is contained in:
2026-07-08 12:28:51 +02:00
parent bd97bc3474
commit 0640aa06ea
3 changed files with 129 additions and 12 deletions
@@ -0,0 +1,74 @@
# DRILL GL-6 — supervised go-live drill (demo box, two full cycles) — 2026-07-08
> Go-live item **G7** + the live-validation landing zone for GL-1…GL-5b deferrals. Destructive-
> supervised: guest 9201 destroyed + rebuilt twice; Viktor present, gating every phase. This record
> is filled per phase as evidence lands; timings + deviations verbatim. No secrets.
**Inputs verified at start:** felhom.eu `bd97bc34` (host-install **v1.11.1**, operator pubkeys
pinned) · felhom-agent `7f073936` (v0.76.0) · hub Day-0 manifest vouches agent
`0.76.0`/`9828c5f7…f50b` + golden `0.103.0`/`8481e8a1…6026e` (fetched via the box-facing API).
## Phase 0 — preflight + key validation (nothing destroyed)
| Step | Result |
|---|---|
| 0a baselines | **PASS** — repo heads + `SCRIPT_VERSION="1.11.1"` + manifest all as stated above |
| 0b key validation leg 1 | **PASS** — all four fingerprints EQUAL (below) |
| 0c key validation leg 2 | [Viktor] — pending at Gate 0 |
| 0d abort-path backup + restore-test | **PASS** (local + PBS backups fresh; PBS restore-test parity ok, 5m35s) |
| 0e busy-drive prop | **STAGED**`gl6-busyprop` unit cwd-pinned into `/mnt/felhom-drives/felhom-usb` (4h) |
| 0f mechanism re-read | **DONE** — Phase-3 delivery pinned (below) |
### 0b — the four fingerprints, side by side
```
repo op (felhom-op-1): SHA256:7YqN4rXO08yixTeOO+UtQ8jHyIGycICuctQgRYVGnWw
box op (felhom-op-1): SHA256:7YqN4rXO08yixTeOO+UtQ8jHyIGycICuctQgRYVGnWw
repo rec (felhom-rec-1): SHA256:/ixgTesZqykAGJpFUUd4kLAiHFgKOkYFLNC3AQXWP+k
box rec (felhom-rec-1): SHA256:/ixgTesZqykAGJpFUUd4kLAiHFgKOkYFLNC3AQXWP+k
```
Box source: felhom-pve agent config (`systemctl cat``-config` path) `authz.signers[]`;
repo source: the v1.11.1 `OPERATOR_KEY_*_LINE` constants. Both match the runbook's stated values.
### 0d — abort-path backups (the session's safety net)
- **Local (agent pipeline):** `--selftest=backup -vmid 9201` → snapshot-mode, crash-consistent,
`local:backup/vzdump-lxc-9201-2026_07_08-11_43_42.tar.zst` (6.82 GB, 5m52s). Expected
`uncovered_volumes`: `/etc/felhom-bootstrap` + `/mnt/felhom-drives` (bind mounts — regenerated /
re-enrolled, per doctrine).
- **PBS (offsite tier, PVE-native vzdump per the S4-proven path):** `felhom-pbs:backup/ct/9201/2026-07-08T09:51:00Z` — 3m04s (dedup)
— NOTE: the live config deliberately pins `local_backup_target: local`; the PBS leg was driven
with `vzdump 9201 --storage felhom-pbs --mode snapshot` (tunnel healthy, storage active).
- **Restore-test vs the fresh PBS archive:** **PASS**`mount_parity: ok`, inventory
`mp0=/var/lib/docker (200G)`, `mp1=/mnt/sys_drive (50G)`, mp8/mp9 throwaways; scratch 990000
restored+booted+verified+torn-down in **5m35s** (first G12 PBS-tier runtime datum).
Observation (cosmetic): the record's `source_tier` says "local" — the tier label derives from the
CONFIG backup target, not the explicit `-archive`'s storage; display-only.
### 0e — busy prop + data-intact witness
Prop: transient unit `gl6-busyprop`, cwd inside `/mnt/felhom-drives/felhom-usb`.
Witness file (for the Phase-1/5 drive-data-intact checks):
`userdata/actualbudget/canary_hdd_actualbudget.txt` on `/dev/sdd1`
(UUID `da9e7089-cf8e-4617-adcb-a377743fae00`), sha256 prefix `7b00bc3550b10e3952e0e0965f5a2628`.
### 0f — Phase-3 signed-update mechanism (confirmed at source, NOT improvised)
1. [Viktor] sign: `felhom-opsign -op agent_update -host <host_id> -key-id felhom-op-1
-agent-version <v> -sha256 <hex> -key <operational private key> [-ttl 30m]` → signed-op blob.
2. Deliver: `POST /api/v1/admin/hosts/{host_id}/jobs` `{job_id, blob_b64}` — **hub GLOBAL key
required** (Viktor), or the v0.70.0-precedent direct `signed_jobs` sqlite insert on the hub pod
(CC via kubectl on 180). The agent's heartbeat sees `has_signed_ops`, fetches, verifies against
the PINNED operational key + durable nonce store, downloads the binary from Gitea, re-verifies
the SIGNED sha (the only integrity root), then `felhom-selfupdate-guarded apply` A/B-swaps with
crash-rollback armed; dwell → `commit`.
## Gate 0 — [Viktor]
- Input 1 (byo caps): <pending>
- Input 2 (Phase-6 repopulation): <pending>
- 0c fingerprint confirmation vs password manager: <pending>
- Verdict: <pending>
*(Phases 16 appended as they run.)*