Reproduction
Two snapshot callers can observe the same next counter. Threads also share the PID used in the temporary filename, so one caller can rename the other caller’s active SQLite backup. A deterministic barrier around counter selection with two real SQLite backup workers reproduces the failure and shows that each caller needs a distinct recovery slot.
Expected behavior
Claim each counter through an exclusive reservation file before copying the SQLite snapshot. Release the reservation on completion or failure; abandoned reservations consume a counter without appearing as usable backups.
The reproduction uses local files/localhost HTTP only; no model downloads or external services are involved. A focused patch and regression tests are prepared against current main.
Reproduction
Two snapshot callers can observe the same next counter. Threads also share the PID used in the temporary filename, so one caller can rename the other caller’s active SQLite backup. A deterministic barrier around counter selection with two real SQLite backup workers reproduces the failure and shows that each caller needs a distinct recovery slot.
Expected behavior
Claim each counter through an exclusive reservation file before copying the SQLite snapshot. Release the reservation on completion or failure; abandoned reservations consume a counter without appearing as usable backups.
The reproduction uses local files/localhost HTTP only; no model downloads or external services are involved. A focused patch and regression tests are prepared against current main.