Repository navigation
feat(pr-pipeline): run pr-verify's model on the key first and the subscription token only on a credit stop - #8577
Conversation
…scription token only on a credit stop run-claude-cli v0.54.0 takes exactly one credential and leaves the subscription fallback to a second job. check-intent now holds only the API key; check-intent-subscription holds only the OAuth token and runs on a fresh ubuntu-24.04 VM only when check-intent's key leg ended in a credit stop with no permission denial, or the key is empty. In those cases check-intent writes no verdict and does not fail, so one job per run judges. The subscription job repeats every step from a fresh checkout and reads only three check-intent outputs, in its if. write-verdict.mjs gains a check-key-leg mode that fails on any denial in the key leg's log, since the subscription job cannot read that log. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xk7Lz7d2twxvA3LfRxnLkT
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xk7Lz7d2twxvA3LfRxnLkT
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
claude-review reviewed No findings. The only change since 5a2a4ab is a rewording of one header comment in I checked the new wording against the file:
The comment is accurate, and the rewording removes the earlier misleading semicolon clause. I did not run the workflow or CI. This review covers only the incremental diff. The earlier commits were reviewed at 5a2a4ab. |
|
claude-security-review reviewed No security findings. The only change since 5a2a4ab is a rewording of a header comment in |
…workflows to one release A credit stop with a denial on the key leg left no lane record: the key job skipped its report and the subscription job never ran. The key-leg check now runs before the report, with continue-on-error, and the report runs on that check's failure with class rate-limit. A clean credit stop was recorded only by the subscription job, under the OAuth credential. Its lane name now says whether the key hit a credit stop or is empty, picked between two literals, and the key-leg step warns that the automations key needs rotating. Every ci-workflows action moves to v0.54.0 with run-claude-cli, and a test holds them to one SHA. The subscription job's if repeats the key job's event, ref and fork conditions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xk7Lz7d2twxvA3LfRxnLkT
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xk7Lz7d2twxvA3LfRxnLkT
Closes #806 ## Summary When intake-triage (or any caller of the two-job pattern) falls back to the subscription token, the run's only lane record comes from the subscription job and does not say why it ran. This adds a machine-readable `fallback=<reason>` token so a credit stop on a role's API key shows in the lane record. ## Fix - `report-lane-outcome`: new optional `fallback-reason` input, `credit-stop` or `no-key`. `recordTokens` prints `fallback=<reason>` right after `credential=`, only for a value in `FALLBACK_REASONS`. The step script fails (`core.setFailed`, naming the allowed values, before any annotation or output) on any other non-empty value. The value reaches the script through env only. - `intake-triage.yml`: the subscription job's "Report triage outcome" step passes `fallback-reason: ${{ needs.claude.outputs.lane-class == 'credit-stop' && 'credit-stop' || needs.claude.outputs.credential-present == 'false' && 'no-key' || '' }}`. That is a `with:` input on a `uses:` step, so the subscription job still writes no `needs.` value into a `run:` or `script:`. - `intake-triage-legs.test.cjs`: the parity test strips exactly this one input from the subscription job (after asserting its exact text), and a new test evaluates it: credit-stop gives `credit-stop`, an empty key gives `no-key`, anything else gives empty. - README: the run-record token list and the two-job pattern describe the input. Out of scope, per the brief: an `auth` value; the claude-code-plugins follow-ups (pr-verify passing the input, the morning brief counting the token). ## Verification - `node --test .github/scripts/*.test.cjs .github/actions/*/*.test.cjs`: 632 pass, 0 fail. - New tests were run red before the change: 3 in report-lane-outcome (record token order and vocabulary, notice and class line carry `credential=... fallback=...`, out-of-vocabulary value fails the step with no outputs), and 2 in the legs test (parity and expression evaluation) before the workflow edit. - Existing record tests are unchanged and pass, so records without the input are byte-identical. - actionlint, biome, typos and markdownlint-cli2 (README) are clean. No shell was touched. ## Related - #804 / #821 (read-only model jobs) and #782 / #830 (trusted-comment filter): this is built on their structure, and nothing they added is relaxed. - Downstream: melodic-software/claude-code-plugins#8577 (the workaround this replaces after a repin). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
No related issue: run-claude-cli v0.54.0 (ci-workflows 7b36242) takes exactly one credential, so pr-verify needs the two-job pattern before its pin can move.
Summary
ci-workflows v0.54.0 makes the run-claude-cli action take exactly one of
api-keyorsubscription-token, fail closed if given both, and setlane-class=credit-stopon a key credit stop instead of falling back inside the step. pr-verify pins v0.53.0, which fell back in-step. This moves pr-verify to two jobs and repins to v0.54.0 (7b362428).Fix
check-intentruns the model on the automations API key. New outputs:lane-class,credential-present,key-leg-clean.check-intent-subscription(needs: check-intent,ubuntu-24.04, fresh checkout, every step repeated, nothing carried from the first job) runs only when the key job hit a credit stop with a clean key leg, or no key is set (if:at :364; with no status function GitHub addssuccess(), so a failed key job skips it).secrets.AUTOMATIONS_CLAUDE_CODE_OAUTH_TOKENis now only in the subscription job (:490, :563). Permissions unchanged, read-only in both jobs.credential:in report-lane-outcome; a new "Check the key leg" step (:300) fails the key job on any permission denial, andwrite-verdict.mjsstill catches denials in the subscription job, so a denial never yields a verdict; exactly one verdict per run (a credit stop always fails the key job's judge step). Step names "Judge the pull request" and "Upload the verdict" kept.Known interaction: the held reconciler change (#8562) counts a started judge step in any job, so it would hold rather than re-run a run whose subscription job was lost. That fails safe; the fix belongs in #8562.
Verification
workflow.test.mjsrewritten per job: hand-off condition, each secret only in its own job, the subscription job's steps equal the key job's apart from the credential (a mutation check fails on drift). New tests forcheckKeyLeginwrite-verdict.mjs. resolve-pr, reconcile, callers and workflow-gates tests pass; actionlint, offline zizmor and runner-policy pass.needs,ifchanges).Related
🤖 Generated with Claude Code
https://claude.ai/code/session_01Xk7Lz7d2twxvA3LfRxnLkT