feat(runner-policy): admit skip-actors on the claude-security-review contract - #307
Conversation
…contract ADR 0002 (claude-code-plugins) re-deliberated the skip-actor exception and rejected the reusable workflow's inherited default for the security lane: it covers `claude[bot]` and `melodic-ai[bot]`, which carry none of the compensating controls that justified the two ratified actors, so an AI-app-pushed commit would satisfy the required security check with no review run of any kind. The caller must therefore pass an explicit narrow list. That divergence is only expressible if the contract admits the input. Add `skip-actors` to the `allowedInputs` of the `claude-security-review.yml@c136b27` entry, matching the `claude-review.yml` contracts that already admit it. Permissive widening only: no consumer starts passing the input, and the validator continues to reject any input outside this list. Refs: melodic-software/claude-code-plugins#1767 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FVoZoMYXqf8ZVbQYixPVPW
|
Claude finished @kyle-sexton's task in 2m 17s —— View job Code review
This PR is a one-line data change to Correctness of the mechanism
🟡 Nit — test coverage gap for the new admission Since 🟡 Nit — array ordering inconsistent with sibling entries Everything else checks out: the diff is scoped exactly as described, doesn't touch |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d55d12bd2c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Claude has reviewed this PR 1 time. The lane skips further automatic reviews after 5; deleting this comment resets the count. |
… list The `c136b27f` review note still recorded the security caller as able to pass only `runner` and `paths-file`, so the contract record contradicted the `allowedInputs` widening in the same component and a reviewer consulting it would have read `skip-actors` as denied. `skip-actors` is one of the reusable's 8 declared inputs at that SHA (`runner`, `paths`, `paths-file`, `prompt`, `claude-args`, `exclude-comments-by-actor`, `skip-actors`, `retry-delay-seconds`), so the "(of 8)" denominator is unchanged and the set stays narrower than the declared surface. Refs: melodic-software/claude-code-plugins#1767 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013dsTvnGqMJeLTZe4DpGGVQ
The README's contract-surface paragraph for the v0.9.1 lane revision still said the security caller may pass only `runner` and `paths-file`, which the previous commit made false. Note the third admitted input, and why: it restores parity with the `66073e58` contract, which already admitted it, and a consumer whose ruleset makes the security check required needs it to narrow the reusable's four-actor default. Refs: melodic-software/claude-code-plugins#1767 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FVoZoMYXqf8ZVbQYixPVPW
Summary
Adds
skip-actorsto theallowedInputsof the runner-policy contract entry formelodic-software/ci-workflows/.github/workflows/claude-security-review.yml@c136b27— the pinboth security-lane consumers run today.
Why now:
claude-code-pluginsre-deliberated ADR 0002's skip-actor exception(melodic-software/claude-code-plugins#1767) and rejected the reusable workflow's inherited
default (
dependabot[bot],claude[bot],melodic-ai[bot],melodic-standards-sync[bot]) for thesecurity lane.
claude[bot]andmelodic-ai[bot]carry none of the compensating controlsthat justified the two operator-ratified actors — a Dependabot pin bump is forced through this
very runner-policy contract, and a standards-sync PR materializes byte-exact upstream-reviewed
content — so an AI-app-pushed commit would satisfy that repo's required security check with
no review run of any kind. Its caller must therefore pass an explicit narrow list
(
dependabot[bot],melodic-standards-sync[bot]), and the caller can only pass an input thecontract admits.
This restores parity rather than widening new ground: the previous approved security SHA's
contract (
66073e58) already admittedskip-actors; thec136b27entry dropped it, which is whythe consumer's caller could not keep its explicit list through the re-pin. The
claude-review.ymlcontracts at
df54d0eand4dbb0dfadmit it too.A second commit reconciles
components/runner-policy/README.md, whosec136b27review note stillrecorded the security caller as able to pass only
runnerandpaths-file— a reviewer consultingit would have read
skip-actorsas denied. The(of 8)denominator is unchanged:skip-actorsisone of the reusable's eight declared inputs at that SHA (
runner,paths,paths-file,prompt,claude-args,exclude-comments-by-actor,skip-actors,retry-delay-seconds), so the admittedset stays narrower than the declared surface.
Blast radius — permissive widening only.
runner-policyis a managed component across thefleet, so this materializes everywhere, but nothing starts passing the input: the validator
rejects inputs outside
allowedInputsand never requires one. The only behavior change isthat a caller may now pass
skip-actorsto this pin without the policy check failing.The entry carries no
autoApprovedblock, so it is a human-reviewed contract edit by design.Known residual gap (follow-up, not this PR): the validator rejects unexpected inputs but cannot
require one, so a future re-pin that drops a caller's
skip-actorsline passes CI and silentlyre-widens the exception. Guarding that needs a
requiredInputs-style contract field — filed as#308, which also records the matching hazard in the parked
claude-security-review-callercomponent (its bytes pass no
skip-actors, so an adopter inherits the widened default when itunparks).
Test plan
node -e "JSON.parse(...)"oncomponents/runner-policy/policy.json— parses.biome check components/runner-policy/policy.json— clean (also clean via thepre-commitlefthook run: typos, gitleaks, editorconfig, biome all pass).
"allowedInputs": ["runner", "paths-file"]→["runner", "paths-file", "skip-actors"], matching the file's one-line-array style and theschema's
uniqueStringArray.skip-actorsis a declaredworkflow_callinput onclaude-security-review.yml@c136b27, defaulting to the four-actorlist and gating the
security-reviewjob (not the workflow), so a skipped actor stillreports a name-stable passing check.
policy.json,runner-policy.mjsreportsRunner policy passed.against the narrowed caller;without it, exactly one finding (
inputs absent from its reviewed contract: skip-actors).Related
No linked issue in this repository — deliberately. The deliberation and its record live in the
consuming repo (melodic-software/claude-code-plugins#1767), which is closed by its own caller PR;
a cross-repo closing keyword here would close that issue on the wrong merge.
claude-code-plugins
runner-policycheck stays red until this merges and the sync materializesrequiredInputscontract field) andfeat(claude-security-review): split the security lane's skip-actors default from the review lane's ci-workflows#330 (narrow the security reusable's own
skip-actorsdefault)paths-fileinput), feat(runner-policy): admit claude-review@df54d0e as runner-input #161(
claude-reviewrunner-input contract)🤖 Generated with Claude Code
https://claude.ai/code/session_01FVoZoMYXqf8ZVbQYixPVPW