Skip to content

refactor(extension): divergence-based message writes and non-destructive DB migration#144

Merged
lcomplete merged 2 commits into
mainfrom
dev
Apr 26, 2026
Merged

refactor(extension): divergence-based message writes and non-destructive DB migration#144
lcomplete merged 2 commits into
mainfrom
dev

Conversation

@lcomplete
Copy link
Copy Markdown
Owner

Summary

  • Remove signature tracking: StoredMessageRef and StoredMessageRecord no longer carry a signature field. Change detection now compares storageKey/messageId/order to find the first divergent index in the message list, writing only records from that point onward.
  • Smarter streaming saves: for append-only updates (streaming assistant reply), only the last message record is written instead of re-hashing every message.
  • Non-destructive DB migration: the previous upgrade path deleted all stores when oldVersion < DB_VERSION. The new path calls migrateLegacySessionRecords, which reads session rows that still carry an inline messages array and rewrites them into the split sessions / session-messages / session-metadata layout, preserving all data.

Tests

  • Added createTwoTurnSession fixture helper.
  • Added test: rewrites only the divergent suffix after a history edit — verifies exactly 2 put calls when the second turn is edited.
  • Renamed test: only rewrites the latest message row on streaming saves (previously "only rewrites changed message rows on later saves").
  • Rewrote migration test: asserts that existing sessions, messages, and attachments survive the upgrade to schema v4.

Verification

cd app/extension && yarn test

…dex and non-destructive migration

- Remove signature field from StoredMessageRef/StoredMessageRecord; detect
  divergence by comparing storageKey/messageId/order instead
- On save, only write message records from the first divergent index onward
  (or just the last record for streaming appends) rather than any record
  whose JSON signature changed
- Replace the drop-all-stores upgrade path with migrateLegacySessionRecords,
  which reads existing session rows that still carry an inline messages array
  and rewrites them into the split sessions/session-messages/session-metadata
  layout without data loss
- Update tests: add createTwoTurnSession helper, add divergence-suffix test,
  rename streaming-save test, rewrite migration test to assert data is
  preserved across the upgrade
@augmentcode
Copy link
Copy Markdown

augmentcode Bot commented Apr 26, 2026

🤖 Augment PR Summary

Summary: Refactors extension session persistence to reduce IndexedDB writes and preserve data across schema upgrades.

Changes:

  • Removes message signature fields from stored session/message records and updates tests accordingly
  • Adds divergence-based persistence: detects the first differing message ref and rewrites only the divergent suffix
  • Optimizes streaming saves by writing only the most recent message row when refs are unchanged
  • Replaces the destructive “drop all stores” upgrade path with a legacy-session migration that rewrites inline messages arrays into split stores
  • Adds/updates tests for streaming-save behavior, divergent-suffix rewrites, and non-destructive migration (including attachments)

Technical Notes: Migration runs during onupgradeneeded and rebuilds sessions, session-messages, and session-metadata from legacy session rows while keeping attachment rows intact.

🤖 Was this summary useful? React with 👍 or 👎

Copy link
Copy Markdown

@augmentcode augmentcode Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed. 2 suggestions posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.

return messageRecords.slice(divergenceIndex);
}

return [messageRecords[messageRecords.length - 1]];
Copy link
Copy Markdown

@augmentcode augmentcode Bot Apr 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getMessageRecordsToPut returns only the last message when refs are unchanged, but serializeSessionAttachments() can change earlier messages (e.g., generating a new attachmentId when missing). That can leave older message rows pointing at attachment IDs that get deleted on later saves, effectively losing attachments or creating orphaned blobs.

Severity: high

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

const sessionStore = transaction.objectStore(SESSIONS_STORE);
const messageStore = transaction.objectStore(SESSION_MESSAGES_STORE);
const metadataStore = transaction.objectStore(METADATA_STORE);
const getAllSessionsRequest = sessionStore.getAll();
Copy link
Copy Markdown

@augmentcode augmentcode Bot Apr 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

migrateLegacySessionRecords only wires onsuccess for sessionStore.getAll(); if the request errors, the DB can upgrade to v4 without rewriting legacy rows, and later reads may fail due to missing messageRefs/message rows. Consider handling the error path so upgrades don’t silently produce a partially-migrated schema.

Severity: medium

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

… stable across saves

Replace crypto.randomUUID() fallback with a deterministic ID derived from
session ID, message ID, and part index. This ensures that file attachment
references remain stable when re-saving a session where only a later message
changed, preventing duplicate attachment writes.

Add test 'keeps earlier attachment refs stable when only the latest message
rewrites' to cover this behaviour.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@lcomplete lcomplete merged commit 543ae04 into main Apr 26, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant