Skip to content

Build master @ bc50cd5bunreleased — 31 commits past v1.282.0Last reviewed Last changed Grade fresh (aging >90d, stale >180d)Source / History

Actions budget ​

node ~/.claude/scripts/fleet/actions-budget.js probe tells 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 ​

One record per repo owner (bob-actions-budget/1):

KeyMeaning
ownerThe account, lower-cased.
kinduser or org, whichever endpoint answered; null when neither did.
verdictok, warn, over, unknown or unavailable (below).
used_minutesActions minutes used this billing cycle (billing endpoint) or this calendar month (usage report).
included_minutesThe plan's included minutes; from the billing endpoint, else BOB_ACTIONS_INCLUDED_MINUTES, else null.
paid_minutes / net_amountMinutes or charges past the included quota this period.
pctused_minutes ÷ included_minutes, one decimal; null without a quota.
warn_pctThe warn threshold applied.
sourcebilling-actions or usage-report.
reason, fixWhy the verdict is not ok/warn, and the command or setting that fixes it.
checked_atWhen the API was read (a cached answer keeps its time and adds cached: true).
VerdictMeaning
okBelow the warn threshold.
warnAt or above BOB_ACTIONS_WARN_PCT (default 80) of the included minutes.
overThe 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.
unknownMinutes are measured but the quota is not known. The usage report does not carry it, so set BOB_ACTIONS_INCLUDED_MINUTES.
unavailableNot 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 ​

For each owner it tries the users/ endpoints and then the orgs/ endpoints:

  1. GET /{users|orgs}/<owner>/settings/billing/actions returns the included minutes and the minutes used this cycle.
  2. GET /{users|orgs}/<owner>/settings/billing/usage?year=&month=, the enhanced-billing usage report. Only rows with product actions and 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 ​

  • Fleet snapshot. summary.actions_budget is {verdict, warn_pct, owners[]}, one record per distinct owner of this machine's projects, taken from each project's repo. verdict is the worst one. It is null when no project has a GitHub origin, or when BOB_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 in NOTE.
  • /what-next --report. The line under the health line comes from actions-budget.js line --cwd <project>. A warn does not change the health verdict. The catch-up names it as a risk.

CLI ​

bash
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
VariableDefaultEffect
BOB_ACTIONS_WARN_PCT80The warn threshold, in percent of the included minutes.
BOB_ACTIONS_INCLUDED_MINUTESunsetThe quota for an owner whose answer does not carry one.
BOB_ACTIONS_BUDGET_TTL_MIN360How long a cached answer is reused.
BOB_FLEET_ACTIONS_PROBEunset0 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.