Two Android fixes found on the iPhone-to-Android pair against a local relay (2026-10-09), both on main today.
Another account on the same install inherited the vault. A plain sign-out keeps the vault so the same person can sign back in. A different account then got a new device identity (android#22) and every other record: it saw the previous account's conversations and sent its first message on the previous account's ratchet session, which the far end could not open. AccountSwitch.forgetPreviousAccountIfSwitching empties the vault when another user id or relay signs in, before its device is made. The same account keeps everything.
Two writes of one vault record killed the app. Draft saves ran per keystroke on the IO pool and staged into one <name>.tmp; the second rename found nothing and threw on a worker thread. Each write now stages under its own name, and draft saves run one at a time, in order.
Tests first: AnotherAccountStartsWithNothingTest (2 red, then 4/4) and TwoWritesOfOneRecordDoNotCrashTest (400 writes from 8 threads, red, then green).
Local suites on 8842479 (vectors at the pinned be8093f): engine 723, client 480 (30 live tests skipped, no relay), obfs4 75, app debug 381, app release 340, 0 failures.
Two Android fixes found on the iPhone-to-Android pair against a local relay (2026-10-09), both on main today.
- **Another account on the same install inherited the vault.** A plain sign-out keeps the vault so the same person can sign back in. A different account then got a new device identity (android#22) and every other record: it saw the previous account's conversations and sent its first message on the previous account's ratchet session, which the far end could not open. `AccountSwitch.forgetPreviousAccountIfSwitching` empties the vault when another user id or relay signs in, before its device is made. The same account keeps everything.
- **Two writes of one vault record killed the app.** Draft saves ran per keystroke on the IO pool and staged into one `<name>.tmp`; the second rename found nothing and threw on a worker thread. Each write now stages under its own name, and draft saves run one at a time, in order.
Tests first: AnotherAccountStartsWithNothingTest (2 red, then 4/4) and TwoWritesOfOneRecordDoNotCrashTest (400 writes from 8 threads, red, then green).
Local suites on 8842479 (vectors at the pinned be8093f): engine 723, client 480 (30 live tests skipped, no relay), obfs4 75, app debug 381, app release 340, 0 failures.
Not a release: no APK publish.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Two Android fixes found on the iPhone-to-Android pair against a local relay (2026-10-09), both on main today.
AccountSwitch.forgetPreviousAccountIfSwitchingempties the vault when another user id or relay signs in, before its device is made. The same account keeps everything.<name>.tmp; the second rename found nothing and threw on a worker thread. Each write now stages under its own name, and draft saves run one at a time, in order.Tests first: AnotherAccountStartsWithNothingTest (2 red, then 4/4) and TwoWritesOfOneRecordDoNotCrashTest (400 writes from 8 threads, red, then green).
Local suites on
8842479(vectors at the pinned be8093f): engine 723, client 480 (30 live tests skipped, no relay), obfs4 75, app debug 381, app release 340, 0 failures.Not a release: no APK publish.
🤖 Generated with Claude Code
mentioned in merge request !162
mentioned in commit
ba9a94a85fmentioned in commit
6eb6b77329