Vector Chunk Upserts Can Collide Across Tenants Or Sources
Bug
Chunk creation currently generates content_id from title, content, and chunk index. The async chunker then upserts vector entries by content_id.
Because content_id is not tenant-scoped or source-scoped, two tenants or two sources with identical title/content/chunk index can collide.
Impact
A chunk row can be moved or overwritten across tenants/sources during indexing. That risks incorrect retrieval results, wrong source attribution, and cross-tenant data corruption.
Current Status
Still open. Recent cleanup did not change chunk identity, vector-entry upsert keys, or database uniqueness constraints. This should be solved with the source replacement/versioning work rather than as a standalone quick patch.
This was re-raised in the follow-up Copilot review as the vector content_id collision issue.
Proposed Solution
Make vector chunk identity source-scoped.
Recommended future shape:
- Use
knowledge_source_id + chunk_indexas the upsert identity for chunks created from a source. - Generate
content_idwith tenant/source identity included, or treat it as an external identifier rather than the primary upsert key. - Add a test where two tenants upload identical content and receive distinct vector rows.
- Add a test where two sources in the same tenant upload identical content and remain distinct.
This should be handled together with the source replacement and cleanup refactor so old chunks are not accidentally left active.