Context
Phase 5 Community Detection (epic #1222, issue #1228) relies on the extraction_count metadata value to trigger periodic community detection.
Problem
The extraction counter increment in semantic.rs uses two separate SQL statements:
INSERT INTO graph_metadata ... ON CONFLICT DO NOTHING
UPDATE graph_metadata SET value = CAST(CAST(value AS INTEGER) + 1 AS TEXT)
This is not atomic — under concurrent access, two tasks could both execute the INSERT (one succeeds, one is no-op) then both UPDATE. SQLite WAL serializes writers so double-increment is unlikely in practice, but the pattern depends on SQLite serialization guarantees.
Suggested Fix
Merge into a single atomic statement:
INSERT INTO graph_metadata (key, value) VALUES ('extraction_count', '1')
ON CONFLICT(key) DO UPDATE SET value = CAST(CAST(value AS INTEGER) + 1 AS TEXT)
This is atomic in SQLite and eliminates the two-statement pattern.
Source
PERF-04 from Phase 5 performance analysis.
Context
Phase 5 Community Detection (epic #1222, issue #1228) relies on the extraction_count metadata value to trigger periodic community detection.
Problem
The extraction counter increment in
semantic.rsuses two separate SQL statements:INSERT INTO graph_metadata ... ON CONFLICT DO NOTHINGUPDATE graph_metadata SET value = CAST(CAST(value AS INTEGER) + 1 AS TEXT)This is not atomic — under concurrent access, two tasks could both execute the INSERT (one succeeds, one is no-op) then both UPDATE. SQLite WAL serializes writers so double-increment is unlikely in practice, but the pattern depends on SQLite serialization guarantees.
Suggested Fix
Merge into a single atomic statement:
This is atomic in SQLite and eliminates the two-statement pattern.
Source
PERF-04 from Phase 5 performance analysis.