Repository navigation
feat(runner-policy): accept a list of exact caller permission maps for a migration - #950
Conversation
…r a migration
A contract's 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. The single-map form and its error wording are unchanged.
intake-triage.yml lists the old map {contents: read, issues: write} and the
new one with actions: read, so callers can move to the new map after the
sync instead of deadlocking on it. The README's contract revision lockstep
item 3 records the expand/contract order.
Refs: melodic-software/claude-code-plugins#13586
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-review reviewed No findings. I read all 5 changed files and traced every consumer of
I could not run |
|
claude-security-review reviewed No security findings in this pull request. What I reviewed. All five changed files in Why nothing was flagged.
Trust controls. None of the changed files is in the listed trust-control set: the trusted-trigger check, token request, kill switch, token broker, merge holds or the other Not read. critical-findings: 0 |
Refs: melodic-software/claude-code-plugins#13586 ## Summary Contract step of the intake-triage permission expand/contract. #950 listed the old and new caller maps; melodic-software/claude-code-plugins#13660 moves the only caller to the new map (`actions: read`). This PR drops the old map, so the contract is again one exact map. Draft until melodic-software/claude-code-plugins#13660 merges: its sync would otherwise reject the caller still on main. ## Fix - `components/runner-policy/policy.json`: intake-triage's `allowedCallerPermissions` is the single map `{actions: read, contents: read, issues: write}`. ## Verification - `node --test components/runner-policy/runner-policy.test.mjs`: 232 pass, 0 fail. ## Related - #950, melodic-software/claude-code-plugins#13630, melodic-software/claude-code-plugins#13660, then melodic-software/ci-workflows#996. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Refs: melodic-software/claude-code-plugins#13586
Summary
The runner-policy contract matches a caller's permissions against
allowedCallerPermissionsexactly. standards#949 addedactions: readto 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 requiredci-statusthat is a deadlock.This PR lets a contract list several exact maps, so a permission change lands expand/contract:
actions: read.Fix
runner-policy.mjs:allowedCallerPermissionsis 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, satisfiesminimumCallerPermissions) run per map and name the failing index.policy.schema.json:allowedCallerPermissionsisoneOfa permission map or aminItems: 1,uniqueItemsarray 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.npm run lint:runner-policy: passed.cioncomponents/runner-policy: clean. markdownlint on the README: clean.Related
🤖 Generated with Claude Code