fix(selfhost): use ownership tokens for transient PR actuation locks - #2991
fix(selfhost): use ownership tokens for transient PR actuation locks#2991RealDiligent wants to merge 1 commit into
Conversation
Per-PR actuation and AI-review mutexes claimed Redis keys with a constant value and released via blind del(). A holder running past the TTL could delete a successor's live lock in finally, reopening merge/close races the mutex exists to prevent (JSONbored#2129/JSONbored#2135). Store a per-holder UUID at claim time and release with compare-and-delete (releaseIfValue) on the Redis cache adapter. Skip release when fail-open (no cache) or when the adapter lacks compare-and-delete (TTL backstop). Co-authored-by: Cursor <cursoragent@cursor.com>
|
Caution 🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥 🛑 Gittensory review result - fixes requiredReview updated: 2026-07-04 08:55:21 UTC
🛑 Suggested Action - Fix Blockers
Review summary Nits — 5 non-blocking
CI checks failing
Review context
Contributor next steps
Signal definitions
🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by Gittensory, a quiet PR intelligence layer for OSS maintainers.
|
Codecov Report❌ Patch coverage is
❌ Your patch check has failed because the patch coverage (96.15%) is below the target coverage (99.00%). You can increase the patch coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## main #2991 +/- ##
==========================================
- Coverage 96.06% 96.06% -0.01%
==========================================
Files 260 260
Lines 28687 28699 +12
Branches 10436 10439 +3
==========================================
+ Hits 27558 27569 +11
Misses 493 493
- Partials 636 637 +1
🚀 New features to boost your workflow:
|
|
Gittensory is closing this pull request on the maintainer's behalf (CI is failing (codecov/patch)). This is an automated maintenance action — to pursue this change, please open a new pull request with the issues resolved. Closed PRs may be analyzed later to improve review accuracy, but they are not automatically reopened or re-reviewed. |
Problem
Self-host PR actuation (maintenance merge/close, draft-dodge, reopen-reclose) and AI-review dedup mutexes use
SELFHOST_TRANSIENT_CACHE.claim()for atomic acquisition, but release was an unconditionaldel(). The code documented this as a KNOWN LIMITATION: if holder A runs past the TTL, holder B claims the lock, and A's stalefinallyruns, A deletes B's live lock — reopening the exact race #2129/#2135 exists to close.Root cause
claimTransientLock()stored a constant"1"andreleasePrActuationLock/releaseAiReviewLockcalled blinddel(key)with no ownership check.Solution
releaseIfValue(key, token)tocreateRedisCache(Redis Lua compare-and-delete)SELFHOST_TRANSIENT_CACHEwith optionalreleaseIfValuerandomUUID()owner tokens; release only when token still matchesownerToken: null) skip release; adapters withoutreleaseIfValuerely on TTL instead of blinddel()Testing
npm run typechecknpx vitest run test/unit/selfhost-redis-cache.test.ts(7/7)test/unit/queue.test.ts(claim/release + concurrent claim + stale-holder regression)ai-review-advisory.test.tsfor new claim return shapeCompatibility
TransientLockClaim { acquired, ownerToken }instead ofboolean(internal/test surface; all call sites updated)release*Lockfunctions take an additionalownerTokenargument