Repository navigation
ci(lanes): repin the Claude lane callers to ci-workflows v0.65.13 and pass the fallback token - #10151
Conversation
… pass the fallback token Repin the reusable-workflow callers (pr-review-hosted.yml, pr-review-security-hosted.yml, intake-triage.yml) and the composite-action callers (pr-run-activity-read.yml, pr-run-activity-write.yml, pr-unblock.yml, pr-verify.yml) to v0.65.12 (78ee7a26). The three reusable callers pass FALLBACK_CLAUDE_CODE_OAUTH_TOKEN by name, as the runner-policy contracts for that SHA require, so the reusables' fallback job can run after the subscription job hands off. The lane-funding catalog lists the fallback secret for the three lanes that now read it, and callers.test.mjs admits it only on a call of a ci-workflows reusable with a fallback job. The pin tests move with the SHA; lane.cjs at 78ee7a26 passes --permission-prompts none at lines 404-405. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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. |
|
Held by Lane Funding: on v0.65.12, pr-review-cli's status job fails with failure-class=no-outcome when the key leg is skipped by the credit window and the subscription leg succeeds (runs 40256492380, 40256492385). Merging this would break the review lanes. The fix and v0.65.13 are in progress in ci-workflows; this PR gets repinned to v0.65.13 and the label removed once that lands. |
v0.65.13 fixes the pr-review-cli status job's read of the token leg's job result (ci-workflows#892), which made v0.65.12 report no-outcome when the key leg was skipped by the credit window. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
claude-security-review reviewed Security review: PR #10151 (head 784414c)No security findings. critical-findings: 0 Scope read: the whole diff (12 files) and the PR context. No changed file matches a trusted path ( What I checked
Observation, not counted as a finding. The PR description is stale against the head commit.
Spend, not a hold: after merge, the code review, security review and intake triage lanes can fall back to the central org subscription token once the role key and role token have both stopped. That draws on subscription usage only and starts no billed resource, so I set no hold and didn't count it as a finding. |
|
claude-review reviewed The pin and the repo's checks line up, but the PR description describes a different release than the one the diff pins. Pin consistency (checked by reading, not run). Every Finding (description does not match the diff, at the pin). The PR body says "Repins every Claude lane caller to ci-workflows v0.65.12 (
The code now cites Minor, not counted. Closing issues. None. The PR context says there is no related issue. Trusted paths. No changed file matches the TRUSTED PATHS globs, so no extra scrutiny applied. Spend. More fallback-subscription usage after a limit stop draws on subscription credit only. It is not a hold and not counted. |
…ed (#884) Refs: melodic-software/claude-code-plugins#10151 ## Summary Owner decision (2026-10-25): a ci-workflows repin moves only the pinned paths a release actually changed, not every pin, and the existing repin tool (`components/claude-lanes/repin-callers.sh`) stays the single source of truth for repins. Evidence: - The `v0.65.12...v0.65.13` compare changed only `.github/workflows/pr-review-cli.yml` and `.github/scripts/pr-review-cli.test.cjs`. - Even so, the consumer repin melodic-software/claude-code-plugins#10151 rewrote 21 `uses:` lines: intake-triage, the `run-claude-cli`, `apply-claude-managed-settings` and `report-lane-outcome` composites, and pr-review-cli. - Each needless move forces runner-policy contract PRs for job-level reusable workflows. - Each needless move also fails lane runs already in flight with a workflow-modified 403 (4 intake runs on melodic-software/claude-code-plugins#10147). ## Fix `repin-callers.sh apply` now decides each `melodic-software/ci-workflows/<path>@<sha>` ref separately: - **One compare per distinct pinned SHA**, `compare/<pinned>...<release>`, cached for the run. The same response feeds the downgrade fence and the file list. The fence is unchanged in meaning: a fallback-form pin the release does not contain (`behind` or `diverged` in this direction) is left as is. - **Moved**: the release changed the reusable workflow file, anything under the composite directory (tests included), or a path the pin reaches through a commit-relative `uses:`. Those are a step-level `$/<dir>` action or a job-level `./.github/workflows/<file>` nested workflow, the two forms runner-policy diffs. Each is read once from the release, transitively. intake-triage, for example, runs `$/.github/actions/run-claude-cli` and `report-lane-outcome`, so a change to those moves intake-triage too. - **Fail closed**, moving every pin at that SHA, in two cases: the compare lists 300 or more files (the documented cap), or it changed a file that is not a test (`*.test.*`), not a `README.md`, not under `docs/`, and not reached by any pin (for example a shared `.github/scripts/*.cjs` or `schemas/`). That is today's behavior. - **Unchanged pins stay byte-identical.** Moved pins get the release SHA with the `# vX.Y.Z` comment. The version note lists what moved and what stayed. - **`--root <dir>`** runs the same tool against any repository. It discovers every git-tracked `.github/` YAML file that pins ci-workflows, so a consumer checkout such as claude-code-plugins repins with this tool instead of hand edits. The rename map is read from beside the script. The standards lane's invocation (no `--root`, enumerated callers) is unchanged. The apply step now gets `GH_TOKEN`, because it calls `gh` on any day a new release resolves. `repin-policy-lockstep.mjs` plans only the pins apply moved, so an unchanged reusable pin keeps its existing contract and needs no contract copy. Its own caller rewrite (`rewriteCallerFiles`) is removed: it rewrote every pin in its target files to the new SHA, which would have undone the selective repin, and apply already rewrites those files. Its two unit tests go with it. Out of scope and unchanged: no runner-policy contract rule is loosened, nothing auto-admits a secret-bearing runner-input contract, and `components/runner-policy/policy.json` semantics are untouched. ## Verification Run from the worktree root: - `bash harness/shell/run-tests.sh components/claude-lanes/repin-callers.test.sh`: pass, 161 assertions (the existing 129 plus 32 new). New cases: - only `pr-review-cli.yml` changed moves only that ref, with one compare call; - a shared-script change moves all refs; - a composite-directory change moves only that composite; - a composite reached through a nested workflow moves the reusable; - an inert-only change moves nothing, while the same files at the 300-file cap move everything; - two distinct SHAs cost two compares; - the standards lane's own invocation moves only the changed lane caller. - Mutation check: forcing every decision to `move`, dropping fail-closed, dropping reach, dropping the cap, dropping the compare cache, counting tests, or dropping the directory prefix rule each turns new cases red. Inverting the fence statuses turns 20 assertions red. - `node --test components/claude-lanes/repin-policy-lockstep.test.mjs`: 23 pass. The two new tests (only moved pins are planned; `settleLockstep` leaves an unmoved caller pin alone) fail against the previous script. - `bash harness/shell/run-tests.sh components/claude-lanes/claude-lanes.test.sh` and `node --test components/runner-policy/runner-policy.test.mjs` (355): pass. - `shellcheck --rcfile .shellcheckrc`, biome, actionlint and zizmor on the changed files: clean. - End to end against the live v0.65.13 compare on a copy of claude-code-plugins' `.github/` from before #10151 (442 files, 47 pins): - Real snapshot: 46 of 47 pins move, because none of the pinned SHAs is v0.65.12. The lane pins were at v0.65.11, and `v0.65.11...v0.65.13` also changed `schemas/lane-outcome.v1.schema.json`, so they fail closed exactly as #10151 moved them. The v0.55, v0.58 and v0.59 pins fail closed on `.github/scripts/*.cjs` and `.claude/rules/*.md`. - Synthetic variant with every pin set to v0.65.12: only the two `pr-review-cli.yml` lines move, and the other 45 stay byte-identical. Consumer command, from any directory with an authenticated `gh`, `jq`, GNU sed and bash 4.4 or newer: ```bash GITHUB_OUTPUT=/tmp/repin.out bash <standards-checkout>/components/claude-lanes/repin-callers.sh resolve melodic-software/ci-workflows GITHUB_OUTPUT=/tmp/repin.out bash <standards-checkout>/components/claude-lanes/repin-callers.sh apply <tag> <sha> <date> --root <consumer-checkout> ``` `resolve` writes `tag`, `sha` and `date` to the output file. `apply` leaves the moved pins in the consumer's working tree and writes `changed`, `old-sha`, `old-tags` and `version-note`. ## Related - Refs melodic-software/claude-code-plugins#10147 (in-flight intake runs failed with a workflow-modified 403 by the full repin). - The inert set stays tests, `README.md` and `docs/` by owner decision: lanes may load other `.md` files as instructions, so a change to one can change what a pin runs. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01DpzEJAE4EMndcWQXiKSZYn --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
No related issue: the owner approved the central fallback subscription (decision Q12, 2026-10-25); this repins the lane callers to the ci-workflows release that adds it.
Summary
Repins every Claude lane caller to ci-workflows v0.65.13 (
ba7af78d291f10bd75651857a0db2357c23df0fe) and passes the org secretFALLBACK_CLAUDE_CODE_OAUTH_TOKENto the two reusables that take it. After this merges, the code review, security review and intake triage lanes hand off once more, to the central fallback subscription, when the role key and the role token have both stopped (a limit stop, a credit stop, or a 401 or 402). With the secret empty, the lanes run as before.Fix
pr-review-hosted.yml,pr-review-security-hosted.yml(pr-review-cli.yml) andintake-triage.yml(intake-triage.yml) move from v0.65.11 and passFALLBACK_CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.FALLBACK_CLAUDE_CODE_OAUTH_TOKEN }}by name, neversecrets: inherit. That is the secret the runner-policy contracts add at v0.65.12 (standards#881) and carry forward unchanged atba7af78d(standards#882), with no input or permission change.pr-run-activity-read.yml,pr-run-activity-write.yml,pr-unblock.ymlandpr-verify.ymlmoverun-claude-cli,report-lane-outcomeandapply-claude-managed-settingsto the same SHA. Betweene5167fc2andba7af78donly ci-workflows#890 and #891 changed them: optionalfallback-tokenandfallback-readyinputs, ahandoff-reasonoutput, and alimit-stopfallback reason; v0.65.13 changes none of them (the compare touches onlypr-review-cli.ymland its test). With neither input set, a subscription leg never hands off, so these callers behave exactly as today..github/lane-funding.jsonlists the fallback secret in the three lanes that now read it.callers.test.mjsadmits that secret, the same for every role, only on a call of a ci-workflowsintake-triage.ymlorpr-review-cli.ymlreusable that passes it by name.callers.test.mjsaddsba7af78dto the launchers checked to pass--permission-prompts none:lane.cjs:404-405atba7af78dreads"--permission-prompts", "none", andgit diff 78ee7a26 ba7af78d -- .github/actions/run-claude-cli/is empty, so the lane-class keys are unchanged too. Thereplay.mjspin,ci-review-lanes.test.shandci-review-plugin-source.test.shmove with it.cliArgsandlegEnvinlane.cjsare unchanged frome5167fc2throughba7af78d.Runners that do not get a fallback leg in this PR, and why:
pr-verify.yml(check-intent): a third job would break.github/scripts/pr-verify/workflow.test.mjs, which pins the jobs to[check-intent, check-intent-subscription], asserts the subscription job has nooutputs:, and allows no secret but the twoPR_VERIFY_*ones;probe/parity.test.mjs:16pins the same two jobs. Both files are outside this change's scope.pr-run-activity-read.yml(pr-unblock's fix-ci, address-feedback, review-dependency and resolve-conflicts lanes, pr-refine's fix-docs, and the issue lane): the legs are separate calls by each caller, so a fallback leg needs a third call in every caller, includingwork-resolve-issue.ymlandpr-refine.yml. It would also breakscripts/check-read-caller-keys.mjs:34-36, the allowlist of secret keys a caller may pass to the read runner, and.github/scripts/pr-unblock/workflow-gates.test.mjs:237, which pins the jobs that follow address-feedback. Adding the leg to the runner alone, with no caller that runs it, would be a path nothing uses.pr-unblock.ymladjudicate-feedback: it runs on the API key only and has no token leg to hand off from.pr-run-activity-write.yml: it runs claude-code-action, not run-claude-cli, so it has no launcher leg.Verification
node --test .github/actions/resolve-config/callers.test.mjs: 182 pass, 0 fail. Before the catalog and test edits, the two catalog tests failed onFALLBACK_CLAUDE_CODE_OAUTH_TOKEN.node --testover.github/scripts/pr-verify/probe/parity.test.mjs,probe/replay.test.mjs,pr-verify/workflow.test.mjsand.github/scripts/pr-unblock/*.test.mjs: 800 pass, 0 fail.bash scripts/ci-review-lanes.test.sh: 88 pass.bash scripts/ci-review-plugin-source.test.sh: 10 pass.bash scripts/check-read-caller-keys.test.sh: 49 pass. The read-runner suites (collect-patch-lane,act-turns-denied,pr-unblock-trusted-base,read-lane-broker-check,read-runner-dispatcher-gate,write-runner-never-rules) pass.node .github/standards/runner-policy/runner-policy.mjs --root .: "Runner policy passed."actionlintandzizmor --offlineon the seven workflows: no findings.bash scripts/check-changelog-fragments.sh --check-required origin/main: no fragment-mode plugin changed, so none is required.Left out: a live fallback run. A real limit stop or credit stop on both role credentials cannot be produced on demand.
Related
🤖 Generated with Claude Code