Summary
save_compression_guidelines in crates/zeph-memory/src/sqlite/compression_guidelines.rs:63-74 uses a read-then-write pattern across two separate transactions to compute the next version number:
let (current_version, _) = self.load_compression_guidelines().await?;
let new_version = current_version + 1;
sqlx::query("INSERT INTO ... VALUES (?, ?, ?)").bind(new_version)...
The schema has no UNIQUE(version) constraint, so two concurrent callers would both insert version=2 silently.
Fix
Use INSERT INTO compression_guidelines SELECT COALESCE(MAX(version),0)+1, ... FROM compression_guidelines to compute and insert in a single atomic statement, or add a UNIQUE(version) constraint to the schema.
Notes
Only one background updater calls this in practice, so the race is unlikely. This is a correctness gap, not a live incident.
Identified by code reviewer (REVIEW-4) during ACON compression guidelines PR (#1647) review.
Summary
save_compression_guidelinesincrates/zeph-memory/src/sqlite/compression_guidelines.rs:63-74uses a read-then-write pattern across two separate transactions to compute the next version number:The schema has no
UNIQUE(version)constraint, so two concurrent callers would both insertversion=2silently.Fix
Use
INSERT INTO compression_guidelines SELECT COALESCE(MAX(version),0)+1, ... FROM compression_guidelinesto compute and insert in a single atomic statement, or add aUNIQUE(version)constraint to the schema.Notes
Only one background updater calls this in practice, so the race is unlikely. This is a correctness gap, not a live incident.
Identified by code reviewer (REVIEW-4) during ACON compression guidelines PR (#1647) review.