Skip to content

fix(core): guard concurrent local document sidecar acceptance #1530

Description

@phernandez

Problem

The local document importer in #1529 checks sidecar provenance and source generation before writing, but those checks are separate from filesystem replacement. Two concurrent-write edge cases remain:

  1. A user edits an existing sidecar (or creates a file at a previously absent sidecar path) after the last check and before FileService.write_file() replaces it. The unconditional replacement can discard those canonical bytes.
  2. Import A checks source generation A, then pauses. The source changes and import B accepts generation B. When A resumes, it can recognize B's sidecar as an untouched generated projection and replace it with generation A. Indexing and the watcher do not rerun extraction, so another import is needed to repair it.

Atomic file replacement does not make the preceding checksum check atomic with replacement.

Scope and decision

Follow-up to #1529, deferred by the maintainer so the Office/CSV ingestion work can land. Keep the current ordinary refresh behavior in that PR. This issue tracks stronger acceptance semantics; it does not claim the existing preflight checks provide compare-and-swap.

Review evidence:

Acceptance criteria

  • Define the supported concurrency boundary explicitly, including separate importer processes and external editors; a process-local lock alone does not protect arbitrary editor writes.
  • Preserve user-created or edited canonical sidecar bytes when they arrive between validation and acceptance, or use a documented conflict-preserving behavior when a platform cannot provide conditional replacement.
  • An older extraction cannot roll back a sidecar already accepted from a newer source generation; it must conflict or no-op.
  • Add deterministic interleaving tests for edit-before-replace, create-before-first-write, and old-import-after-new-import acceptance, including Windows filesystem behavior.
  • Preserve run-ledger provenance and normal unchanged-import reuse/source-change refresh. Avoid wider database locking for derived index state.

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

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions