Fix #69: atomic concurrent Star #70

Merged
crueber merged 1 commit from fix/issue-69 into main 2026-09-04 23:29:00 +00:00
Owner

Same-principal concurrent Star double-counted in the post-recreate zero window (record-Create winner's +1 plus a late observer's resync +1 from a separate pre-read). Fix: resync decision folded into the counter CAS loop + leaf per-Service gate serializing Star's record-to-counter mutation. Single-call semantics unchanged. Proved: new deterministic TestStarConcurrentResyncConverges fails on base (8 for 1), TestStarConcurrentConverge + resync pass -race -count=20, coverage 99.5%. Fixes #69.

Same-principal concurrent Star double-counted in the post-recreate zero window (record-Create winner's +1 plus a late observer's resync +1 from a separate pre-read). Fix: resync decision folded into the counter CAS loop + leaf per-Service gate serializing Star's record-to-counter mutation. Single-call semantics unchanged. Proved: new deterministic TestStarConcurrentResyncConverges fails on base (8 for 1), TestStarConcurrentConverge + resync pass -race -count=20, coverage 99.5%. Fixes #69.
Same-principal concurrent Star double-counted in the post-recreate zero
window: the record-Create winner's +1 plus a late observer's resync +1
fired from a separate pre-read (check-then-act across two CAS windows;
TestStarConcurrentConverge flaked 3-4 instead of 2).

- reconcileStar now decides inside the counter CAS loop (absent/zero => one
  +1, nonzero => as-is, corrupt => 0 no-write); retries re-check.
- Star's record->counter mutation serializes on a leaf per-Service gate
  (channel semaphore, no new imports; Star-only, defer-released).
- Single-call semantics unchanged (idempotent re-Star, unstar floor 0,
  #63 lazy tolerance). Doc: 07 §4 concurrency line + Decisions entry.
Sign in to join this conversation.
No description provided.