Skip to content

fix(pr-pipeline): plan refire-refused's job-token client to github-token - #10842

Merged
kyle-sexton merged 3 commits into
mainfrom
fix/refire-refused-job-token-margin
Oct 29, 2026
Merged

kyle-sexton merged 3 commits into
mainfrom
fix/refire-refused-job-token-margin

Conversation

@kyle-sexton

Copy link
Copy Markdown
Member

Refs: #10811

Summary

#10811 set API_BUDGET_TOKEN: lanes-app on pr-merge's Re-fire step, pr-merge.yml:1729, which is right for its GH_TOKEN (lane token) client. The rate guard also plans each client's read floor from the limits.api entry its token names: entryOf and margin in rate-guard.mjs, used in observe. So refire-refused's ACTIONS_TOKEN (job token) client used lanes-app's entry and lost github-token's 1000 limit-cap. Its read-floor warning then planned to the header's 5000 instead of 1000. This was the side effect the security review flagged as P5. Before #10811, that step named no bucket and the client planned to github-token.

Fix

  • refire-refused builds its job-token client through actionsClient, pinned with budgetLatch("github-token"). Its readings and its read-floor plan are the job token's, and it shares the process latch's stops.
  • budgetLatch moves into rate-guard.mjs, beside the latch it wraps. label-unblocked, its first user, re-exports it.
  • The ci: count every GitHub request the Node clients send, GraphQL split out #10811 changelog fragment's "No request changes" now names this side effect and its fix. The fragment is unreleased.

Hold path: refire-refused.mjs and rate-guard.mjs are on the hold list, so the owner approves the merge. No secret, token or permission changes.

Verification

  • New refire-refused.test.mjs case, run with API_BUDGET_TOKEN=lanes-app: the job-token client's reading lands in api-budget/github-token and none in lanes-app. Its read-floor warning plans to github-token's cap: 950 of 5000 used leaves "50 of the planned 1000". That value is computed by hand from rate-limits.json, where lanes-app's uncapped plan would leave 4050 and give no warning.
  • Mutation check: unpinning the client (latch in place of budgetLatch("github-token", latch)) fails the test.
  • Not covered by a test: main building its client through actionsClient, since every main test injects actions.
  • node --test on the pr-merge, work-unblock and log-api-budget suites: 976 pass, 0 fail.

Related

🤖 Generated with Claude Code

kyle-sexton and others added 2 commits October 28, 2026 22:12
#10811 named lanes-app as the Re-fire step's API_BUDGET_TOKEN, which is
right for its GH_TOKEN client. The rate guard also plans each client's
read floor to the entry its token names (entryOf), so the ACTIONS_TOKEN
client lost github-token's 1000 limit-cap. Pin that client to
github-token with budgetLatch, now exported by rate-guard.mjs beside the
latch it wraps (label-unblocked re-exports it), and correct the
changelog's "No request changes".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-29T03:50:08.736017Z 9b1be9f Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

claude-review reviewed e9d73286e06d2317772d26ae23de5b8801ee5401: 0 finding(s), 0 as inline comments.

No findings. I read the full diff and the PR context, and checked the changed code against rate-guard.mjs, check-trusted-trigger.mjs, the test file's imports, and every budgetLatch call site.

  • budgetLatch move. It now lives in rate-guard.mjs beside the latch it wraps. label-unblocked.mjs imports it and re-exports it, so the existing import in label-unblocked.test.mjs and the use at line 1791 still resolve. The function body is unchanged.
  • actionsClient in refire-refused.mjs. It passes latch: budgetLatch("github-token", latch) to createGitHub, which calls latch.guard(fetchImpl) (check-trusted-trigger.mjs:174). The pinned guard forwards { token } to countRequests and observe. observe uses that token for margin and entryOf, so the read-floor plan comes from the github-token entry. That matches the PR's claim. The conditional spread of fetchImpl leaves createGitHub's default in place when no fetchImpl is injected.
  • Test. The imports resolve: readFileSync and join are already imported at the top of the test file, and lib/test-tmp.mjs exists at the repo root, which is where ../../../lib/test-tmp.mjs points. The test restores RUNNER_TEMP and API_BUDGET_TOKEN and removes its temp dir in finally. I did not run it. The "976 pass" result and the mutation check come from the PR author and are unverified by me. I also did not check the hand-computed 50 of 1000 floor against rate-limits.json.
  • Trusted paths. refire-refused.mjs and rate-guard.mjs match the trusted-path list, so I read their whole changes. The change adds no token, secret or permission handling beyond choosing which budget bucket the existing job-token client reports under. The pr-merge.yml step is untouched.
  • Cost. No billing change. Request counts are unchanged, as the changelog fragment says.
  • Closing issue. The PR says "Refs: ci: count every GitHub request the Node clients send, GraphQL split out #10811", so no closing-issue section exists to check criteria against.
  • Gap the PR admits. main building its client through actionsClient has no test, because every main test injects actions. This is a one-line call to a function that is tested, so I did not flag it.

@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

claude-security-review reviewed e9d73286e06d2317772d26ae23de5b8801ee5401: 0 finding(s), 0 as inline comments.

No security issues found in this change.

critical-findings: 0

What I read: the full diff and the PR context. I also checked rate-guard.mjs (entryOf, margin, observe, guard) and createGitHub in check-trusted-trigger.mjs.

Trusted paths touched: rate-guard.mjs and refire-refused.mjs.

  • rate-guard.mjs: the change adds budgetLatch. It wraps latch.guard so the client's readings and limits.api plan (read floor, limit cap) use the named token's entry. That is its only effect. Stops stay shared through the spread latch. The function is moved over unchanged from label-unblocked.mjs, which now re-exports it.
  • refire-refused.mjs: the job-token client is now built by actionsClient, which pins the budget bucket to github-token. The token (env.ACTIONS_TOKEN), the API URL and the requests are unchanged. No token scope, permission, trusted-actor check, kill switch or merge-hold logic is touched. merge-holds.mjs is only imported for its login constant, as before.
  • Effect on the rate guard: the read-floor plan for that client goes back to github-token's 1000 limit-cap. That restores the earlier plan. It does not widen anything.
  • Test and changelog: the new test and the changelog edit add nothing to the attack surface. The test changes process.env only inside a try/finally that restores it.

Manifests: no plugin manifests changed.
Instruction surfaces: no standing instructions were deleted or softened.

Spend: none. This only changes how API calls are counted and planned.

@kyle-sexton
kyle-sexton added this pull request to the merge queue Oct 29, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Oct 29, 2026
Lane-Activity: pr-unblock/resolve-conflicts
@kyle-sexton
kyle-sexton added this pull request to the merge queue Oct 29, 2026
Merged via the queue into main with commit 444d3de Oct 29, 2026
40 checks passed
@kyle-sexton
kyle-sexton deleted the fix/refire-refused-job-token-margin branch October 29, 2026 05:32
@github-actions

Copy link
Copy Markdown
Contributor

Post-merge mutation testing

Killed 1, survived 0, timeout 0, no coverage 0, invalid 0, not run 5.
Covered-code score 100%; mutation score 100%.

File Killed Survived Timeout No coverage Invalid Not run
.github/actions/log-api-budget/rate-guard.mjs 0 0 0 0 0 2
.github/scripts/pr-merge/refire-refused.mjs 0 0 0 0 0 3
.github/scripts/work-unblock/label-unblocked.mjs 1 0 0 0 0 0

The run's summary has the full report.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant