# TASK — agent: identity-only escrow ceremony (K-optional) — unblocks no-PBS customers ## 0. Scope & baseline felhom-agent v0.79.0 (re-confirm live head) → **v0.80.0**. No controller/hub change: the upload wire shape already carries `restic_pw_sha256` + the blob; auto-confirm matches the hash — K is irrelevant to it. ## 1. Design - `escrow.CreateOptions.KeyPath == ""` becomes VALID **iff** `IdentityBundle != nil` → identity-only mode: skip `KeyFingerprint`, skip the K `Wrap`, skip paperkey; generate R exactly as today; `WrapIdentityBundle` under R; **self-verify by unwrapping the identity blob** (the "an escrow you haven't recovered isn't an escrow" rule applies to the identity path too — today only K is self-verified; identity-only mode MUST self-verify the identity blob); upload with `KeyFingerprint` empty/omitted. - `runSelftestEscrowCreate`: when no `-storage` AND `escrow.pbs_storage_id` empty → do NOT die; log "no PBS storage — identity-only escrow" and proceed iff there is anything to escrow (staged restic password and/or bundle file and/or WG key); if truly nothing to wrap → clear error ("nothing to escrow"). - K present (demo & PBS customers) → behavior byte-identical to today (K + identity, both self-verified). - Hub: verify `SaveHostEscrow`/upload handler tolerate an empty key fingerprint (read the handler; if it rejects empty, a one-line relaxation on the hub side joins this task — re-confirm at source, do not assume). ## 2. R semantics (unchanged, restate in the doc) Fresh R per ceremony, displayed once, never retained; supersedes the customer's previous R; the old blob stays valid for old history only. ## 3. Tests (non-hollow + red-proofs) - Identity-only: no KeyPath + bundle with `restic_repo_password` → blob created, **self-verify unwrap byte-exact**, upload payload has the blob + `restic_pw_sha256`, no K ops attempted (fake records). **Red-proof:** restore the KeyPath-required guard → identity-only test fails. - Self-verify red-proof: corrupt the blob before verify → ceremony FAILS, nothing uploaded. - Nothing-to-escrow: no K, no staged pw, no bundle, no WG key → clear refuse. - K path regression: with KeyPath → identical call sequence to v0.79.0 (golden assertions). ## 4. Deploy / live Build v0.80.0 → felhom-pve (demo agent) → healthy, 56/56 caps. Publish 0.80.0 to Gitea + bump the hub Day-0 agent manifest (the publish-train pattern; the operator-sign step is Viktor's 🛑 as per GL-1). **Peti's agent update path:** the agent self-update is operator-signed + pinned — confirm from the go-live record how a BYO agent updates (self-update channel armed at his install? operator pubkey file was NOT passed on his install form) — if his box cannot self-update the agent, REPORT must say so and the ceremony waits for the next Peti-touch window (he runs one update command). Do not improvise a new update path. ## NOT to do Do not weaken the K path or its self-verify; do not skip the identity self-verify; do not change the R generation/display; do not touch controller/hub auto-confirm logic; do not run a ceremony on any real box from this task (unit + demo-agent deploy only).