Skip to content

fix(skill): correct the GHAS budget hard-stop procedure, which could not run - #1303

Merged
seoseo-ai merged 4 commits into
mainfrom
fix/ghas-budget-sku-correction
Aug 26, 2026
Merged

fix(skill): correct the GHAS budget hard-stop procedure, which could not run#1303
seoseo-ai merged 4 commits into
mainfrom
fix/ghas-budget-sku-correction

Conversation

@seoseo-ai

Copy link
Copy Markdown
Collaborator

Problem

Step 7 of github-metered-billing-leak-diagnosis — the skill's only mutating
step — shipped a gh api call that cannot succeed against the live API:

gh api -X POST "/organizations/$ORG/settings/billing/budgets" \
  -f budget_amount=0 -F prevent_further_usage=true

Every required body field is missing (budget_type, budget_product_sku,
budget_scope, budget_entity_name, budget_alerting), so this returns
400 Missing required fields. Supplying them under the implied
ProductPricing + ghas combination then returns 500 — GHAS budgets are
accepted only at SkuPricing granularity.

The correct procedure was already established empirically in session
c8d15a6c (2026-08-24), which hit three separate API rejections before
creating both GHAS license budgets successfully. That evidence never reached
the skill file; the skill was written from the same session but encoded the
first, failing attempt.

Changes

Step 7 replaced with the verified procedure. Loops over both
ghas_secret_protection_licenses and ghas_code_security_licenses — GHAS
bills as two license SKUs and capping one leaves the other accruing. The
generated JSON body is byte-identical to the request that returned
Budget successfully created. on 08-24. A pre-check listing existing budgets
was added ahead of it.

Trap 5 added, covering the three rejections in order:

  • the stop flag is prevent_further_usage, not
    stop_usage_when_budget_exhausted;
  • the ProductPricing + ghas 500 text — "High watermark products cannot
    have PreventFurtherUsage budget alerting except for GHAS SKUs"
    — reads as
    permission, not refusal;
  • budget_amount counts licenses, not dollars, for license-based
    products. GitHub's parameter doc: "The budget amount in whole dollars. For
    license-based products, this represents the number of licenses."
    So
    budget_amount: 0 means zero seats, not zero spend.

SKU-enumeration technique documented. Posting a deliberately invalid SKU
makes the API return the full valid-SKU list, which is how
ghas_secret_protection_licenses was found. Flagged explicitly as a POST that
leaves the otherwise read-only path, even though it creates nothing.

Safety section corrected. It previously described the hard stop in dollar
terms and did not list the enumeration probe among the mutating operations.

Verification

  • bash -n on the step 7 snippet passes
  • the jq-generated body matches the 08-24 success byte for byte
  • autoinstall.sh no-headings lint passes
  • repo copy confirmed identical to the installed copy before this patch, so
    the diff contains nothing else

Note

Sources are the origin session transcript and the current GitHub REST budgets
documentation. The SKU names and the 500 error text are quoted from a live
jinwon-int response, so they reflect that org's plan; the docs confirm the
general rule.

🤖 Generated with Claude Code

…not run

Step 7 of github-metered-billing-leak-diagnosis shipped a `gh api` POST that
fails against the live API. It omitted every required body field
(`budget_type`, `budget_product_sku`, `budget_scope`, `budget_entity_name`,
`budget_alerting`), so the call returns `400 Missing required fields`. Even
with those supplied, the implied `ProductPricing` + `ghas` combination returns
500 — GHAS budgets are only accepted at `SkuPricing` granularity.

The working procedure was already established empirically in session
c8d15a6c (2026-08-24), which created both GHAS license budgets successfully
after three API rejections. That evidence never made it into the skill.

Changes:

- Replace step 7 with the verified `SkuPricing` procedure, looping over both
  `ghas_secret_protection_licenses` and `ghas_code_security_licenses` —
  capping only one leaves the other accruing. The emitted JSON body is
  byte-identical to the request that succeeded on 08-24. Adds a pre-check
  listing existing budgets.

- Add trap 5 covering the three distinct rejections: the stop flag is
  `prevent_further_usage`, the ProductPricing 500 text ("except for GHAS
  SKUs") should be read as permission rather than refusal, and
  `budget_amount` counts licenses rather than dollars for license-based
  products. `budget_amount: 0` therefore means zero seats, not zero spend.

- Document the SKU-enumeration technique: posting an invalid SKU makes the
  API return the full valid-SKU list. Flagged as a POST that leaves the
  otherwise read-only path, though it creates nothing.

- Correct the Safety section, which described the hard stop in dollar terms
  and did not list the enumeration probe as mutating.

Verified: bash/jq syntax checks pass, generated body matches the 08-24
success, and the no-headings autoinstall lint passes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@seoseo-ai
seoseo-ai requested a review from jinon86 as a code owner August 26, 2026 13:49

@jinon86 jinon86 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved after explicit operator authorization using the Seoseo-held jinon86 credential.

seoseo-ai and others added 3 commits August 27, 2026 01:43
`gh pr update-branch` produced a `web-flow` merge commit that did not raise a
`pull_request` synchronize event, so none of the six required checks ran on
the new head and the PR sat at BLOCKED with zero reported checks. The
workflows carry no path filters, so this was a missing event rather than a
skipped trigger.

This empty commit exists only to raise that event. It carries no file
changes, and the squash merge collapses it, so it leaves nothing on main.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@seoseo-ai
seoseo-ai merged commit 9e9b58d into main Aug 26, 2026
8 checks passed
@seoseo-ai
seoseo-ai deleted the fix/ghas-budget-sku-correction branch August 26, 2026 18:33
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.

2 participants