feat: Carry the sealed duress slot across adoption snapshot (v4.6.0) A duress configured on the extension must survive adopting the vault onto a new device. The 2.9.0 inline adoption snapshot shipped entries + tombstones but not the duress slot, so phone-pairing adoption silently dropped a configured decoy (the Codex-restore path already carried it). Wire contract (additive, backward-compatible; coordinated with peach-android): - ADOPT_SNAPSHOT gains optional duress_slot?: string = JSON.stringify of the browser-shaped slot B, identical to the Codex vault_b field. - Populated on the FINAL chunk only, and only when duress is configured (isDuressEnabled); absent otherwise (never ships noise). Old peers ignore it. Changes: - vault-adopt.ts: duress_slot on AdoptSnapshot + isAdoptSnapshot guard; sendVaultSnapshot threads it (final chunk only); receiveVaultSnapshot returns duressSlot. - vault.ts: exportDuressSlotForAdoption (source; no decrypt) and installAdoptedDuressSlot (receiver; same hasValidVaultSchema guard as unlockFromCodex; passthrough write to slot B; no decrypt). - relay-adoption-source-bg.ts: source sends it (omission non-fatal); receiver installs it in an isolated try/catch so a duress-install failure cannot demote a successful entry snapshot to the sync fallback. Preserves browser HOLE-5 (duress vault has no root key / sync identity): duress propagates via vault TRANSFER, not day-to-day sync. Verification (orchestrator-independent): tsc clean; full vitest 3656 passed / 138 files (baseline 3645, +11 tests); Chrome+Firefox+Mobile builds succeed.
$ koh steal kepr.uk/peach-browser@7410c0da42c1
·
parent: 26932e7e92a5
discussion
log in to leave a comment.