Skip to content

Concurrent knowledge ingests bypass deduplication and record stale version metadata #317

Description

@Calmingstorm

Failure scenarios

Concurrent identical sources bypass document dedup

  1. Start with an empty knowledge store.
  2. Concurrently call KnowledgeStore.ingest("same content", "source-a") and KnowledgeStore.ingest("same content", "source-b").
  3. Both calls return 1 and list_sources() contains both sources, even though sequential ingestion rejects the second document as an exact duplicate.

The exact- and near-duplicate queries run before either caller acquires the write lock, so both callers observe an empty store. The lock serializes only the later delete/write/version block and cannot restore the promised deduplication invariant.

Concurrent updates use stale version metadata

  1. Start with an empty knowledge store.
  2. Concurrently ingest different content under the same source name.
  3. Both calls return success, but both version rows are recorded with action = "create" and diff_summary = "initial version"; the second committed version should be an update with a diff against the version it replaced.

Each caller reads old_content and computes is_update before entering the write lock. The second caller therefore records metadata from a state that ceased to be current before its write began.

Sites

  • src/knowledge/store.py:190-221 performs document deduplication outside the write lock.
  • src/knowledge/store.py:223-225 captures the old source content and update/create decision outside the write lock.
  • src/knowledge/store.py:241-257 serializes only the destructive write and then records version metadata derived from the stale pre-lock read.

Expected result

Make deduplication and the old-version read/decision part of the same serialized transaction as replacement, so each successful ingest validates against the state immediately preceding its own commit and records truthful version metadata.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions