Under ThreadingHTTPServer several store writers ran unlocked read-modify-write
cycles, so concurrent operator actions could silently lose each other's
updates or revert an in-flight change.
Concurrency (_write_lock; external I/O kept OUTSIDE the lock):
- record_decision now takes _write_lock so a decision isn't reverted by a
concurrent rescore/sweep.
- manual_search runs the network search first, then re-reads the submission
under the lock before the queryHistory RMW (was clobbering concurrent edits).
- _apply_provider_usage_delta merges only usage/status onto the fresh row
instead of rewriting a stale pre-search snapshot (kept an in-flight emergency
disable from being reverted).
- _sync_provider_payloads preserves an operator's disable via an
operatorDisabled flag (connectivity-only disables still reconnect).
- set_provider_enabled / emergency_disable / _sync_submission_provider_state /
collect_keyword_candidates now lock (+ single transaction where applicable).
Robustness:
- seed: a zero-byte/corrupt image now yields a 'failed' submission + audit
instead of an IndexError that aborted the whole import.
- ensure_queue: key the UPDATE/SELECT on the existing row id on a folder_path
match (was matching zero rows and returning None -> seed TypeError); audit
queue activation / legacy migration.
- store_enrichment: lastFailure uses the first failed item; auto-search dedup
reads only the submission's evidence; log a swallowed face-crop load error.
- image_store: documents the pre-existing same-stem id limitation (a prior
sibling-dependent fix was reverted — it resurrected decided submissions).
Tests: operator-disable survives reseed, usage delta keeps an in-flight
disable, seed survives an unanalyzable image, ensure_queue mismatched-id,
dismiss persistence.