Skip to content

fix(github): make githubBypassResponseCache force an own network read on both legs - #10103

Merged
loopover-orb[bot] merged 1 commit into
JSONbored:mainfrom
shin-core:fix/bypass-response-cache-10032
Jul 31, 2026
Merged

fix(github): make githubBypassResponseCache force an own network read on both legs#10103
loopover-orb[bot] merged 1 commit into
JSONbored:mainfrom
shin-core:fix/bypass-response-cache-10032

Conversation

@shin-core

Copy link
Copy Markdown
Contributor

What & why

githubBypassResponseCache is documented as an absolute guarantee — "Force this request to hit GitHub instead of the persistent response cache; use for freshness/security reads." Its one production caller is fetchLiveBaseBranchAdvancedAt, the force-fresh-rebase gate's live base-tip read: a base that advanced with a non-conflicting sibling commit still reads mergeable_state: "clean", so this timestamp is the only thing that forces a rebase + CI recheck before merge. It fails open, so a wrong (stale) answer merges on a stale base.

Two legs broke the guarantee:

1. The read was routed into the volatile single-flight coalescer. In timeoutFetch, setting the flag forces cls = null — which is precisely the condition that admits a URL to the coalescer:

const cls =  !init?.githubBypassResponseCache ? githubCacheClassForUrl(url) : null;
if (method === "GET" && !conditional && cls === null && isVolatileSingleFlightEligibleGithubUrl(url, headers)) {
  return fetchWithVolatileSingleFlight(...);   // ← a bypass read joined here
}

/repos/{o}/{r}/commits/{ref} is volatile-eligible, so the bypass read joined any concurrent identical in-flight read and was answered by responseFromCached(replay, "coalesced")never issuing its own request. That is exactly the hazard the exclusion list exists for: sharing one in-flight promise's outcome (success OR a transient failure) across independent callers. A coalesced transient failure on this read means no forced rebase.

2. The 404 unauthenticated retry dropped the flag. githubJsonWithHeaders set it on the first request and re-issued without it on the public-token 404 fallback, so the read became an ordinary cacheable commit-class GET answerable from the persistent response cache — up to GITHUB_COMMIT_CACHE_TTL_SECONDS (default 15 min) of staleness — for a call whose entire purpose is liveness.

The fix

  • Leg 1: gate the volatile-single-flight branch on the flag too, the same way the cache branch already is (!init?.githubBypassResponseCache). A bypass read now goes straight to fetchWithGitHubRetry and never publishes itself into inFlightVolatileGets for another caller to replay.
  • Leg 2: the 404 retry spreads githubBypassResponseCache: true whenever the caller set bypassResponseCache, exactly as the first request spreads it.

Unchanged: the volatile path is identical for every non-bypass read (same URLs coalesce, same exclusion list, same coalesced/bypassed metrics); the 404 retry keeps its deliberate, documented githubRateLimitAdmission omission; recordGitHubResponse's bypass/replay suppression is untouched; /commits/{ref} is not added to the exclusion list (that would de-coalesce the two hourly resolveUpstreamCommitSha reads); no cache class/TTL changes.

Tests

  • github-client.test.ts — REGRESSION (named for the bug): two concurrent bypass reads for a volatile-eligible URL each issue their own fetch and neither carries the replay header; a bypass read concurrent with a non-bypass leader gets its own body, not the leader's replay; and the unchanged pin — two concurrent non-bypass reads still coalesce to one fetch with x-loopover-cache: coalesced.
  • backfill.test.ts — a bypassResponseCache call whose first (public-token) request 404s issues a second request that also bypasses the cache (a matching stale cache entry is installed and is not replayed); and the 404 retry still sends no githubRateLimitAdmission header.
  • All new tests fail on main and pass with the fix.

Validation

  • Diff coverage on src/github/client.ts and src/github/backfill.ts is 100% line and branch (both arms of the new !githubBypassResponseCache term and the bypassResponseCache ? … : {} spread).
  • npm run typecheck clean for these files (only the pre-existing missing-release-please-dep phantom in unrelated release tooling, present on bare main); the full github-client + backfill suites (212 tests) green.
  • git diff --check clean; no schema/route/env-reference/wrangler change.

Closes #10032

… on both legs

githubBypassResponseCache is documented as an absolute force-fresh guarantee, but
two legs broke it for its one production caller (fetchLiveBaseBranchAdvancedAt, the
force-fresh-rebase gate's live base-tip read):

1. timeoutFetch routed the read INTO the volatile single-flight coalescer. The flag
   forces cls=null, which is exactly the condition that admits a URL to the coalescer,
   so a bypass read joined any concurrent identical in-flight read and was answered by
   its response -- a transient failure included -- instead of issuing its own request.
   Gate the volatile branch on the flag too, the same way the cache branch already is,
   so a bypass read goes straight to the network and never publishes itself for replay.

2. githubJsonWithHeaders' 404 unauthenticated retry dropped the flag, so on that path
   the read became an ordinary cacheable commit-class GET answerable from the persistent
   response cache (up to GITHUB_COMMIT_CACHE_TTL_SECONDS stale) for a call whose whole
   purpose is liveness. Propagate the flag on the retry exactly as the first request
   spreads it; the deliberate rateLimitAdmission omission on that retry is preserved.

The volatile path is unchanged for every non-bypass read: the same URLs coalesce, the
same exclusion list applies, and the coalesced/bypassed metrics are emitted as before.

Closes JSONbored#10032
@shin-core
shin-core requested a review from JSONbored as a code owner July 31, 2026 07:03
@loopover-orb

loopover-orb Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Tip

✅ LoopOver review result - approve/merge recommended

Review updated: 2026-07-31 07:17:39 UTC

4 files · 1 AI reviewer · no blockers · readiness 98/100 · CI green · clean

✅ Suggested Action - Approve/Merge

  • safe to merge

Review summary
This PR closes two real leaks in the githubBypassResponseCache guarantee: (1) in client.ts's timeoutFetch, a bypass GET forced cls=null which is the same condition that admits a URL to the volatile single-flight coalescer, letting a liveness read be answered by another concurrent caller's in-flight result (success or transient failure) instead of its own network hit; (2) in backfill.ts's githubJsonWithHeaders, the unauthenticated 404 retry dropped the flag entirely, turning the retry into an ordinary cacheable commit-class GET that could be served stale from the persistent cache for up to 15 minutes. Both fixes are minimal, correctly traced to the actual admission conditions (the `cls === null && isVolatileSingleFlightEligibleGithubUrl` branch and the retry's options spread), and are exercised by targeted regression tests that simulate real concurrent/racing reads rather than fabricated states — the coalescing test genuinely drives two concurrent fetches through the real gate and asserts fetches===2, and the retry test installs a real response cache and asserts it's never touched. The rateLimitAdmission-omission comment is accurate and matches existing code (that flag intentionally isn't propagated on the retry, unrelated to this fix).

Nits — 4 non-blocking
  • nit: the PR description says 'Leg 1: gate the volatile-single-flight branch on the flag too' and only shows an excerpt before truncation — worth confirming the full description covers Leg 2 (the 404 retry) explicitly for future readers of the merged PR, though the diff itself makes the intent clear.
  • nit: test/unit/backfill.test.ts's cache-bypass regression test asserts `cacheGet` was never called but doesn't also assert `cache.set` wasn't called on the successful second response — worth covering both cache-write and cache-read non-interaction for full confidence in the bypass guarantee.
  • Consider adding a one-line comment at the `githubBypassResponseCache` field definition in client.ts pointing to the two enforcement sites (the cls computation and the volatile-single-flight gate) so a future change to either doesn't silently reopen this exact gap again.
  • The retry propagation in backfill.ts only forwards `bypassResponseCache`, not `rateLimitAdmissionKey` — that's called out as deliberate in the comment, but consider a short unit test asserting that admission key truly stays absent even when the original call passed one with `bypassResponseCache: true` together, to lock in the interaction between the two flags.

Decision drivers

  • ✅ Code review — No blockers (1 reviewer)
  • ✅ Gate result — Passing (No configured blocker found.)
Context & advisory signals — never blocks the verdict
Signal Result Evidence
Linked issue ✅ Linked #10032
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: 65 registered-repo PR(s), 50 merged, 0 issue(s).
Contributor context ✅ Confirmed Gittensor contributor shin-core; Gittensor profile; 65 PR(s), 0 issue(s).
Improvement ✅ Minor risk: clean · value: minor · LLM: moderate
Linked issue satisfaction

Addressed
The diff gates the volatile single-flight branch on `!init?.githubBypassResponseCache` exactly as required, and propagates `githubBypassResponseCache: true` on the 404 unauthenticated retry in `githubJsonWithHeaders` while leaving the rate-limit-admission omission untouched, matching both Requirements bullets precisely. Tests cover both legs (coalescer bypass and 404 retry cache-bypass) plus a reg

Review context
  • Author: shin-core
  • Role context: outside_contributor
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: TypeScript, JavaScript, Solidity, Dart, Python, CSS, PHP, Rust
  • Official Gittensor activity: 65 PR(s), 0 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Keep the PR focused and include validation evidence before maintainer review.
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.
🧪 Chat with LoopOver

Ask LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.

  • @loopover ask <question> answers contribution-quality Q&A with source citations and freshness.
  • @loopover chat <question> answers in natural prose from cached decision-pack facts via local inference (maintainer/collaborator; read-only).
  • A plain-language @loopover mention with a real question is routed to the closest matching read-only command automatically — no exact syntax required.

Full command reference: https://loopover.ai/docs/loopover-commands

🧪 Experimental — new and may change.

🟩 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 LoopOver, a quiet PR intelligence layer for OSS maintainers.

  • Re-run LoopOver review

@superagent-security

Copy link
Copy Markdown
Contributor

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

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

codecov Bot commented Jul 31, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 80.23%. Comparing base (3b2dd1e) to head (d67ba99).
⚠️ Report is 5 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #10103      +/-   ##
==========================================
+ Coverage   79.75%   80.23%   +0.48%     
==========================================
  Files         282      284       +2     
  Lines       58685    60405    +1720     
  Branches     6878     7549     +671     
==========================================
+ Hits        46804    48466    +1662     
- Misses      11593    11600       +7     
- Partials      288      339      +51     
Flag Coverage Δ
backend 96.62% <100.00%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/github/backfill.ts 96.04% <100.00%> (ø)
src/github/client.ts 99.64% <100.00%> (ø)

@loopover-orb loopover-orb Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LoopOver approves — the gate is satisfied and CI is green.

@loopover-orb
loopover-orb Bot merged commit b900ef0 into JSONbored:main Jul 31, 2026
8 checks passed
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.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

github(client): make githubBypassResponseCache actually force an own network read instead of coalescing or falling back into the cache

1 participant