fix: Reserve frame for duress at chunk cap (v4.6.4 GPT-5.6-Sol HIGH re-review fix) GPT-5.6-Sol re-review of the v4.6.4 frame-ceiling duress wire fix surfaced one HIGH finding (silent duress drop when entries hit MAX_SNAPSHOT_CHUNKS) and two doc drift items. This save addresses all three: HIGH: cap-math fix in src/shared/vault-adopt.ts:sendVaultSnapshot. When duress is configured, the entry cap is now MAX_SNAPSHOT_CHUNKS - 1 = 199 so the duress frame can always fit alongside. Previously a vault with exactly 200 entries + duress had its duress frame silently dropped at the cap, and ordinary sync cannot restore duress (vault.test.ts:158 test-locks duress as non-syncing). Now duress always fits; one entry is deferred to sync when needed, which is safe because sync carries entries and tombstones. Also added a pre-encode check on the duress envelope: oversized duress (single duress frame > SNAPSHOT_FRAME_WIRE_CEILING) throws ADOPT_SNAPSHOT_DURESS_FRAME_TOO_LARGE BEFORE any frame is sent, so the caller can split duress out of band instead of silently losing it. LOW + NIT doc drift in docs/vault-adoption-design.md and src/shared/vault-adopt.test.ts: - Acknowledgement timing subsection rewritten: ADOPT_SNAPSHOT_APPLIED is the entries/tombstones/duress commit and ADOPT_DEVICE_MANIFEST_APPLIED is a separate, subsequent commit (the source treats them as independent, not nested). Cross-referenced to relay-adoption-bg.ts:458-500. - Duress-frame description corrected: duress frame has empty entries but carries the tombstone map (not empty tombstones); tombstones migrate here from the last entries chunk when duress is configured. - T-A33 comments rewritten in historical tense and the duress payload size note corrected (320 KiB of `cc` chars yields ~640 KiB of JSON, not 320 KiB raw; the assertion remains valid because the duress is opaque to the receiver and serializes raw). src/shared/vault-adopt.test.ts - added 2 boundary tests at the cap: - T-A36: 199 entries + duress fits in MAX_SNAPSHOT_CHUNKS (199 + 1 duress = 200 frames, duress arrives intact). - T-A37: 200 entries + duress does not silently drop duress at the chunk cap (duress still arrives intact; entry cap = 199, excess entries deferred to sync). Plus the pre-check guardrail is exercised by the existing oversized test that already exceeded the ceiling on the duress-only frame path (now throwing instead of silently producing an oversized duress frame). Mirrored on peach-android v2.9.9 save 943c244c435c (Android unchanged, no version bump; the prior v2.9.9 save c0c413a8804 still owns the wire shape, this save closes the cross-repo HIGH re-review finding). Versions: peach-browser unchanged at 4.6.4 (cap fix is a wire-fix follow-up; same VERSION saves the wire shape previously since the duress-reservation rule is part of the same feature). Gate: tsc --noEmit RC=0; vitest run 138 passed / 1 skipped (139 files) / 3670 tests passed / 40 todo / 0 failed (baseline 3665 + T-A33 + T-A34 + T-A35 + T-A36 + T-A37 = 3670). pnpm run build RC=0 across Chrome Firefox Mobile; dist manifests report 4.6.4.
$ koh steal kepr.uk/peach-browser@1077ccaa33eb
·
parent: 8411b9a63ec4
discussion
log in to leave a comment.