●BILLING — 1 day to the Jun 15 change: Agent SDK, headless runs, GitHub Actions, and third-party agents move to separate monthly credits ($20/$100/$200) metered at full API rates, no rollover●FABLE5 — Claude Fable 5, a Mythos-class model billed as Anthropic's most capable generally available release, is usable in Claude Code v2.1.170+ (launched Jun 9)●SUBAGENTS — Claude Code sub-agents can now spawn their own sub-agents, with smarter model and region handling●ENTERPRISE — Custom roles gain admin permissions, letting members reach billing and privacy settings without Owner access●PLUGINS — New plugin search plus better Chrome, VSCode, and terminal workflows; session, memory, and permission bugs fixed●UI — New setting disables mouse-wheel scroll acceleration in fullscreen; the /model picker now shows model families correctly●BILLING — 1 day to the Jun 15 change: Agent SDK, headless runs, GitHub Actions, and third-party agents move to separate monthly credits ($20/$100/$200) metered at full API rates, no rollover●FABLE5 — Claude Fable 5, a Mythos-class model billed as Anthropic's most capable generally available release, is usable in Claude Code v2.1.170+ (launched Jun 9)●SUBAGENTS — Claude Code sub-agents can now spawn their own sub-agents, with smarter model and region handling●ENTERPRISE — Custom roles gain admin permissions, letting members reach billing and privacy settings without Owner access●PLUGINS — New plugin search plus better Chrome, VSCode, and terminal workflows; session, memory, and permission bugs fixed●UI — New setting disables mouse-wheel scroll acceleration in fullscreen; the /model picker now shows model families correctly
Before Per-PR CI Burns Through Your Monthly Credits: A Three-Layer Guard for Claude Code GitHub Actions
From June 15, Claude Code GitHub Actions bills against non-rolling monthly credits. Run a review on every PR and you can drain the month in the first week. Here is a three-layer guard — when to run, how heavy one run can get, and making spend visible — with working workflows.
Early in June I was scrolling the morning notifications and noticed my credit balance had already dropped below half. The month was three days old. The cause was easy to spot: the night before, twelve dependency-update PRs had landed at once, and the code-review workflow had fired on every single one of them.
As an indie developer I keep several app repositories, and I wire Claude Code review into their CI. Until now that ran inside my subscription, so I never watched the run count closely. The billing change on June 15 removes that cushion. Here are the three layers of guards I added to keep CI running while bringing the spend back under control — with the workflows that actually run.
What Changes on June 15: CI Leaves the Subscription
From June 15, 2026, the Claude Agent SDK, headless claude -p, Claude Code GitHub Actions, and third-party agents move onto monthly credits that sit outside your subscription limit. Credits are granted per plan (roughly $20 / $100 / $200 worth), consumed at the full API rate, and — critically — they do not roll over.
That last property is the one that bites. Leaving credits unused at month end is a loss, but spending them all in the first week means no automated CI review for the rest of the month. Under the subscription, "running too often" was still flat-rate; from now on, every run carves directly into the pool.
Boiled down, credit spend is a product of two things:
How many runs fired — how often the workflow started
How heavy each run was — tokens read and written per run
The first number was what had broken. In my repos, review fired on both on: pull_request and on: push, and it covered everything without exception — bot dependency PRs, docs-only edits, even draft PRs. Fewer than half of the monthly CI starts were meaningful as human code review.
The second can't be ignored either. A refactor PR with several thousand changed lines loads the whole diff into context, costing tens of times the tokens of a normal run. Even after trimming the count, one "heavy run" like that can take a big bite out of the month.
So I worked in this order: cut the count with run conditions (layer 1), cap how heavy one run can be (layer 2), and make spend visible (layer 3).
✦
Thank you for reading this far.
Continue Reading
What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.
WHAT YOU'LL LEARN
✦Cut roughly 60% of the CI runs that were burning your monthly credits in the first week, using path/label/draft run conditions — without losing any human-facing review coverage
✦Build a diff-size and token ceiling into the workflow so a single massive PR can no longer swallow a large slice of the month's credits
✦Log each run's token spend to the job summary so you can decide, mid-month, how many runs you have left in plain numbers
Secure payment via Stripe · Cancel anytime
✦
Unlock This Article
Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.
Layer 1: When to Run — Trim the Count with Conditions
The biggest win was narrowing the trigger itself. This lives entirely on the GitHub Actions side and filters before Claude is ever called, so any PR dropped here spends zero tokens.
I added four conditions. First, drop the push trigger and consolidate on pull_request. Second, exclude changes that touch only non-code paths (docs, config). Third, skip draft PRs and PRs opened by bots. Fourth, use concurrency to cancel an in-flight review when a newer commit lands on the same PR.
name: claude-reviewon: pull_request: types: [opened, ready_for_review, synchronize] paths: - "src/**" - "app/**" - "lib/**" - "**/*.ts" - "**/*.tsx" - "**/*.swift" - "**/*.kt"# When a newer commit lands on the same PR, cancel the in-flight reviewconcurrency: group: claude-review-${{ github.event.pull_request.number }} cancel-in-progress: truepermissions: contents: read pull-requests: writejobs: gate: runs-on: ubuntu-latest # Skip draft PRs, bot PRs, and anything labeled [skip-ai] if: >- github.event.pull_request.draft == false && github.actor != 'dependabot[bot]' && github.actor != 'renovate[bot]' && !contains(github.event.pull_request.labels.*.name, 'skip-ai') outputs: proceed: ${{ steps.size.outputs.proceed }} steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - id: size name: Gate on diff size run: | BASE="${{ github.event.pull_request.base.sha }}" HEAD="${{ github.event.pull_request.head.sha }}" CHANGED=$(git diff --numstat "$BASE" "$HEAD" -- \ ':(exclude)**/*.lock' ':(exclude)**/*.snap' \ | awk '{added+=$1; removed+=$2} END {print added+removed}') echo "changed lines: ${CHANGED:-0}" # Skip review on huge PRs over 1500 lines (nudge a human to split it) if [ "${CHANGED:-0}" -gt 1500 ]; then echo "proceed=false" >> "$GITHUB_OUTPUT" else echo "proceed=true" >> "$GITHUB_OUTPUT" fi
For pull_request events, the paths filter checks whether any changed file matches, so a docs-only PR never starts the job at all. Keeping a manual skip-ai label lets a human opt out of PRs they already know don't need review.
Those four conditions alone cut my monthly CI starts by about 60%. Almost all of the drop was "bot dependency updates" and "small pushes to drafts" — the human review experience lost nothing.
Layer 2: How Heavy One Run Can Get — Diff and Model Ceilings
Trimming the count still leaves you exposed if a surviving run is heavy. In layer 2 I set two ceilings per run.
The first is the diff-size ceiling already in the gate job above. PRs over 1,500 lines aren't reviewed; instead they get a single comment asking for a split. Huge PRs also produce weaker reviews, so nudging a split is the rational call on both cost and quality grounds.
review: needs: gate if: needs.gate.outputs.proceed == 'true' runs-on: ubuntu-latest permissions: contents: read pull-requests: write steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Claude Code review uses: anthropics/claude-code-action@v1 with: anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} # Pin the model explicitly so an implicit upgrade to a higher tier # does not quietly melt credits claude_args: "--model claude-sonnet-4-6 --max-turns 6" prompt: | Review only the diff of this PR. There is no need to explore the whole repo. Limit your focus to three things — clear bugs, security concerns, and breaking changes — and quote the relevant lines for each finding, concisely. If there are no issues, reply with just "LGTM". too-large: needs: gate if: needs.gate.outputs.proceed == 'false' runs-on: ubuntu-latest permissions: pull-requests: write steps: - name: Ask for a split uses: actions/github-script@v7 with: script: | await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, body: "This PR is large, so automated review was skipped. Splitting it to under 1,500 lines helps both review quality and CI cost." });
The second is pinning the model. If a subagent or a fallback quietly steps up to a higher tier, the same task melts credits differently. In CI I recommend naming a model that balances accuracy and cost with --model rather than leaving it to auto-upgrade. Adding a --max-turns ceiling also stops a runaway loop from spiraling.
How to fix the model from the admin side with enforceAvailableModels is covered in pinning the served model with enforceAvailableModels. Reach for that when you want to bind local developer runs alongside CI.
Telling the prompt to "look at the diff only, focus on three points" is also a cost measure. Letting it explore the whole repository sends tokens soaring, so CI review deliberately narrows what it reads.
Layer 3: Keep Each Run's Spend Where You Can See It
Even with count and ceiling in place, you can't judge "how many runs are left" mid-month if you can't see what you're actually spending. In layer 3 I logged each run's spend to the job summary.
Claude Code Action prints token usage to the run log. Pull that out and write it to GitHub's $GITHUB_STEP_SUMMARY, and per-PR spend stays visible on the Actions screen.
- name: Record token spend to the summary if: always() run: | # Extract input/output tokens from the latest run log (adjust to the output shape) IN=$(grep -oE '"input_tokens":[0-9]+' claude-output.json | grep -oE '[0-9]+' | paste -sd+ | bc) OUT=$(grep -oE '"output_tokens":[0-9]+' claude-output.json | grep -oE '[0-9]+' | paste -sd+ | bc) # Rough cost in USD at Sonnet-class rates (swap in your own rates) # Assume input $3 / output $15 per MTok COST=$(echo "scale=3; ${IN:-0}/1000000*3 + ${OUT:-0}/1000000*15" | bc) { echo "### Claude review spend" echo "- input tokens: ${IN:-0}" echo "- output tokens: ${OUT:-0}" echo "- approx cost: about \$${COST}" } >> "$GITHUB_STEP_SUMMARY"
Once the numbers are on screen, the feel of operating CI changes immediately. In my case a single PR review lands around $0.15 to $0.30, and gating out the huge PRs showed up as a real number. If spend runs over plan in the first half of the month, I can tighten the skip-ai label policy temporarily — a decision I make from the numbers.
The thinking behind smoothing that spend across the month — not draining it early, not wasting it late — is in burn-rate pacing for non-rolling monthly credits. Read it as the sequel for distributing credits across your whole automation, not just CI.
The Fork-PR Credit Trap
One production caveat worth sharing. On fork PRs from outside contributors, the pull_request event does not pass secrets. That means ANTHROPIC_API_KEY is empty and the review job fails.
Switching to pull_request_target "because it doesn't run" is dangerous. pull_request_target handles the fork's code while holding the base repository's permissions and secrets, which is the classic path for a malicious PR to exfiltrate them. I personally don't run automated review on external PRs; I run it through a trusted workflow only when a maintainer adds a label.
gate: # Only PRs within my own repo, or those explicitly approved by label if: >- github.event.pull_request.head.repo.full_name == github.repository || contains(github.event.pull_request.labels.*.name, 'ai-review-approved')
For repositories shipping apps to the App Store and Google Play, mishandling secrets can lead all the way to a leaked signing key. Loosening security to save credits is backwards, so I deliberately err on the strict side here.
What the Numbers Showed, and the Next Step
After the three layers, the first month cut CI starts by about 60% and brought credit spend into a range I could predict to month end. Every PR that needed review was still covered; what disappeared was the bot and draft noise. Gating the huge PRs also made the maximum spend per run legible.
If you're starting from scratch, I'd put in the layer-1 gate job first. The four points — paths, the draft check, the bot exclusion, and concurrency — live entirely on the GitHub Actions side and stop wasted starts without calling Claude at all. Visibility and model pinning can follow, one at a time. I hope this helps anyone running CI solo or in a small team avoid the early-month scramble.
Share
Thank You for Reading
Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.