feat: add governed runner input to three hosted-only reusables - #124
Conversation
Add the optional `runner` input (string, default `ubuntu-24.04`) and route
`runs-on` through `${{ inputs.runner }}` for link-check, standards-sync (all
three jobs), and pulumi-version-drift-check, mirroring the zizmor and
claude-review governed runner-input contracts. Permissions and every
SHA-pinned step are unchanged; the `ubuntu-24.04` default keeps direct and
public callers on the same hosted image while strict private callers pass
their governed selector output.
Wave 1 of the private-repo floor conversion (melodic-software/github-iac#78):
the reusable-source prerequisite that lets standards register runner-input
contracts for these three (Wave 2) and per-repo callers route them to the
fleet (Wave 3).
Update the Pulumi drift-guard test to assert the governed runner input and
`runs-on: ${{ inputs.runner }}` in place of the retired hosted pin.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K3QehVwmWzkBLpKokNCkkt
|
Claude finished @kyle-sexton's task in 2m 43s —— View job PR Review: feat/runner-input-hosted-only-reusables
SummaryThe change is mechanically correct and well-scoped. It mirrors the established runner-input contract from CorrectnessInput/
Input/
Input/
Test update — pulumi-deploy-guard.test.cjs Lines 152–156: The old assertion Security
Observations1. Test coverage gap for
2. The VerdictApprove. The two items above are not blockers. Observation 1 is a low-priority test-coverage improvement; observation 2 is pre-existing and informational only. The change correctly implements the governed runner-input contract and is safe to merge as the Wave 1 source-side prerequisite. |
…racts (#156) ## Summary Register `runner-input` contracts in `components/runner-policy/policy.json` for two floor-conversion reusables, both pinning ci-workflows PR #124's squash-merge commit `3dfb18452a8c6059a22e62456390d84feb10b42f` (the reviewed source that carries the governed `runner` input): - `link-check.yml` — `allowedInputs: ["runner", "args"]`, `allowedCallerPermissions: {contents: read, issues: write}`. - `pulumi-version-drift-check.yml` — `allowedInputs: ["runner"]`, `allowedCallerPermissions: {contents: read, issues: write}`. Each carries `allowedCallerPermissions` because its rolling tracking-issue lane writes issues through the caller `GITHUB_TOKEN`; the waiver is honored only while the call is genuinely selector-routed, and the reusables' own permissions are unchanged. This also corrects the now-false README claim that the Pulumi version-drift monitor "remains fixed to explicit GitHub-hosted images," adds a review note for both contracts, and extends the runner-policy golden fixture (`runner-policy.test.mjs`) to assert them. `hostedExceptionReasons` is **unchanged** — enum-tightening is the separate last wave and must not land before every consumer has dropped its floor exceptions. ## Why Wave 2 of the private-repo hosted-floor elimination (melodic-software/github-iac#78, decision of record 2026-07-16). ci-workflows PR #124 (Wave 1) added the governed `runner` input to these reusables' source; this PR registers the reviewed contracts so each private consumer (Wave 3) can add a `select-runner` job, route the reusable to the fleet, and drop its `hosted-control-plane` / `privileged-control-plane` exception. `policy.json` is the upstream source of truth synced to five consumers, so the contract belongs here. ## Deferred — standards-sync The third floor-conversion reusable, `standards-sync.yml`, is **intentionally not registered here.** Its caller `GITHUB_TOKEN` is read-only (`sync.yml` declares `permissions: contents: read`; all writes go through a minted App token), but a `runner-input` contract that passes secrets must carry `allowedCallerPermissions`, which the validator requires to include at least one `write` (`runner-policy.mjs:186-198`). There is no honest caller write to declare, so registering it would bake a least-privilege inaccuracy into the managed contract. This is a contract-model gap (the secrets waiver is coupled to a write requirement) routed to the runner-policy component owner for a "reviewed secrets + read-only caller" contract shape; `standards-sync` keeps its hosted-only contract until that lands. ## Test plan - [x] `npm run test:runner-policy` — passing with two new golden assertions on the registered contracts: 143/143 on this branch base, and 146/146 verified against a local rebase onto current `main` (post #155 review-tier admission, #153 dependabot-policy component). - [x] `npm run lint:runner-policy` (`GITHUB_REPOSITORY=melodic-software/standards`) — `Runner policy passed` on both the branch base and the current-`main` rebase (the #155 validator). - [x] biome, markdownlint — clean (pre-commit). - [x] Merge SHA finalized to `3dfb184…` (PR #124 squash-merge) across `policy.json` (both contract keys), the golden-fixture constant, and the README review note. ## Related No linked standards issue. Cross-repo references: - Wave 2 of melodic-software/github-iac#78 (private-repo hosted-floor elimination epic). - Depends on melodic-software/ci-workflows#124 (merged) — source of the pinned reusable SHA. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01K3QehVwmWzkBLpKokNCkkt --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Summary
runnerinput (type: string,default: ubuntu-24.04) and routeruns-onthrough${{ inputs.runner }}in three previously hosted-only reusable workflows:link-check.yml,standards-sync.yml(all three jobs — plan, attest, sync), andpulumi-version-drift-check.yml.zizmor.ymlandclaude-review.yml: selector-routed callers pass their runner label; theubuntu-24.04default keeps direct and public callers on the same GitHub-hosted image.uses:step are byte-for-byte unchanged.pulumi-deploy-guard.test.cjsto assert the governed runner input andruns-on: ${{ inputs.runner }}in place of the retired hosted pin.Why
Wave 1 of the private-repo floor conversion (melodic-software/github-iac#78, decision of record 2026-07-16). These three are the hosted-only privileged reusables still lacking a runner-input contract. Adding the input here is the source-side prerequisite that lets:
melodic-software/standardsregisterrunner-inputcontracts for these three merged SHAs incomponents/runner-policy/policy.json, andselect-runnerjob and route these to the fleet, dropping thehosted-control-plane/privileged-control-planeexceptions.Under the org's strict
self-hosted-onlypolicy the selector returns the fleet label or theci-runner-selection-failedsentinel (never empty), so a converted caller spends zero hosted minutes; the retainedubuntu-24.04default only serves direct and public callers, which this repo's own dogfood exercises.Scope note — source only
This PR changes only the reusable definitions. It adds/repins no caller, and no consumer references these new SHAs until Wave 2 registers them and Wave 3 wires them. The optional-default form (matching
zizmor/claude-review) is deliberate: these are scheduled maintenance jobs, not required PR checks, so they do not need the required/no-default + sentinel-guard caller contract thatosv-scannerandsemantic-pruse.Validation
actionlint(schema + expression syntax) on all three workflows — clean.node --testacross the affected and runner-posture guard suites (pulumi-deploy-guard,hosted-runner-pins,link-check,network-timeout-policy,standards-sync-app-attestation,zizmor-native,osv-scanner-pin) — 59 passed, 0 failed.select-runner.ymluntouched.Related
No linked issue.
🤖 Generated with Claude Code
https://claude.ai/code/session_01K3QehVwmWzkBLpKokNCkkt