- Drive chat list, timeline and forward picker from SwiftData @Query
instead of AppModel's in-memory arrays; inject the per-account
ModelContext from RootView with an in-memory fallback.
- Physically delete locally deleted messages (context.delete) and
purge rows marked deleted by older builds on store open, so @Query
views never resurrect them.
- Delete the legacy JSON snapshot only after a successful import save
and restore the completeUntilFirstUserAuthentication data protection
attribute on the store file.
- Mirror the old ChatArchive tolerant decoding in LegacyArchiveImporter
so snapshots from older schema versions (missing reactions,
isGroupMessage, roster fields) still import.
- Cover the new behaviour in ArchiveStoreTests and guard it with new
verify.sh invariants; update AGENTS.md, ARCHITECTURE.md and
SECURITY.md.
thread
- Replace O(n^2) origin-id/stanza-id lookups in AppModel with hash
indexes
and stop rebuilding the whole index on every unseen stanza-id, so
archive
application no longer grows quadratically with history size.
- Run OMEMO decryption on a serial background queue instead of the main
actor, and decrypt archived stanzas in small batches with a shorter
yield,
keeping the UI responsive during large archive catch-ups.
- Show the "Синхронизация истории…" banner only for the one-page
bootstrap
window; incremental backlog catch-up continues silently in the
background.
- Fix MUC-MAM: publish decoded group mutations at the end of room
catch-up;
they were previously accumulated and then silently dropped.
- Retry a failed catch-up pass automatically (bounded) and lengthen the
query/apply timeouts so a single slow page no longer leaves history
unloaded until the next app activation.