Actions budget
Actions budget
Section titled “Actions budget”
node ~/.claude/scripts/fleet/actions-budget.js probetells you how much of an account’s GitHub Actions minutes are spent before the spending limit stops every job. When the limit is reached, each job dies at startup and nothing says why (todo #1648). This probe turns that into a figure you see in advance (#1695, cap #1690).
A run that has already died at startup is reported by the CI locus resolver as “jobs never started” (CI Locus, #1731). This page covers the forward-looking half: how close the account is.
The record
Section titled “The record”One record per repo owner (bob-actions-budget/1):
| Key | Meaning |
|---|---|
owner |
The account, lower-cased. |
kind |
user or org, whichever endpoint answered; null when neither did. |
verdict |
ok, warn, over, unknown or unavailable (below). |
used_minutes |
Actions minutes used this billing cycle (billing endpoint) or this calendar month (usage report). |
included_minutes |
The plan’s included minutes; from the billing endpoint, else BOB_ACTIONS_INCLUDED_MINUTES, else null. |
paid_minutes / net_amount |
Minutes or charges past the included quota this period. |
pct |
used_minutes ÷ included_minutes, one decimal; null without a quota. |
warn_pct |
The warn threshold applied. |
source |
billing-actions or usage-report. |
reason, fix |
Why the verdict is not ok/warn, and the command or setting that fixes it. |
checked_at |
When the API was read (a cached answer keeps its time and adds cached: true). |
| Verdict | Meaning |
|---|---|
ok |
Below the warn threshold. |
warn |
At or above BOB_ACTIONS_WARN_PCT (default 80) of the included minutes. |
over |
The included minutes are spent (pct ≥ 100, or paid minutes or a net charge this period). Jobs now run against the spending limit and die at startup when it is reached. |
unknown |
Minutes are measured but the quota is not known. The usage report does not carry it, so set BOB_ACTIONS_INCLUDED_MINUTES. |
unavailable |
Not measured. The token cannot read billing, or the API failed. The caller never fails because of it, and it is never treated as ok. |
What it reads
Section titled “What it reads”For each owner it tries the users/ endpoints and then the orgs/ endpoints:
GET /{users|orgs}/<owner>/settings/billing/actionsreturns the included minutes and the minutes used this cycle.GET /{users|orgs}/<owner>/settings/billing/usage?year=&month=, the enhanced-billing usage report. Only rows with productactionsand unit minutes are summed.
Scope. A user’s billing needs a token with the user scope. A default
gh auth login token does not have it, so the verdict is unavailable with
the fix gh auth refresh -h github.com -s user. A scope refusal settles the
answer for that owner after one call, because the other endpoint needs the
same scope. An organization’s billing needs an owner or billing-manager token.
Cache. Each answer is kept in $BOB_HOME/.actions-budget.json for
BOB_ACTIONS_BUDGET_TTL_MIN minutes (default 360), and that includes an
unavailable answer. A snapshot therefore costs at most two gh calls per
owner a few times a day. A cached figure is re-graded on every read, so a new
warn threshold takes effect at once. --fresh bypasses the cache.
Where it is shown
Section titled “Where it is shown”- Fleet snapshot.
summary.actions_budgetis{verdict, warn_pct, owners[]}, one record per distinct owner of this machine’s projects, taken from each project’srepo.verdictis the worst one. It isnullwhen no project has a GitHub origin, or whenBOB_FLEET_ACTIONS_PROBE=0. See Fleet Snapshot Timer. audit.js view. An Actions budget table has one row per owner across the fleet:OWNER VERDICT USED% USED INCLUDED NOTE. Where several machines report an owner, the newest measured answer wins. An unreadable owner shows its fix inNOTE./what-next --report. The line under the health line comes fromactions-budget.js line --cwd <project>. A warn does not change the health verdict. The catch-up names it as a risk.
node ~/.claude/scripts/fleet/actions-budget.js probe [--owner O]... [--repo O/R] [--cwd DIR] [--fresh] [--json]node ~/.claude/scripts/fleet/actions-budget.js line [--repo O/R] [--cwd DIR] [--fresh]probe defaults to the owner of the checkout’s origin. Its exit codes:
0 when every owner is ok, unknown or unavailable, 1 when any is
warn or over, 2 on a usage error. line always exits 0:
Actions: paulirv: 84% of 3000 included minutes used (2520 min) WARN (≥80%)Actions: paulirv: usage unavailable — the gh token cannot read billing (no `user` scope) (fix: gh auth refresh -h github.com -s user)Actions: not measured — no GitHub origin| Variable | Default | Effect |
|---|---|---|
BOB_ACTIONS_WARN_PCT |
80 |
The warn threshold, in percent of the included minutes. |
BOB_ACTIONS_INCLUDED_MINUTES |
unset | The quota for an owner whose answer does not carry one. |
BOB_ACTIONS_BUDGET_TTL_MIN |
360 |
How long a cached answer is reused. |
BOB_FLEET_ACTIONS_PROBE |
unset | 0 leaves summary.actions_budget null and makes no billing call. |
tests/test-actions-budget.sh drives the CLI, the snapshot and the view
against a stub gh. The owners it covers are ok, warn, an org over quota, a
scope refusal and a usage-report-only owner. It also tests the cache,
--fresh and the opt-out.