go-lease-renewal-clock-drift-tolerance
The solution is complete and fully verified. Here is the summary.
~/fencelock/ — a self-contained Go 1.26 module (fencelock) implementing the lease-based distributed mutex, plus SOLUTION.md (the markdown deliverable with root-cause analysis, exact code, and verification).
| File | Role |
|---|---|
coordinator.go |
Single grant authority; fencing token incremented on every grant, not on renewal; atomic Acquire (so duplicate/concurrent grants mint exactly one token) |
holder.go |
Renewal loop with jittered exponential backoff and monotonic-time expiry; local lease shortened by MaxClockSkew so it can never outlive the coordinator fence |
resource.go |
Fenced resource — rejects any write with token <= lastAccepted, the hard mutual-exclusion guarantee |
clock.go |
Injectable clock (deterministic virtual clock in tests, monotonic time.Now in prod) |
sim_test.go / stress_test.go |
Verification suite |
SOLUTION.md |
Problem statement, root-cause analysis, full code, verification |
MinRenewLead, so a ≤2 s partition never costs the lock while a live lock is protected.-race, stable across repeated runs)--- PASS: TestConcurrentAcquireSingleWinnerPerGrant
--- PASS: TestSequentialAcquireAndStaleRenew
--- PASS: TestHolderRefusesWriteAfterMonotonicExpiry
--- PASS: TestSkewRespected
--- PASS: TestHolderSurvivesTwoSecondPartition
--- PASS: TestStressMutualExclusion # 50 seeds × 5 holders, injected skew/partitions/duplicates
PASS
ok fencelock 2.069s
The stress test constructed 50 adversarial schedules and asserted that every accepted write's fencing token is strictly increasing — i.e., no two holders ever mutated the resource under any injected schedule.
# Evidence - Problem class: go-lease-renewal-clock-drift-tolerance - Model: openrouter/deepseek/deepseek-v4-flash-0731 - Solved: 2026-08-27T16:52:40.523Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "Implement a lease-based distributed mutex where the holder must renew before expiry or lose the lock, tolerating clock drift up to 250ms between nodes and partitions up to 2s without any fencing violation (two holders ever overlapping). The renewal loop must use jittered backoff, monotonic time for expiry checks, and a fencing-token counter incremented on every grant so stale holders writes are rejected by the resource. The grader injects pauses, clock skew, and duplicate grant messages and asserts mutual exclusion under every schedule.", "environment": "go1.26", "language": "go", "model": "openrouter/deepseek/deepseek-v4-flash-0731", "problem_class": "go-lease-renewal-clock-drift-tolerance", "provider": "openrouter", "solved_at": "2026-08-27T16:52:40.523Z", "version": "1.26"}The solution is complete and fully verified. Here is the summary.
~/fencelock/ — a self-contained Go 1.26 module (fencelock) implementing the lease-based distributed mutex, plus SOLUTION.md (the markdown deliverable with root-cause analysis, exact code, and verification).
| File | Role |
|---|---|
coordinator.go |
Single grant authority; fencing token incremented on every grant, not on renewal; atomic Acquire (so duplicate/concurrent grants mint exactly one token) |
holder.go |
Renewal loop with jittered exponential backoff and monotonic-time expiry; local lease shortened by MaxClockSkew so it can never outlive the coordinator fence |
resource.go |
Fenced resource — rejects any write with token <= lastAccepted, the hard mutual-exclusion guarantee |
clock.go |
Injectable clock (deterministic virtual clock in tests, monotonic time.Now in prod) |
sim_test.go / stress_test.go |
Verification suite |
SOLUTION.md |
Problem statement, root-cause analysis, full code, verification |
MinRenewLead, so a ≤2 s partition never costs the lock while a live lock is protected.-race, stable across repeated runs)--- PASS: TestConcurrentAcquireSingleWinnerPerGrant
--- PASS: TestSequentialAcquireAndStaleRenew
--- PASS: TestHolderRefusesWriteAfterMonotonicExpiry
--- PASS: TestSkewRespected
--- PASS: TestHolderSurvivesTwoSecondPartition
--- PASS: TestStressMutualExclusion # 50 seeds × 5 holders, injected skew/partitions/duplicates
PASS
ok fencelock 2.069s
The stress test constructed 50 adversarial schedules and asserted that every accepted write's fencing token is strictly increasing — i.e., no two holders ever mutated the resource under any injected schedule.
# Evidence - Problem class: go-lease-renewal-clock-drift-tolerance - Model: openrouter/deepseek/deepseek-v4-flash-0731 - Solved: 2026-08-27T16:52:40.523Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "Implement a lease-based distributed mutex where the holder must renew before expiry or lose the lock, tolerating clock drift up to 250ms between nodes and partitions up to 2s without any fencing violation (two holders ever overlapping). The renewal loop must use jittered backoff, monotonic time for expiry checks, and a fencing-token counter incremented on every grant so stale holders writes are rejected by the resource. The grader injects pauses, clock skew, and duplicate grant messages and asserts mutual exclusion under every schedule.", "environment": "go1.26", "language": "go", "model": "openrouter/deepseek/deepseek-v4-flash-0731", "problem_class": "go-lease-renewal-clock-drift-tolerance", "provider": "openrouter", "solved_at": "2026-08-27T16:52:40.523Z", "version": "1.26"}