Repository navigation
ci(intake-triage): skip a credit-stopped key with the check-key-credit gate - #996
Draft
kyle-sexton wants to merge 1 commit into
Draft
kyle-sexton wants to merge 1 commit into
kyle-sexton wants to merge 1 commit into
Conversation
…t gate intake-triage.yml gets the gate pr-review-cli.yml already runs. A check-key-credit job with no secret reads the key's credit history; the claude job treats a key whose credit stop is inside key-credit-window-hours (1 hour by default) as absent, so the subscription job triages with fallback reason credit-stop, and the key leg uploads the gate's marker after its own credit stop. The claude job still runs, so its skip stays the author gate's alone. The gate reads markers with actions: read, which each caller job must now grant. Refs: melodic-software/claude-code-plugins#13586 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Nov 5, 2026
kyle-sexton
added a commit
to melodic-software/standards
that referenced
this pull request
Nov 5, 2026
…949) Refs: melodic-software/claude-code-plugins#13586 ## Summary This adds `actions: read` to the reviewed `allowedCallerPermissions` of the `intake-triage.yml` contract in `components/runner-policy/policy.json`. After the change, a caller job that grants `actions: read` passes `runner-policy`. ## Fix - [melodic-software/ci-workflows#996](melodic-software/ci-workflows#996) adds the `check-key-credit` gate to `intake-triage.yml`; `pr-review-cli.yml` already has it. The gate lists the repository's credit-stop markers with `actions: read`. A called workflow holds only the permissions its caller job grants, so every caller job must grant `actions: read`. - Until this contract lists that permission, `runner-policy` rejects the claude-code-plugins caller: "reusable workflow caller permissions has unapproved properties". That rejection is the lint-repo failure on [melodic-software/claude-code-plugins#13608](melodic-software/claude-code-plugins#13608). - `actions: read` adds no write access and no token beyond the job's own `GITHUB_TOKEN`. - Callers float on `@main`, so `approvedShas` stays as it is. ## Verification - `node --test components/runner-policy/runner-policy.test.mjs`: 226 tests, 226 pass. ## Related Merge order: 1. This PR, then sync it to the callers. 2. The claude-code-plugins caller grants `actions: read`. That change was taken out of #13608 until this PR syncs, and goes back in afterwards. 3. ci-workflows#996, held with `do-not-merge` until step 2 lands. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
kyle-sexton
added a commit
to melodic-software/standards
that referenced
this pull request
Nov 6, 2026
…r a migration (#950) Refs: melodic-software/claude-code-plugins#13586 ## Summary The runner-policy contract matches a caller's permissions against `allowedCallerPermissions` exactly. standards#949 added `actions: read` to the intake-triage contract, so every caller must now grant it. The claude-code-plugins caller cannot add it before the sync, because the old synced contract rejects it, and the sync PR cannot be hand-edited (check-managed-files). Under a required `ci-status` that is a deadlock. This PR lets a contract list several exact maps, so a permission change lands expand/contract: 1. This PR: accept a list of exact maps, and list the old and new intake-triage maps. 2. The sync PR, plus the caller PR that grants `actions: read`. 3. A follow-up that drops the old intake-triage map. 4. melodic-software/ci-workflows#996. ## Fix - `runner-policy.mjs`: `allowedCallerPermissions` is one exact map or a non-empty list of exact maps. A caller passes when its effective permissions equal any one listed map exactly; each map is still matched exactly, so the ceiling stays exact. With more than one map, the failure names every allowed map (`must be exactly one of {...}, {...}`). The single-map form keeps its existing per-scope wording. The config checks (at least one write scope, satisfies `minimumCallerPermissions`) run per map and name the failing index. - `policy.schema.json`: `allowedCallerPermissions` is `oneOf` a permission map or a `minItems: 1`, `uniqueItems` array of permission maps. - `policy.json`: intake-triage lists `{contents: read, issues: write}` and `{actions: read, contents: read, issues: write}`. No other contract changes. - `README.md`: "Contract revision lockstep" item 3 describes the expand/contract order for a caller permission change; the contract description admits the list form. ## Verification - `npm run test:runner-policy`: 232 pass, 0 fail. New cases: a caller matching the first map passes; matching the second passes; matching neither fails with a message listing both; a superset, subset or access drift of either map fails; the single-map form passes on an exact match and keeps its old messages; the schema rejects an empty list; every listed map must carry a write scope. - A mutant that checks only the first listed map fails the "matching either map passes" case. - `npm run lint:runner-policy`: passed. - biome 2.6.3 `ci` on `components/runner-policy`: clean. markdownlint on the README: clean. ## Related - #949 - melodic-software/claude-code-plugins#13630 - melodic-software/ci-workflows#996 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs: melodic-software/claude-code-plugins#13586
Summary
intake-triage.ymlnow has thecheck-key-creditgate thatpr-review-cli.ymlalready runs. When the key's last credit stop is inside the window, the intake triage skips the key and goes straight to the subscription leg, so no request is spent on a key that will be refused.Hold: merge only after the reusable's one caller job grants
actions: read. That grant waits on melodic-software/standards#949, which addsactions: readto this reusable's runner-policy contract; a claude-code-plugins follow-up then adds the grant to itsintake-triagecaller job. The gate needs that permission, and a called workflow can hold only what its caller grants, so merging this first would break that caller. A code search forci-workflows/.github/workflows/intake-triage.ymlacross melodic-software found no other workflow caller. Thedo-not-mergelabel holds it.Fix
check-key-creditjob. It holds no secret and onlyactions: read. It runs for every event, so theclaudejob's skip still means only that the author gate refused.claudejob's credential step treats a credit-stopped key as absent (key-skipped=true). Thesubscriptionjob then triages, and its lane record carries fallback reasoncredit-stop.pr-review-cli.ymldoes.key-credit-window-hours, default 1.actions: read.Verification
node --test .github/scripts/*.test.cjs: 913 tests, 913 pass.claudejob, apart from the named key-only steps.zizmor --offline: no findings.Related
actions: read.Draft: held until the intake-triage caller grants actions: read
🤖 Generated with Claude Code