Severity: HIGH
Location: src/queue/processors.ts:12517
Found via a full-system adversarial audit of the ORB review/scoring engine (2026-07-15) — 2 independent skeptic passes, both had to vote "confirmed" for this to survive.
Failure scenario
maybeThrottleLoopOverCommand (src/queue/processors.ts:12465-12560) builds targetKey = ${repoFullName}#${issueNumber}#${command}`` (line 12482) and counts prior invocations with countRecentAuditEventsForActorAndTarget(env, commenter, COMMAND_RATE_LIMIT_EVENT_TYPE, targetKey, sinceIso) (line 12517) — an exact-targetKey match, so the count resets to 0 the moment a NEW issue/PR number appears in targetKey. With commandRateLimitPolicy:"hold" and commandRateLimitAiMaxPerWindow:5, an actor invokes an AI-cost-bearing `@loopover ask ...` 5 times on issue #100 (hits the hold on the 6th), then simply comments the same command on any other open issue/PR (or opens a brand-new issue, which is free and instant) — targetKey becomes `owner/repo#101#ask`, the counter is 0/5 again, and the actor gets another full budget. This repeats indefinitely across every thread in the repo, so the configured window/max are not an effective ceiling on the actor's total AI-cost-bearing invocations. maybeThrottleIntentRouting (lines 12575-12616) has the identical pattern at line 12600.
Impact
Defeats the anti-abuse/cost-containment purpose of commandRateLimitPolicy for both the general per-command limiter and the intent-classification router, allowing unbounded paid-AI-review invocation volume from a single actor. This is not a design choice: the sibling review-nag feature had the SAME per-target scoping originally, and commit a697e20 'fix(review): scope review-nag ping cooldown to the actor, not one PR (#4021)' (2026-07-07) explicitly fixed it to use the repo-wide countRecentAuditEventsForActorInRepo (now used at src/queue/processors.ts:12153) specifically because 'a contributor who exhausts a cooldown on PR A' could 'reset to a clean slate simply by opening a fresh PR B' (repositories.ts:2886-2893 doc comment). maybeThrottleLoopOverCommand was created 5 days EARLIER (commit 4b9fe18, 2026-07-02) by generalizing review-nag's ORIGINAL (pre-fix) per-target pattern, and was never updated when the fix landed; maybeThrottleIntentRouting was added even later (commit f8f281b, after the #4021 fix) and still copied the vulnerable pattern. Confirmed still present in current HEAD by direct read of processors.ts.
Severity: HIGH
Location:
src/queue/processors.ts:12517Found via a full-system adversarial audit of the ORB review/scoring engine (2026-07-15) — 2 independent skeptic passes, both had to vote "confirmed" for this to survive.
Failure scenario
maybeThrottleLoopOverCommand (src/queue/processors.ts:12465-12560) builds
targetKey =${repoFullName}#${issueNumber}#${command}`` (line 12482) and counts prior invocations withcountRecentAuditEventsForActorAndTarget(env, commenter, COMMAND_RATE_LIMIT_EVENT_TYPE, targetKey, sinceIso)(line 12517) — an exact-targetKey match, so the count resets to 0 the moment a NEW issue/PR number appears in targetKey. With commandRateLimitPolicy:"hold" and commandRateLimitAiMaxPerWindow:5, an actor invokes an AI-cost-bearing `@loopover ask ...` 5 times on issue #100 (hits the hold on the 6th), then simply comments the same command on any other open issue/PR (or opens a brand-new issue, which is free and instant) — targetKey becomes `owner/repo#101#ask`, the counter is 0/5 again, and the actor gets another full budget. This repeats indefinitely across every thread in the repo, so the configured window/max are not an effective ceiling on the actor's total AI-cost-bearing invocations. maybeThrottleIntentRouting (lines 12575-12616) has the identical pattern at line 12600.Impact
Defeats the anti-abuse/cost-containment purpose of commandRateLimitPolicy for both the general per-command limiter and the intent-classification router, allowing unbounded paid-AI-review invocation volume from a single actor. This is not a design choice: the sibling review-nag feature had the SAME per-target scoping originally, and commit a697e20 'fix(review): scope review-nag ping cooldown to the actor, not one PR (#4021)' (2026-07-07) explicitly fixed it to use the repo-wide countRecentAuditEventsForActorInRepo (now used at src/queue/processors.ts:12153) specifically because 'a contributor who exhausts a cooldown on PR A' could 'reset to a clean slate simply by opening a fresh PR B' (repositories.ts:2886-2893 doc comment). maybeThrottleLoopOverCommand was created 5 days EARLIER (commit 4b9fe18, 2026-07-02) by generalizing review-nag's ORIGINAL (pre-fix) per-target pattern, and was never updated when the fix landed; maybeThrottleIntentRouting was added even later (commit f8f281b, after the #4021 fix) and still copied the vulnerable pattern. Confirmed still present in current HEAD by direct read of processors.ts.