← All needs

Restarting the worker during a Chroma rebuild re-embeds every document the interrupted run already wrote

## Before submitting - [x] I searched [existing issues](https://github.com/thedotmack/claude-mem/issues) and confirmed this is not a duplicate ### Bug Description When the worker restarts in the middle of a local Chroma rebuild, the project that was being rebuilt starts again from row zero, and every document it had already written is embedded a second time. On a large project that is tens of thousands of embeddings of pure waste, with `chroma-mcp` at 100% CPU and the document count not moving. ### Cause Two things combine: 1. For a project with `rebuildPending`, `ChromaSync` calls `ChromaSyncState.resetForRebuild(project)` at the start of every backfill run (`src/services/sync/ChromaSync.ts`, around the "Rebuilding project from SQLite after a corrupt collection was dropped" log), and `finishRebuild` only runs when the project completes. The reset is there on purpose (#4818: live writes can bump the watermark while the project waits). The side effect is that a restart mid-project replays every row the interrupted run already wrote. 2. Those replayed rows collide on their deterministic IDs. The duplicate path in `addDocuments` fetches the existing IDs and sends them to `chroma_update_documents` with `documents`, so Chroma computes the embedding again even though the text is identical to what is stored. ### Steps to Reproduce 1. Local Chroma mode with a project large enough that its rebuild takes a few minutes. Empty `~/.claude-mem/chroma` (or a dropped collection) so the project gets `rebuildPending`. 2. Let the backfill write part of the project, then restart the worker. 3. The log shows the project starting again at `watermark=0`, followed by many `Batch reconciled via in-place update + add after duplicate conflict {updated=N, added=0}`, while the collection count does not grow. From my machine (15.7.0): the project had been backfilling for two hours and stopped on shutdown with `lastRowId=30972, remainingRows=593` of 4,061 observations, 24,402 embeddings already stored. After the restart: `Backfilling observations {missing=4061, pending=0, watermark=0, total=4061}` and only in-place updates for the next stretch. Any restart during a long rebuild does this: plugin update, crash, sleep, a version mismatch recycle. ### Expected Behavior Rows that are already indexed with the same text are not embedded again. Changed text still updates in place, and new IDs are still added. ### Proposed fix Keep the #4818 reset as it is, and make the duplicate path cheap: fetch the stored text with the existing IDs, send `documents` only for IDs whose text changed, and refresh the metadata alone for the rest (`chroma_update_documents` with only `metadatas` does not re-embed). I have a small PR ready with tests. ### Environment - **Claude-mem version**: main at 70aa40042 (15.7.0) - **OS**: macOS (the sync logic is the same on every OS)