huddle 1.3.1 — post-quantum downgrade hardening + DM handshake liveness
Security + reliability patch hardening the 1.3.0 hybrid post-quantum DM key agreement. No wire-format change; fully compatible with 1.3.0 and pre-1.3 peers.
Post-quantum downgrade hardening
- PQ-capability pinning. 1.3.0 stopped a relay from stripping the signed ML-KEM fields, but a relay could still replay a peer's captured pre-1.3 (classical-only) announce to force the quantum-breakable classical key — reopening the harvest-now-decrypt-later gap. 1.3.1 pins a peer's post-quantum capability the first time it's seen (persisted across restarts) and then refuses the classical fallback for that peer.
- Self-healing classical→hybrid upgrade. A DM that ever ends up keyed classical (rollout timing, or a replay that won an initial race) is upgraded to hybrid the moment the partner's capability is observed — no restart — and the upgrade rotates the outbound Megolm session so every message sent after the upgrade uses a key never exposed classically. (Forward-only: messages already sent during the brief classical window stay exposed.) Upgrades are one-way; a hybrid DM is never downgraded.
Handshake liveness
- The responder explicitly requests the KEM ciphertext when missing, a bounded background nudge re-prompts a stalled handshake, and a decrypt-miss key-request re-delivers a lost session key — so a single lost announce no longer wedges a DM until restart.
Docs
- Corrected the threat-model wording: rotation is forward-only, the relay can attempt a replay-downgrade (now mitigated by the pin, with a documented first-contact residual), and a few stale claims/labels.
Reviewed by a multi-agent adversarial pass (design judge panel + two review rounds). Full workspace build/clippy/tests green.