⚠️ Definition of Done: this issue must be completed in full, in a single PR. Do not split this
work across multiple PRs, and do not defer any Deliverable below to a follow-up issue. A PR that
satisfies only some of the Deliverables, stubs a required test, or leaves a checkbox
partially-done does NOT resolve this issue and will be closed.
Context
src/env.d.ts:73-75 carries a standing TODO for "a per-PR LOCK Durable Object (SubmissionLock mutex)... deliberately NOT declared in this chunk." The per-PR actuation mutex (guarding maintenance sweep / draft-dodge-close / reopen-reclose racing on the same PR) is currently a "lightweight interim mutex" (src/queue/transient-locks.ts:1-16) built on a fail-open cache primitive, used at src/queue/processors.ts:2443. This is real, acknowledged deferred work with no tracking issue found in the current open backlog.
Requirements
Implement SubmissionLock as a Durable Object class with its own migration tag in wrangler.toml/wrangler.jsonc, and wire claimTransientLock/releaseTransientLockIfOwner call sites in transient-locks.ts to prefer it when available, falling back to the current cache-based mutex for self-host installs without Durable Objects.
Deliverables
All of the above Deliverables are required in the same PR unless the deliverable text itself states otherwise.
Test Coverage Requirements
src/** -- 99%+ patch coverage, branch-counted, on both the Durable Object implementation and the fallback path. All four Deliverables are required in the same PR.
Expected Outcome
The per-PR actuation mutex is backed by a real, strongly-consistent Durable Object where available, closing the acknowledged gap between the documented SubmissionLock design and the current best-effort cache mutex, while preserving self-host compatibility.
Links & Resources
src/env.d.ts:73-75
src/queue/transient-locks.ts:1-16
src/queue/processors.ts:2443
Context
src/env.d.ts:73-75carries a standing TODO for "a per-PR LOCK Durable Object (SubmissionLockmutex)... deliberately NOT declared in this chunk." The per-PR actuation mutex (guarding maintenance sweep / draft-dodge-close / reopen-reclose racing on the same PR) is currently a "lightweight interim mutex" (src/queue/transient-locks.ts:1-16) built on a fail-open cache primitive, used atsrc/queue/processors.ts:2443. This is real, acknowledged deferred work with no tracking issue found in the current open backlog.Requirements
Implement
SubmissionLockas a Durable Object class with its own migration tag inwrangler.toml/wrangler.jsonc, and wireclaimTransientLock/releaseTransientLockIfOwnercall sites intransient-locks.tsto prefer it when available, falling back to the current cache-based mutex for self-host installs without Durable Objects.Deliverables
SubmissionLockDurable Object class implementing the per-PR mutex, with its ownwrangler.toml/wrangler.jsoncmigration tagtransient-locks.ts'sclaimTransientLock/releaseTransientLockIfOwnerprefer the Durable Object when available, falling back to the existing cache-based mutex otherwiseAll of the above Deliverables are required in the same PR unless the deliverable text itself states otherwise.
Test Coverage Requirements
src/**-- 99%+ patch coverage, branch-counted, on both the Durable Object implementation and the fallback path. All four Deliverables are required in the same PR.Expected Outcome
The per-PR actuation mutex is backed by a real, strongly-consistent Durable Object where available, closing the acknowledged gap between the documented
SubmissionLockdesign and the current best-effort cache mutex, while preserving self-host compatibility.Links & Resources
src/env.d.ts:73-75src/queue/transient-locks.ts:1-16src/queue/processors.ts:2443