Repository navigation
Preserve encrypted receive history when cache writes fail - #226
Merged
Merged
Conversation
Replace the prove-marker chatd check with a fixture controller and native window driver so base/branch evidence is the real decrypt-then- restart path, not an absent success marker. Co-authored-by: Cursor <[email protected]>
itz4blitz
marked this pull request as ready for review
November 8, 2026 19:59
itz4blitz
force-pushed
the
diagnose/sealed-cache-write-order
branch
from
November 8, 2026 20:00
27cd072 to
3ecc067
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed and why
A received Tiny message could advance its persisted MLS ratchet before its opened-history cache append failed. It stayed readable in RAM, then became undecryptable after restart. Save authenticated opened history durably before accepting that receive; a failed cache commit leaves its key available for retry after storage repair.
Type
Platforms
Proof
Scenario: e2e/scenarios/opened-history-cache-commit
Published Linux matched recordings and manifest, exact source
27cd07263a49176fcbca55f1538541ef8d26547cagainst official released base7ffa840a9beb7a7eb8017c679bc4ea1d82710876. Both use normal release-profile apps, invented people, fresh independent databases, and persistent wrapping keys established before first launch.Recorders started before driver steps. Both videos validate and were visually reviewed. Exact scoped message IDs, durable-cache presence and captured conversation pixels agree. The branch was built directly from a pinned source archive with normal release features and explicit embedded commit; all 1,535 archived source files were verified unchanged after build. The copied bundle hashes were checked before launch. All nine published asset sizes and SHA256 digests were verified.
e2e-lab/linuxis successful on this exact head; no aggregate status was posted.Both cases remove only the empty cache-path blocker and the scoped SQLite message index between cold launches. Conversation, keys and MLS state remain intact, without group resets or ratchet rewinds. The fixture server binary's source tree matches current server main; its manifest distinguishes build commit from source-tree equivalence.
Earlier Windows matched recordings remain pinned to prior head
b7f02bda8869ee9c0c706ec416fb98475d51b583; they are not relabeled as proof of the current head. The production Rust code is unchanged since that head; the later delta integrates current main and adds Linux test support. The Linux adapter uses owned executable/PID/foreground guards, native Jump input, conversation-pane image OCR and diagnostic Unix framing; Welcome screens and sidebar previews cannot satisfy the body assertion.The MLS/FileStore/Tiny component regression fails on the base. Additional regressions cover accepted-receive state-save failure, mismatched row epoch acceptance and attachment-registration ordering. At the production-code head: focused Tiny E2EE 95 passed / five existing ignored;
cargo test -p e2eepassed; fullcargo test -p chatdpassed with 499 library tests, 11 existing ignored and all integration suites green. Windows and Linux scenario suites each passed 19 tests with one platform-specific skip; all 108 lab tests passed. Independent Linux driver review found no blocking defect. Current-head release build and hosted CI pass.Draft / MERGE HOLD: the full five-platform plan is incomplete. Current-head Windows, macOS, Android and iOS native runs remain outstanding. No aggregate
e2e-proof, release certification, power-loss guarantee, or affected-install recovery claim is made. Scenario remainsrelease: false.Compatibility
Existing decrypt API keeps its lenient state-save semantics. The new receive-specific commit callback runs after authentication while its checkpoint is reversible. No protocol, key, snapshot/cache format or account-scope change. Older servers remain compatible. Soft outgoing/import/sibling persistence retains existing behavior; the separate long-history cutoff fix is outside this change.
Risk and rollback
Strict receives synchronize cache data before persisting consumed state, adding I/O latency. A cache failure refuses that read and logs storage failure; repairing storage permits retry. State-save failures retain consumed state in memory and remain visible on flush. A durable cached row survives an older state snapshot, but this is not an atomic two-file transaction: after restarting from lagging state, a genuine ciphertext under another server row ID may reopen, as with the existing lenient failure contract. No arbitrary post-crash replay, partial-write/sync-error injection, or power-loss guarantee is claimed. This prevents a reproduced future loss path; it does not reconstruct already lost plaintext or establish any affected user's exact cause. Reverting restores the unsafe cache-after-ratchet order. No client release or server deployment.
Release note
Keep received encrypted messages recoverable when saving their local history cache fails.