fix(desktop): harden conversation reconciliation#7210
Conversation
Greptile SummaryThis PR hardens desktop conversation reconciliation by extracting match logic into a shared
Confidence Score: 4/5The reconciliation hardening is solid and well-tested; the only concerns are logging inconsistencies that could mislead future debugging but do not affect correctness. The core session-guard and queue-filter logic is correct and covered by new tests. Two logging issues exist: finishSession's success message still fires on the skipped path because the return exits only the db.write closure, and the Waiting for API reconciliation message in AppState fires even when targetSessionId is nil. Neither affects data or session state. TranscriptionStorage.swift (finishSession log) and AppState.swift (else-branch diagnostic log) are the two spots worth a second look before merging. Important Files Changed
|
| } else { | ||
| didBindLocalSession = false | ||
| if memoryId != "?" { | ||
| if let startTime = targetStartTime, | ||
| let memoryStartedAt = DesktopConversationMatchPolicy.parseMemoryEventDate( | ||
| memory?["started_at"] ?? memory?["startedAt"]) { | ||
| let delta = abs(memoryStartedAt.timeIntervalSince(startTime)) | ||
| if delta >= DesktopConversationMatchPolicy.startedAtTolerance { | ||
| log("Transcription: Ignoring memory_created event; started_at delta \(String(format: "%.1f", delta))s exceeds session match tolerance") | ||
| } | ||
| } | ||
| log("Transcription: Waiting for API reconciliation before binding memory_created \(memoryId) to a local session") | ||
| } | ||
| } |
There was a problem hiding this comment.
When
targetSessionId is nil (no finished session was captured before this event), the "Waiting for API reconciliation" message still logs unconditionally. There is no pending session to reconcile, so the message implies a state that doesn't exist and will confuse log-based debugging.
| } else { | |
| didBindLocalSession = false | |
| if memoryId != "?" { | |
| if let startTime = targetStartTime, | |
| let memoryStartedAt = DesktopConversationMatchPolicy.parseMemoryEventDate( | |
| memory?["started_at"] ?? memory?["startedAt"]) { | |
| let delta = abs(memoryStartedAt.timeIntervalSince(startTime)) | |
| if delta >= DesktopConversationMatchPolicy.startedAtTolerance { | |
| log("Transcription: Ignoring memory_created event; started_at delta \(String(format: "%.1f", delta))s exceeds session match tolerance") | |
| } | |
| } | |
| log("Transcription: Waiting for API reconciliation before binding memory_created \(memoryId) to a local session") | |
| } | |
| } | |
| } else { | |
| didBindLocalSession = false | |
| if memoryId != "?" { | |
| if let startTime = targetStartTime, | |
| let memoryStartedAt = DesktopConversationMatchPolicy.parseMemoryEventDate( | |
| memory?["started_at"] ?? memory?["startedAt"]) { | |
| let delta = abs(memoryStartedAt.timeIntervalSince(startTime)) | |
| if delta >= DesktopConversationMatchPolicy.startedAtTolerance { | |
| log("Transcription: Ignoring memory_created event; started_at delta \(String(format: "%.1f", delta))s exceeds session match tolerance") | |
| } else { | |
| log("Transcription: Waiting for API reconciliation before binding memory_created \(memoryId) to a local session") | |
| } | |
| } else if targetSessionId == nil { | |
| log("Transcription: No pending finished session; memory_created \(memoryId) will be picked up by API reconciliation") | |
| } else { | |
| log("Transcription: Waiting for API reconciliation before binding memory_created \(memoryId) to a local session") | |
| } | |
| } | |
| } |
Summary
Addresses #6418.
Related to #6952.
Desktop reconciliation could still regress a local transcription session after the backend had already associated it with a conversation. This hardens the client-side path by:
memory_createdevents to the session captured before rotationNo matching desktop conversation found on backendFiles touched
desktop/Desktop/Sources/AppState.swiftdesktop/Desktop/Sources/TranscriptionRetryService.swiftdesktop/Desktop/Sources/Rewind/Core/TranscriptionModels.swiftdesktop/Desktop/Sources/Rewind/Core/TranscriptionStorage.swiftdesktop/Desktop/Tests/StopReconciliationTests.swiftdesktop/Desktop/Tests/TranscriptionSessionRecordTests.swiftTest plan
xcrun swift test --package-path Desktop --filter StopReconciliationTestsxcrun swift test --package-path Desktop --filter TranscriptionSessionRecordTestsgit diff --check