Skip to content

fix(review): record getAppInstallation calls in the shared rate-limit store (#4506)#4580

Merged
JSONbored merged 1 commit into
mainfrom
fix/installation-health-rate-limit-observation-4506
Jul 10, 2026
Merged

fix(review): record getAppInstallation calls in the shared rate-limit store (#4506)#4580
JSONbored merged 1 commit into
mainfrom
fix/installation-health-rate-limit-observation-4506

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Summary

  • Records getAppInstallation's response into the D1-persisted rate-limit observation store (recordGitHubRateLimitObservation) so refreshInstallationHealthRecords's per-installation loop is actually visible to shouldWaitForGitHubRateLimit, the same admission check every comparable background job already feeds.
  • The call is deliberately NOT threaded through timeoutFetch's githubRateLimitAdmission/githubRateLimitAdmissionKey options: that option pair also drives the GET response-cache key, and installation:{id} collides across different calling Apps for the same installation id, which would have broken this endpoint's existing per-App-identity cache isolation (#1940). Recorded directly instead, mirroring backfill.ts's recordGitHubResponse header-parsing logic inline (backfill.ts already imports getAppInstallation from this module, so the reverse import would cycle).
  • Corrects the stale index.ts:163-164 comment that called refresh-installation-health a "cheap single-call health job."

Closes #4506.

Scope

  • The PR title follows type(scope): short summary Conventional Commit format.
  • This PR is focused and does not mix unrelated backend, UI, MCP, docs, dependency, and deploy changes.
  • This follows CONTRIBUTING.md and does not reintroduce GitHub Pages, VitePress, site/, or CNAME.
  • I linked a currently open issue this PR resolves (Closes #4506).

Validation

  • git diff --check
  • npm run actionlint
  • npm run typecheck
  • npm run test:coverage locally — new/changed lines and branches in src/github/app.ts are 100% covered (confirmed via isolated --coverage run against test/unit/github-app.test.ts, zero uncovered lines in the changed range).
  • npm run test:workers
  • npm run build:mcp
  • npm run test:mcp-pack
  • npm run ui:openapi:check
  • npm run ui:lint
  • npm run ui:typecheck
  • npm run ui:build
  • npm audit --audit-level=moderate
  • New or changed behavior has unit/integration tests for new branches, fallback paths, and sanitizer boundaries — invariant test (D1 recording) + regression test (large-N-installation fixture, zero fetches when the shared budget is exhausted), both empirically verified to fail without their respective fixes and pass with them.

Safety

  • No secrets, wallet details, hotkeys, coldkeys, user PATs, private keys, raw trust scores, private rankings, or private maintainer evidence are exposed.
  • Public GitHub text stays sanitized, low-noise, and does not imply compensation guarantees or optimization tactics.
  • Auth, cookie, CORS, GitHub App, Cloudflare, or session changes include negative-path tests. (N/A — no auth/cookie/CORS surface touched; the App-JWT cache-isolation regression this PR avoided is covered by the existing #1940 test, re-verified green.)
  • API/OpenAPI/MCP behavior is updated and tested where needed. (N/A — no API/OpenAPI/MCP surface changed.)
  • UI changes use live API data or real empty/error/loading states, not production mock/demo fallbacks. (N/A — no UI changes.)
  • Visible UI changes include a UI Evidence section below. (N/A — backend-only change, no visible UI.)
  • Public docs/changelogs are updated where needed; changelogs are only edited for release-prep PRs. (N/A)

Notes

  • While rebasing onto latest main, initially suspected a main-red typecheck break from the just-merged miner-hands PR (#4576) — turned out to be a stale local packages/gittensory-engine/dist build artifact (gitignored, untracked) left over from before the rebase, not a real regression. Rebuilt locally and confirmed clean; no fix needed on main.

@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@codecov

codecov Bot commented Jul 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.88889% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 94.12%. Comparing base (d4e2464) to head (0054bbd).
⚠️ Report is 2 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/github/app.ts 88.88% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4580      +/-   ##
==========================================
- Coverage   94.12%   94.12%   -0.01%     
==========================================
  Files         430      430              
  Lines       38155    38163       +8     
  Branches    13912    13915       +3     
==========================================
+ Hits        35913    35920       +7     
  Misses       1585     1585              
- Partials      657      658       +1     
Files with missing lines Coverage Δ
src/github/backfill.ts 97.16% <ø> (ø)
src/index.ts 95.45% <ø> (ø)
src/github/app.ts 97.87% <88.88%> (-0.31%) ⬇️
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@loopover-orb loopover-orb Bot added the gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. label Jul 10, 2026
@loopover-orb

loopover-orb Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Caution

🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥

🛑 Gittensory review result - fixes required

Review updated: 2026-07-10 05:30:44 UTC

5 files · 1 AI reviewer · no blockers · readiness 100/100 · CI failing · blocked

🛑 Suggested Action - Manual Review

  • Touches a guarded path — held for manual review: This PR changes guardrail-protected path(s): src/github/app.ts (matched src/github/app.ts), src/github/backfill.ts (matched src/github/backfill.ts).

Review summary
This PR records getAppInstallation's response headers into recordGitHubRateLimitObservation, closing the visibility gap that let refresh-installation-health's per-installation GitHub calls bypass shouldWaitForGitHubRateLimit. It deliberately avoids threading the call through timeoutFetch's admission-key option to prevent a cache-key collision across Apps (documented against #1940), instead mirroring backfill.ts's inline recording pattern to sidestep a circular import. The end-to-end regression test in index.test.ts convincingly proves the whole job now pre-yields under an exhausted budget, and the new github-app.test.ts case confirms the observation is actually written with the right admissionKey and header values.

Nits — 7 non-blocking
  • src/github/app.ts: recordGitHubRateLimitObservation is awaited before the `!response.ok` check, so a D1 write failure would throw and mask what should be a clean 'installation fetch failed (status)' error — this mirrors backfill.ts's existing convention (perf(selfhost): tune Postgres autovacuum and batch the rate-limit observation writes #2543), so confirm that's the intended tradeoff rather than an oversight.
  • test/unit/github-app.test.ts: the new INVARIANT test only exercises the finite/present branch of the x-ratelimit-reset ternary and the finite branch of parseNullableRateLimitHeader — verify an existing test elsewhere in the file covers the missing/non-numeric header case, since that's a live branch on the changed lines.
  • src/github/app.ts:383: confirm githubRateLimitAdmissionKeyForInstallation is already imported/defined in this file — it isn't shown being added in the diff's import hunk, so it should already exist, but worth a quick check.
  • src/github/app.ts and src/github/backfill.ts are both flagged as long files (425 and 4448 lines) by the size checker — not actionable here, but a candidate for a future split if backfill.ts keeps growing.
  • Add a test exercising a non-2xx (rate-limited) response from GitHub to explicitly prove the 'recorded before the ok-check' claim in the code comment, since the current INVARIANT test only covers the 200 path.
  • PR author also opened the linked issue — Link an issue that was opened by a different contributor, or provide a rationale for why this self-authored issue represents genuine discovery work.
  • Touches a guarded path — held for manual review — A maintainer must review and merge this change.

CI checks failing

  • validate
  • validate-code
Signal Result Evidence
Code review ✅ No blockers 1 reviewer
Linked issue ✅ Linked #4506
Related work ✅ No active overlap found No same-issue or scoped active PR overlap found.
Change scope ✅ 20/20 Low review scope from cached public metadata (1 linked issue).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 48 registered-repo PR(s), 40 merged, 353 issue(s).
Contributor context ✅ Confirmed Gittensor contributor JSONbored; Gittensor profile; 48 PR(s), 353 issue(s).
Gate result ⚠️ Not blocking Advisory; not blocking this PR.
Linked issue satisfaction

Addressed
The PR records getAppInstallation's response headers directly into the shared rate-limit observation store (with a documented rationale for not reusing the timeoutFetch admission-key option due to a cache-collision conflict), adds both an invariant test confirming the observation is recorded and a regression test showing the whole job pre-yields with zero fetches when the budget is exhausted, and

Review context
  • Author: JSONbored
  • Role context: owner (maintainer lane)
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: not available
  • Official Gittensor activity: 48 PR(s), 353 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Treat this as maintainer-lane context rather than normal contributor-lane activity.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Change scope = cached public metadata such as size labels, draft state, and review-burden hints.
  • Validation posture = whether the PR provides enough public validation/test evidence for maintainer review.
  • Contributor workload = public contributor activity and cleanup pressure, not a repo-wide quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.

🟩 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.

  • Re-run Gittensory review

@loopover-orb loopover-orb Bot added the manual-review Gittensor contributor context label Jul 10, 2026
… store (#4506)

refreshInstallationHealthRecords makes one real GitHub REST call per
installation via getAppInstallation, but that call never fed the
D1-persisted rate-limit observation store shouldWaitForGitHubRateLimit
reads for queue-dequeue admission -- only #4505's job-level throttle
protected it, with no visibility into its own consumption.
@JSONbored
JSONbored force-pushed the fix/installation-health-rate-limit-observation-4506 branch from 36574d1 to 0054bbd Compare July 10, 2026 05:46
@JSONbored
JSONbored merged commit 19c0910 into main Jul 10, 2026
7 checks passed
@JSONbored
JSONbored deleted the fix/installation-health-rate-limit-observation-4506 branch July 10, 2026 05:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. manual-review Gittensor contributor context

Development

Successfully merging this pull request may close these issues.

fix(queue): refresh-installation-health loops per-installation with no GitHub-budget rate-limit admission

1 participant