Apple/Web Message Processing Parity
Apple/Web Message Processing Parity Status: Linux static audit Created: 2026-06-01 Scope: user message persistence, assistant message persistence, message ve...
[T:documentation.sender_name]
Apple/Web Message Processing Parity
Status: Linux static audit
Created: 2026-06-01
Scope: user message persistence, assistant message persistence, message versions, deletion cleanup
Goal
Apple must preserve the same message lifecycle as web: a user message is locally visible and persisted immediately, assistant responses stream and then persist, messages_v tracks server-authoritative versions, and refresh/cold boot restores all messages.
Web Source
frontend/apps/web_app/tests/message-sync.spec.tsfrontend/packages/ui/src/services/chatSyncServiceHandlersAI.tsfrontend/packages/ui/src/services/chatSyncServiceHandlersCoreSync.tsfrontend/packages/ui/src/services/chatSyncMerge.tsfrontend/packages/ui/src/types/chat.ts
Apple Source
apple/OpenMates/Sources/Core/Models/ChatModels.swiftapple/OpenMates/Sources/Core/Persistence/ChatStore.swiftapple/OpenMates/Sources/Core/Persistence/OfflineStore.swiftapple/OpenMates/Sources/Core/Persistence/OfflineSyncBridge.swiftapple/OpenMates/Sources/Core/Networking/WebSocketManager.swiftapple/OpenMates/Sources/Features/Chat/ViewModels/ChatViewModel.swiftapple/OpenMates/Sources/Features/Chat/Views/ChatView.swift
Web Contract From Specs
- After sending first prompt and receiving response, IndexedDB has at least 2 messages: 1 user and 1 assistant.
- After sending the second user prompt, the second user message is persisted before the assistant response arrives.
- Final state has at least 4 messages: 2 user and at least 2 assistant messages.
messages_vis greater than or equal to message count and never zero once messages exist.- Reloading the page and returning to the chat restores all messages.
- Deleting the chat removes the active chat item.
Confirmed Apple Behavior From Source
Messagedecodes both camelCase and snake_case fields for IDs, encrypted content, timestamps, app ID, streaming state, embed refs, and model name.ChatStore.appendMessageupserts by message ID, updates in-memory state, and persists throughOfflineSyncBridge.ChatStore.setMessagessorts bycreatedAtand persists.ChatStore.updateMessageupdates content while preserving encrypted content, app ID, embed refs, and model name.OfflineStore.persistMessagesBatchupserts persisted messages by ID for a chat.ChatStore.makeSyncClientStateincludesmessages_vfor server diffing.- Offline send queues a
send_messagepending action and immediately appends a local user message.
Likely Gaps To Verify Or Fix
Messagelacks several web-side fields visible intypes/chat.ts, including status-like fields used by tests (status), highlight metadata, and richer attachment/embed metadata. Confirm whether Apple intentionally computes these elsewhere or needs model expansion.PersistedMessage.toMessagealways returnsisStreaming: false, so app relaunch cannot represent an interrupted/in-progress stream. Confirm desired behavior for background or interrupted AI responses.- Apple
Chatcurrently lacksunread_count, parent/sub-chat fields, hidden/private fields beyond persistence-onlyisPrivate, and some metadata present in web sync types. These may affect message list parity and cross-device state. messages_vis stored onChat, but static audit did not prove it is updated after every local/remote message event. Verify with Mac tests.- Deletion cleanup in
ChatStore.removeChatremoves in-memory messages and callsOfflineSyncBridge.onChatDeleted, but parity for message-level delete/highlight events needs a separate audit.
Testability IDs Needed
new-chat-buttonmessage-editormessage-usermessage-assistantchat-context-deletechat-item-wrapperalready exists
Mac Verification Checklist
- Send two sequential user messages in the same chat and confirm both appear before/after assistant responses.
- Relaunch the app and confirm all messages remain present.
- Compare Apple chat message count and roles against web for the same chat.
- Verify
messages_vis sent in the next phased sync request after message changes. - Delete the test chat and confirm it disappears locally and does not reappear after sync.
First Implementation Tasks
- Add missing message test identifiers in Apple chat UI.
- Audit Apple message model fields against
frontend/packages/ui/src/types/chat.tsand backend payloads. - Add an Apple UI/integration test plan mirroring
message-sync.spec.ts.