Conversation
|
Open pull requests citing the same issues:
If one already covers this change, review or build on it instead of racing it (CONTRIBUTING.md "Overlapping work"). |
Minh3132
left a comment
There was a problem hiding this comment.
On exact head 699ff4599a1370a5ed0ebb10e70b5cbec548b38e, the new regression does not actually prove the stale-sidecar bug is fixed; it proves only that _create_gate passes False to the early check and True to the authoritative one.
test_the_early_capacity_check_cannot_persist_a_stale_namespace_rebuild monkeypatches _check_note_capacity, records the persist argument, then asserts calls == [False, True, False, True] and finally reads the resulting count. It never forces the #637 interleaving where an early rebuild snapshots N notes, a competing locked reservation advances the sidecar to N+1, and the early path resumes afterward. Because of that, an implementation could accidentally regress to _note_totals(..., persist=True) unconditionally inside _check_note_capacity while still accepting/forwarding the persist argument; this test would continue recording the same [False, True, ...] sequence and the sequential final count would still be 2, even though the original stale overwrite race had returned.
That matters because CONTRIBUTING asks regressions to pin externally observable changed behavior, and #637 already gives a deterministic interleaving recipe. Please make the test gate the early rebuild between its read and persistence, let a second create reserve/update the namespace count, then resume the early path and assert the newer sidecar is not clobbered (and ideally that the cap cannot be exceeded). That would fail for the actual old behavior and would also catch future code that merely preserves the boolean plumbing while ignoring its semantics.
|
Closing as a duplicate of #640 — both fix #637 by keeping the unlocked early capacity rebuild read-only, in Keeping #640 because it was opened first. Not a judgement on the work here: if this PR covers something #640 does not, say what on #640 and it can be carried across with credit. |
Summary
Closes #637.
Why this matters
When a namespace
.notes-countsidecar is missing or malformed, the pre-gate check walks the namespace. Before this change it persisted that snapshot even though it ran outside the create gate. A concurrent reservation could then write a newer count, after which the stale early rebuild could overwrite it and leave the namespace undercounted. Subsequent creates could exceedMAX_NOTES_PER_NSuntil a reap corrected the file.Verification
uv run pytest tests/unit/test_note_count.py -q— 33 passedgit diff --checkuv run ruff check .uv run ruff format --check .uv run ty checkuv run sz.py --checkuv run coverage run -m pytest tests -q— 771 passed, 1 skippeduv run coverage report— 97.97% total coverage