fix(github): scope rate-limit admission checks to the caller's own bucket - #3825
Conversation
…cket (#3809) shouldWaitForGitHubRateLimit read the globally-newest REST rate-limit observation across every installation and the shared public/registry token, regardless of which bucket the caller actually draws from. Since each installation and the shared public token have separate GitHub-side REST buckets, a healthy recent observation from one bucket could mask another bucket's real exhaustion, or an exhausted recent observation from one bucket could wrongly throttle a caller whose own bucket has headroom. Add an optional admissionKey parameter to shouldWaitForGitHubRateLimit and listLatestGitHubRateLimitObservations, and thread each caller's own already-computed admission key through at every call site where one is naturally available. One call site genuinely has no installation in scope yet (a pre-dispatch scheduler check) and is left unscoped, unchanged from before -- the real per-installation check still happens downstream once a specific job is dispatched.
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3825 +/- ##
=======================================
Coverage 93.41% 93.41%
=======================================
Files 325 325
Lines 32844 32845 +1
Branches 12030 12032 +2
=======================================
+ Hits 30680 30681 +1
Misses 1530 1530
Partials 634 634
🚀 New features to boost your workflow:
|
|
Tip 🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩 ✅ Gittensory review result - approve/merge recommendedReview updated: 2026-07-06 13:31:02 UTC
✅ Suggested Action - Approve/Merge
Review summary Nits — 6 non-blocking
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.
|
Summary
shouldWaitForGitHubRateLimitread the globally-newest REST rate-limit observation across every installation and the shared public/registry token, regardless of which bucket the caller actually draws from. Every installation and the shared public token draw from DIFFERENT GitHub-side REST buckets, so this could (a) let a healthy, recently-observed OTHER bucket mask a genuinely exhausted caller bucket, or (b) let an exhausted, recently-observed OTHER bucket wrongly throttle a caller whose own bucket has plenty of headroom. This was a real contributor to today's incident, where registry/ecosystem discovery traffic (the shared public token) and installed-repo review traffic (the installation token) share this same observation table.admissionKeyparameter tolistLatestGitHubRateLimitObservationsandshouldWaitForGitHubRateLimit, scoping the read to that bucket when given (an index on(admission_key, observed_at)already existed for this — it just wasn't used).queue/processors.tssweep/regate paths (already hadinstallationId), all threegithub/backfill.tssegment/hydration paths (one already receivedadmissionKeyas an unused parameter — this was a one-line bug there specifically),upstream/commit.ts(already computes the same key for its own fetch one line below), and both message-scopedindex.tsqueue-consumer checks plusqueue/dlq.ts's redrive check (via the existinggithubRateLimitAdmissionKeyForJobhelper).index.ts's pre-dispatch scheduled-sweep-trigger throttle) has no natural single installation in scope at that point in the code (it runs before any specific repo/job is chosen) — left unscoped, preserving its exact prior behavior. This is not a correctness gap: the real per-repo/per-installation admission check still happens downstream at the now-scopedqueue/processors.tscall sites once a specific job is dispatched.Closes #3809.
Scope
type(scope): short summaryConventional Commit format, for examplefix(api): restore profile access checks.CONTRIBUTING.mdand does not reintroduce GitHub Pages, VitePress,site/, orCNAME.Validation
git diff --checknpm run actionlintnpm run typechecknpm run test:coveragelocally;codecov/patchrequires ≥99% coverage of the lines AND branches you changed (aim for 100% on your diff so CI variance does not fail near the threshold). Global coverage is a non-blocking trend with a loose 90% backstop, not the gate.npm run test:workersnpm run build:mcpnpm run test:mcp-packnpm run ui:openapi:checknpm run ui:lintnpm run ui:typechecknpm run ui:buildnpm audit --audit-level=moderateSafety
UI Evidencesection below. (N/A — no visible UI change.)Notes