Closer/app
null 3c74aec82d feat(crypto): escrow the sealed-reveal key under the couple key (heals the second-device gap)
The per-user ECIES keypair lived on exactly one phone. A second device — a new
phone, a reinstall — had no private key, so every sealed reveal died there. Worse
than dying: it reported "waiting for partner". The user isn't waiting for anything;
their key is gone. They'd never report that bug accurately, because the app told
them the wrong story.

Fix: escrow, not multi-device fan-out. The private keyset is stored encrypted under
the COUPLE key (AAD = uid) at users/{uid}/devices/primary/secure/escrow; a device
holding the couple key — which is a precondition for reading anything at all —
imports it and becomes crypto-identical to the original. Fan-out (sealing every
release key to N public keys, plus device lifecycle and pruning) buys the same
outcome for an order of magnitude more protocol, and this product has no
multi-device story to justify it.

Escrow leaks nothing: the only party besides the owner who can hold the couple key
is the partner, and everything this keypair protects — release keys for the
partner's OWN answers, restore keyboxes of the SHARED keyset — is material the
partner already has. It adds zero capability to anyone. It's owner-only anyway:
the escrow is a SUBDOC because the parent devices/primary must stay
partner-readable (they seal to the public key) and rules can't gate one field.
That distinction is now the mutation-checked test — making the escrow inherit the
parent's read rule fails exactly "the PARTNER cannot read the escrow".

Corrected the KDoc while I was in there: it claimed a second sign-in "overwrites
users/{uid}/devices/primary". It doesn't — every publish site is existence-gated,
so device 1 keeps working. The real failure was narrower and quieter than the
documentation said, which is its own small lesson about trusting comments.

Heal-forward on Home load (migrateProfileFields shape: idempotent, best-effort,
never blocks Home) so existing users escrow on next launch. Residual case
documented rather than hidden: a user whose only device dies BEFORE ever escrowing
keeps today's behaviour — that key never left the phone and nothing can fix it
retroactively.

10 new rules tests (151 total, mutation-checked). Android suite green, assemble
clean. Rules deploy + the live wipe→recover→sealed-reveal proof still pending.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 22:28:43 -05:00
..
schemas
src feat(crypto): escrow the sealed-reveal key under the couple key (heals the second-device gap) 2026-07-15 22:28:43 -05:00
build.gradle.kts feat(avatar): frame a picked photo, and fall back to initials not a heart 2026-07-14 23:19:37 -05:00
proguard-rules.pro