Repository navigation
ci: count every GitHub request the Node clients send, GraphQL split out - #10811
Conversation
The rate guard's reading recorder (rate-guard.mjs) becomes countRequests, a count-only fetch wrapper the guard and every client factory send their attempts through. A fetch that already counts is marked and not wrapped twice. A request whose token is not the step's own GH_TOKEN (else GITHUB_TOKEN) counts under API_BUDGET_OVERRIDE_TOKEN, as babysit_gh.py does, so the job token's calls in a lanes App step are no longer counted as lanes-app. Newly counted: the address-feedback client in its select, fix-ci-context and review-dependency mains (loaded at run time, so the directory-copy script activities still load), the dispatch and feedback-dispatch factories' own fetch, pr-verify's job-log read, and three Node steps that named no bucket. The api-calls notice adds graphql=K. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…quests Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| GitGuardian id | GitGuardian status | Secret | Commit | Filename | |
|---|---|---|---|---|---|
| 39229828 | Triggered | Generic CLI Secret | e39b4f9 | plugins/developer-experience/evals/sources/harness/score-deterministic.py | View secret |
🛠 Guidelines to remediate hardcoded secrets
- Understand the implications of revoking this secret by investigating where it is used in your code.
- Replace and store your secret safely. Learn here the best practices.
- Revoke and rotate this secret.
- If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.
To avoid such incidents in the future consider
- following these best practices for managing and storing secrets including API keys and other credentials
- install secret detection on pre-commit to catch secret before it leaves your machine and ease remediation.
🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
claude-security-review reviewed No security findings in PR #10811 at head e39b4f9. critical-findings: 0 I read the whole diff (19 files) and the PR context. I checked the trusted-path files and what they gate:
|
|
claude-review reviewed Code review: no findingsI read the full diff ( What I checked
Manifests: the diff changes no Closing issue: none. The PR says "No related issue", so there are no acceptance criteria to check. The PR body says the "~10%" criterion from #10765 is not met by this PR alone. That is a stated scope limit, not a defect. Embedded instructions in PR text: none found. Spend: none. This change adds no paid plan, billing setting or billed resource. The PR names itself as touching hold-list paths and needing the owner's merge approval, and that is a merge-gate matter, not a cost hold. |
Post-merge mutation testingKilled 1, survived 0, timeout 0, no coverage 0, invalid 0, not run 6.
The run's summary has the full report. |
No related issue: measured uncounted GITHUB_TOKEN spend, the Node half of #10765 (counted 1,359 against the header's 4,000 used for the 22:55-23:55Z pool-B hour)
Summary
Every GitHub request a lane script's Node client sends now reaches the job-end
api-callsnotice. #10765 did this forgh.The premise this started from was off:
onResponsenever did the counting. EverycreateGitHubrequest already went through the rate guard (retryServerErrors→latch.guard→recordReading), which records a reading whenever the step names a bucket inAPI_BUDGET_TOKEN. The real gaps were these:createGitHubApi, used by its select main, fix-ci-context and review-dependency. These jobs setAPI_BUDGET_TOKEN: github-tokenand still counted 0. Also the dispatch and feedback-dispatch factories when not handedbudgetedFetch, and pr-verify's raw job-log read.CHECKS_TOKENand verify reader. That was pool-B traffic showing up in the other pool.Call sites counted, of the 49
createGitHub/createGitHubApicalls: 43 before (given a bucket), 46 now, plus pr-verify's log read. The three steps above now name their bucket, and the second-token clients in 5 pr-merge steps move to github-token.Fix
rate-guard.mjscountRequests(fetch)keeps each answer's reading and changes nothing else: no latch and no retry. The guard sends through it, and so do the factories that never had the guard. A fetch that already counts carries a mark (countsRequests) and is not wrapped again, sobudgetedFetchand guarded fetches handed to a factory are counted once.budgetToken: a pinned token wins. Otherwise a request whose bearer is not the step's own token (GH_TOKEN, elseGITHUB_TOKEN) counts underAPI_BUDGET_OVERRIDE_TOKEN, the rulebabysit_gh.pyalready applies to gh calls. Otherwise it counts underAPI_BUDGET_TOKEN. Without an override set, nothing moves..github/actions. SocountedFetch()loads the recorder at run time, and only the three base-run mains call it. The copy-run scripts stay uncounted. They also run on the lane token in a job with no bucket.safeToResend,Connection: close, attempt timeouts and caps. Merging them would change request behavior.api-callsnow ends ingraphql=K, the GraphQL requests among N, which spend GraphQL's own pool. Comparing N with the core header'susedtherefore needs K subtracted. A reading'sresourcegives K, and the gh wrapper writesrequest graphqlfor a/graphqlrequest. The first field is unchanged.Hold paths: rate-guard.mjs, request-budget.mjs, address-feedback.mjs, fix-ci-context.mjs, feedback-dispatch.mjs, pr-merge.yml and pr-require-checks.yml are on the hold list, so this needs the owner's merge approval. No secret, token or permission changes. The new env lines only name counting buckets.
Verification
log-api-budget/count-requests.test.mjs(11 tests). One reading per request throughcreateGitHub, address-feedback (each attempt, a resent 500 included), dispatch, and feedback-dispatch, raw and handedbudgetedFetch(once, not twice). Override bucketing: GH_TOKEN, then GITHUB_TOKEN as own, and no override means no move. The three mains count one reading per stubbed request.resolve-pr.test.mjs: one reading per API request, the log's 302 among them, and none for the storage read.log-api-budget.test.mjs:pr viewwith one GraphQL and one REST request givesgithub-token=2 graphql=1, and a header-readgh api graphqlgivesgraphql=1.pr-merge/workflow.test.mjs: a step that holds both tokens and builds a client must namelanes-appand thegithub-tokenoverride.countedFetch, thebudgetedFetchmark, the guard's recording, idempotence, the override rule, the own-token rule, resolve-pr's wrap (and counting the storage read), both graphql markers, and Re-fire's override env..githubnode suite: 4,584 tests. After installing resolve-config's locked deps, the 21 that had failed for a missingajv/yamlpass.scripts/ci-gh-read.test.shPASS=40,scripts/ci-rerun-ci-status.test.shPASS=157. shellcheck onapi-budget.bashand actionlint on the three workflows are clean.Not met by this PR alone: the ~10% criterion. The uncounted volume in that hour sits mostly elsewhere: 30 runs of pr-review-hosted and pr-review-security-hosted posted no notice, and the jobs newly counted here ran a handful of times.
Owner merge decision
Q14, 2026-10-29: merge at
e39b4f91ce6184682f3cf4f8f4cda49385b46ef6now, and fix the security review's one P5 finding in a follow-up PR (option A). The owner's answer, verbatim: "yes". That finding: refire-refused'sAPI_BUDGET_TOKEN: lanes-appalso moves the job-token client's margin entry. The follow-up pins that client togithub-tokenand corrects the changelog's "No request changes" line. The independent security review found no HIGH or CRITICAL.Related
fetchGitHub(raw fetch), after fix(pr-pipeline): end designed stops cleanly and keep held pull requests out of the merge queue #10737 merges.🤖 Generated with Claude Code