Repository navigation
feat(runner-policy): admit role-named secrets and register ci-workflows v0.51.0 intake - #811
Conversation
…ws v0.51.0 intake A contract with allowedCallerPermissions still maps each secret to its own name, or now, when it declares a funding role, to that role's prefixed name (<ROLE>_NAME, role upper-snake). The role must be in allowedInputs and the caller must pass it as that exact literal; every other rename is refused. Role-named secrets let several funding roles share one repository. Registers intake-triage at the v0.51.0 tag f129f4c with role automations: the v0.49.0 entry plus the role input and the automations role's API key and subscription token. The v0.49.0 entry stays until the caller repins. 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. |
|
claude-security-review reviewed Security review: PR #811 at
|
|
claude-review reviewed No findings. I read the full diff, the PR context, and the surrounding
|
…829) Refs: melodic-software/ci-workflows#818 Refs: melodic-software/ci-workflows#819 ## Summary Registers ci-workflows [v0.56.0](https://github.com/melodic-software/ci-workflows/releases/tag/v0.56.0) (`1bb8953644d16f21d10718962c6702f01ea3308a`) contracts for `intake-triage.yml` and `intake-label-needs-triage.yml`. [claude-code-plugins#8800](melodic-software/claude-code-plugins#8800) repins both intake callers to that SHA, and its runner-policy gate fails with `runner-target-contract: the reusable workflow path@SHA has no reviewed runner-input contract (auto-approval declined: ... carries a reviewed allowedCallerPermissions grant; its steps cannot be proven unchanged by this surface diff, so auto-approval is declined)` for both. **Owner sign-off pending.** The README rollout line says "sign-off pending"; replace it with "signed off by hand on <date>" when you sign off. ## Fix - `components/runner-policy/policy.json`: - `intake-triage.yml@1bb8953`: a verbatim copy of the v0.55.0 entry (`3a2c748`). - `intake-label-needs-triage.yml@1bb8953`: a verbatim copy of the v0.42.0 entry (`182aca3`), the newest reviewed SHA for that file. - `components/runner-policy/README.md`: the v0.56.0 rollout line, sign-off pending. - `components/runner-policy/runner-policy.test.mjs`: a test that both v0.56.0 entries equal their source entries and that they are the only two keys at that SHA. ### Byte-identity evidence Git blob SHA of each file, from `gh api repos/melodic-software/ci-workflows/contents/.github/workflows/<file>?ref=<sha> --jq .sha`: | File | `182aca3` | `3a2c748` (v0.55.0) | `1bb8953` (v0.56.0) | |---|---|---|---| | `intake-triage.yml` | `fa4e86f8` | `d79b7e9e` | `d79b7e9e` | | `intake-label-needs-triage.yml` | `8d274a66` | `8d274a66` | `8d274a66` | `gh api repos/melodic-software/ci-workflows/compare/3a2c748...1bb8953` is one commit ([ci-workflows#836](melodic-software/ci-workflows#836)) touching nine files, all under `.github/actions/pr-require-checks/` plus `README.md`; neither intake file is among them. Against `182aca3`, the compare lists `intake-triage.yml` as modified (that file's reviewed SHA is `3a2c748`, not `182aca3`) and not `intake-label-needs-triage.yml`. No input, secret, caller permission, or `runs-on` routing changes. ## Verification - `npm run test:runner-policy`: 323 pass, 0 fail, including `✔ both intake contracts at the v0.56.0 tag copy their reviewed entries forward verbatim`. Adding an input to the new `intake-label-needs-triage` entry makes that test fail. - `npm run lint:runner-policy`: `Runner policy passed.` - Against the claude-code-plugins#8800 worktree (`--repository-visibility public`, worktree not modified): - with its vendored policy: the two `runner-target-contract` failures above, and no others; - with `--policy` set to this branch's `policy.json`: `Runner policy passed.`; - with this branch's `runner-policy.mjs` and `policy.json`: `Runner policy passed.` - Every other ci-workflows reusable that #8800 calls stays on a SHA that already has a contract (`pr-review` and `pr-review-security` at v0.48.0, `maintenance-check-links-online` at v0.55.0). The other v0.56.0 pins are composite actions, which need no contract. - lefthook pre-commit (typos, editorconfig, markdownlint, gitleaks, biome): clean. ## Related - [claude-code-plugins#8800](melodic-software/claude-code-plugins#8800) passes its runner-policy gate once this merges and syncs. - Precedent: #828 (v0.55.0 verbatim copies), #811, #802. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01Tje1j8KEYaYSxYe8RgJ3Lw --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
No related issue: runner-policy contract for the claude-code-plugins intake move onto ci-workflows' run-claude-cli launcher (melodic-software/ci-workflows#784)
Hold: a human merges this.
Summary
claude-code-plugins' intake now calls ci-workflows
intake-triage.ymlat v0.51.0, which runs on therun-claude-clilauncher funded by theautomationsrole. The caller passes the role's two secrets,AUTOMATIONS_CLAUDE_API_KEYandAUTOMATIONS_CLAUDE_CODE_OAUTH_TOKEN. The same-name rule for privileged contracts (from #140) refused that mapping, so the contract could not load.Fix
Security control change, owner-approved 2026-10-19. A contract with
allowedCallerPermissionsmay map a secret to its own name, as before, or to its funding role's prefixed name,NAME: ${{ secrets.<ROLE>_NAME }}. The prefixed form is allowed only when:role(lower kebab);roleis in itsallowedInputs;role:as that exact literal.Any other rename is still refused, as are expressions and other prefixes. The role is a reviewed literal, never an expression. This lets several funding roles share one repository.
Registers
intake-triage.yml@f129f4c142d00ec3feacbf2b9102d327088504bf(v0.51.0) withrole: automations. It is the v0.49.0 entry plus theroleinput, with the one OAuth secret replaced by the role's API key and subscription token. Permissions and routing are unchanged. The v0.49.0 entry stays until the caller repins.policy.schema.jsongains the optionalroleproperty, and the README documents the rule.Verification
node --test components/runner-policy/*.test.mjs: 319/319 pass. The new tests:allowedInputsis refused;Related
feat/intake-on-run-claude-cli: the caller, opened after this syncs.🤖 Generated with Claude Code