Skip to content

orb(anti-abuse): contributor-cap-lock TTL (30s) is far shorter than the work it guards — reopens the #7284 TOCTOU #9024

Description

@JSONbored

CONTRIBUTOR_CAP_LOCK_TTL_SECONDS = 30 (src/queue/transient-locks.ts ~170) was sized for the executor's pre-merge recheck, which holds it around a single contributorCapMergeRecheck() call (agent-action-executor.ts ~572-590).

But maybeCloseForContributorCapOnOpen holds the same lock across a much longer body (src/queue/processors.ts ~2770-2853): token mint, isBelowAccountAgeThreshold, resolvePerRepoContributorCapMatch (GitHub calls), ensurePullRequestLabel, then the nested pr-actuation-lock and the full executeAgentMaintenanceActions (live-CI recheck + GitHub close).

Under GitHub rate-limit backoff that body exceeds 30s → Redis expires the lock while the holder is still inside the executor → a concurrent sibling PR's cap check (or the executor's pre-merge recheck) acquires it and evaluates the author's open-PR count before the in-flight close lands. Both act: a double cap-close, or a merge that pushes the author over cap — precisely the TOCTOU #7284 added this lock to close.

Fix

Either raise the cap-lock TTL to cover the early-close path (~600s, matching pr-actuation-lock), or stop holding it across the executor — hold it for the decision only and let the executor's own pre-merge cap recheck be the serialization point.

Metadata

Metadata

Assignees

Labels

maintainer-onlyOwner-only work — yields no Gittensor points.orbGittensory Orb related - maintainer self-hosting analytics.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions