# Task26 exact-one replacement invite harness v3

This append-only harness supersedes v2 only for the explicitly authorized replacement. It requires one and only one prior session: the fixed, generation-2, unclaimed `EXPIRED` session `cb_v4olwxbpSQatMtVLR4QLmw`. The canonical registry must remain empty and the gateway service inactive. Any absent, additional, changed, claimed, or nonterminal session fails closed before candidate preparation.

The sealed r2 draft and its globally new customer key are the only accepted input. `prepare` subscribes to the existing canonical ledger directory before invoking `RoomBootstrapStore.prepare_rehearsal_customer_invite`, then requires one ledger write event and a distinct generation-1 `PREPARED` session while preserving the old session byte-for-byte. A second use sees two sessions and is rejected, so a third invite cannot be prepared. The old session ID and SID hash are forbidden for the replacement.

`observe` and `expire` accept only the distinct second session and preserve v2's event-first claim observation and canonical `RoomBootstrapStore.expire_unbound` behavior. Raw token material is confined to the one mode-0600 handoff.

Run `dry-run` and `verify` before `prepare`. Do not disclose the handoff until `observe` has emitted its READY receipt. No command performs service startup, profile restoration, direct authority editing, network access, provider access, or Telegram access.
