From f675cbf1debce1a4fbf10ceb3f7730e0cd381327 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Sat, 10 Oct 2026 17:53:21 -0400 Subject: [PATCH 1/3] feat(runner-policy): add ci-workflows v0.39.8 contracts Register the nine ci-workflows reusables at the v0.39.8 tag 594987abe8657a40bccc13d301f1f0d5cccb5348. No workflow_call input, secret, permission or runs-on routing changed since v0.39.3, so each contract equals its v0.39.3 entry. The v0.39.3 entries stay until every consumer repins. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_01TRhsMPSTMFo99ik7gkdgQt --- components/runner-policy/README.md | 16 +++ components/runner-policy/policy.json | 121 ++++++++++++++++++ .../runner-policy/runner-policy.test.mjs | 33 +++++ 3 files changed, 170 insertions(+) diff --git a/components/runner-policy/README.md b/components/runner-policy/README.md index 8450826b..fb8d76ac 100644 --- a/components/runner-policy/README.md +++ b/components/runner-policy/README.md @@ -1154,6 +1154,22 @@ Once every consumer pinned v0.39.3, every v0.38.2 (`cf316d1`) and v0.39.0 key was retired under step 4 of the lockstep below, so `policy.json` admits ci-workflows only at `ab83b01`; the review notes in this section stay as the record the v0.39.3 terms were copied from. +All nine are also registered at the v0.39.8 tag +`594987abe8657a40bccc13d301f1f0d5cccb5348`, and each contract equals its +v0.39.3 entry: no reusable's `workflow_call` inputs, secrets, workflow or job +permissions, or `runs-on` routing changed between the two tags. Four blobs are +byte-identical (`intake-label-needs-triage`, `pr-scan-dependencies`, +`pr-audit-workflows`, `pr-automerge-dependabot`), and the claude-lanes lockstep +copies them. It declines the other five, which were signed off by hand on +2026-10-10. `intake-triage`, `pr-review` and `pr-review-security` bump +`anthropics/claude-code-action` from v1.0.241 to v1.0.245 (`6fed3ca`) on the +step that receives `CLAUDE_CODE_OAUTH_TOKEN`, so their credential references +change; `pr-review` and `pr-review-security` also reword the rate-limit +failure summary, and `$/report-lane-outcome` rewords only its rate-limit error +message. `maintenance-sync-standards` bumps `actions/setup-node` from v7.0.0 +to v7.1.0 (`949feb2`) and is declined on shape, because its `sync` job routes +through `needs`. `pr-run-checks` keeps its blob, but its `$/markdownlint` +action tree takes the same `setup-node` bump. The Zizmor contract at `de50a08b6093d231519ee7a4c9371db76c0a7e1e` uses its reviewed `runner` input and checksum-verified native Linux binary, so enrolled consumers may route that advisory lane onto the managed fleet diff --git a/components/runner-policy/policy.json b/components/runner-policy/policy.json index 9e9ad8e2..32183ea5 100644 --- a/components/runner-policy/policy.json +++ b/components/runner-policy/policy.json @@ -19,6 +19,24 @@ "issues": "write" } }, + "melodic-software/ci-workflows/.github/workflows/intake-triage.yml@594987abe8657a40bccc13d301f1f0d5cccb5348": { + "routing": "runner-input", + "runnerInput": "runner", + "allowedInputs": [ + "runner", + "allowed-labels", + "escalation-label", + "instructions", + "cli-version" + ], + "allowedSecrets": { + "CLAUDE_CODE_OAUTH_TOKEN": "${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}" + }, + "allowedCallerPermissions": { + "contents": "read", + "issues": "write" + } + }, "melodic-software/ci-workflows/.github/workflows/pr-review.yml@ab83b01273026ab5c23c6f3b40e946d97a863fa2": { "routing": "runner-input", "runnerInput": "runner", @@ -32,6 +50,19 @@ "id-token": "write" } }, + "melodic-software/ci-workflows/.github/workflows/pr-review.yml@594987abe8657a40bccc13d301f1f0d5cccb5348": { + "routing": "runner-input", + "runnerInput": "runner", + "allowedInputs": ["runner", "incremental-review"], + "allowedSecrets": { + "CLAUDE_CODE_OAUTH_TOKEN": "${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}" + }, + "allowedCallerPermissions": { + "contents": "read", + "pull-requests": "write", + "id-token": "write" + } + }, "melodic-software/ci-workflows/.github/workflows/pr-review-security.yml@ab83b01273026ab5c23c6f3b40e946d97a863fa2": { "routing": "runner-input", "runnerInput": "runner", @@ -45,6 +76,19 @@ "id-token": "write" } }, + "melodic-software/ci-workflows/.github/workflows/pr-review-security.yml@594987abe8657a40bccc13d301f1f0d5cccb5348": { + "routing": "runner-input", + "runnerInput": "runner", + "allowedInputs": ["runner", "incremental-review"], + "allowedSecrets": { + "CLAUDE_CODE_OAUTH_TOKEN": "${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}" + }, + "allowedCallerPermissions": { + "contents": "read", + "pull-requests": "write", + "id-token": "write" + } + }, "melodic-software/ci-workflows/.github/workflows/intake-label-needs-triage.yml@ab83b01273026ab5c23c6f3b40e946d97a863fa2": { "routing": "runner-input", "runnerInput": "runner", @@ -54,6 +98,15 @@ "issues": "write" } }, + "melodic-software/ci-workflows/.github/workflows/intake-label-needs-triage.yml@594987abe8657a40bccc13d301f1f0d5cccb5348": { + "routing": "runner-input", + "runnerInput": "runner", + "allowedInputs": ["runner", "label", "label-prefix"], + "allowedSecrets": {}, + "allowedCallerPermissions": { + "issues": "write" + } + }, "melodic-software/ci-workflows/.github/workflows/pr-scan-dependencies.yml@ab83b01273026ab5c23c6f3b40e946d97a863fa2": { "routing": "runner-input", "runnerInput": "runner", @@ -63,6 +116,15 @@ "contents": "read" } }, + "melodic-software/ci-workflows/.github/workflows/pr-scan-dependencies.yml@594987abe8657a40bccc13d301f1f0d5cccb5348": { + "routing": "runner-input", + "runnerInput": "runner", + "allowedInputs": ["runner"], + "allowedSecrets": {}, + "minimumCallerPermissions": { + "contents": "read" + } + }, "melodic-software/ci-workflows/.github/workflows/maintenance-sync-standards.yml@ab83b01273026ab5c23c6f3b40e946d97a863fa2": { "routing": "runner-input", "runnerInput": "runner", @@ -72,6 +134,15 @@ "STANDARDS_SYNC_APP_PRIVATE_KEY": "${{ secrets.STANDARDS_SYNC_APP_PRIVATE_KEY }}" } }, + "melodic-software/ci-workflows/.github/workflows/maintenance-sync-standards.yml@594987abe8657a40bccc13d301f1f0d5cccb5348": { + "routing": "runner-input", + "runnerInput": "runner", + "allowedInputs": ["runner", "manifest", "standards-ref", "dry-run", "targets", "environment"], + "allowedSecrets": { + "STANDARDS_SYNC_APP_CLIENT_ID": "${{ secrets.STANDARDS_SYNC_APP_CLIENT_ID }}", + "STANDARDS_SYNC_APP_PRIVATE_KEY": "${{ secrets.STANDARDS_SYNC_APP_PRIVATE_KEY }}" + } + }, "melodic-software/ci-workflows/.github/workflows/pr-audit-workflows.yml@ab83b01273026ab5c23c6f3b40e946d97a863fa2": { "routing": "runner-input", "runnerInput": "runner", @@ -82,6 +153,16 @@ "security-events": "write" } }, + "melodic-software/ci-workflows/.github/workflows/pr-audit-workflows.yml@594987abe8657a40bccc13d301f1f0d5cccb5348": { + "routing": "runner-input", + "runnerInput": "runner", + "allowedInputs": ["runner", "paths", "fail-on-severity"], + "allowedSecrets": {}, + "allowedCallerPermissions": { + "contents": "read", + "security-events": "write" + } + }, "melodic-software/ci-workflows/.github/workflows/pr-automerge-dependabot.yml@ab83b01273026ab5c23c6f3b40e946d97a863fa2": { "routing": "runner-input", "runnerInput": "runner", @@ -92,6 +173,16 @@ "pull-requests": "write" } }, + "melodic-software/ci-workflows/.github/workflows/pr-automerge-dependabot.yml@594987abe8657a40bccc13d301f1f0d5cccb5348": { + "routing": "runner-input", + "runnerInput": "runner", + "allowedInputs": ["runner"], + "allowedSecrets": {}, + "allowedCallerPermissions": { + "contents": "write", + "pull-requests": "write" + } + }, "melodic-software/ci-workflows/.github/workflows/pr-run-checks.yml@ab83b01273026ab5c23c6f3b40e946d97a863fa2": { "routing": "runner-input", "runnerInput": "runner", @@ -121,6 +212,36 @@ "contents": "read", "pull-requests": "read" } + }, + "melodic-software/ci-workflows/.github/workflows/pr-run-checks.yml@594987abe8657a40bccc13d301f1f0d5cccb5348": { + "routing": "runner-input", + "runnerInput": "runner", + "allowedInputs": [ + "runner", + "filters", + "timeout-minutes", + "typos", + "gitleaks", + "editorconfig", + "markdown", + "shellcheck", + "actionlint", + "exec-bit", + "machine-specific-paths", + "eol-renormalize", + "comment-hygiene", + "lychee-offline", + "check-jsonschema", + "check-jsonschema-files", + "check-jsonschema-builtin-schema", + "machine-specific-paths-exclude", + "comment-hygiene-exclude" + ], + "allowedSecrets": {}, + "minimumCallerPermissions": { + "contents": "read", + "pull-requests": "read" + } } }, "approvedHostedRunnerLabels": ["ubuntu-24.04", "windows-2025"], diff --git a/components/runner-policy/runner-policy.test.mjs b/components/runner-policy/runner-policy.test.mjs index c688b3fe..ac63cb4a 100644 --- a/components/runner-policy/runner-policy.test.mjs +++ b/components/runner-policy/runner-policy.test.mjs @@ -36,6 +36,7 @@ const REPINE_LANE_SHA_V0_28_1 = "cc0462990687534e9597de9e00ab89d3dcca61d2"; const REPINE_LANE_SHA_V0_29_0 = "6567856ef6070a4a1c9c2691f610278a7f2de153"; const REPINE_LANE_SHA_V0_29_1 = "0d3e6a6f3851cf678f82fa9a8a17f10faa909ac9"; const REPINE_LANE_SHA_V0_30_1 = "35880dcbb2f174aac90159e276dc7eddf1bc20b9"; +const REPINE_LANE_SHA_V0_39_8 = "594987abe8657a40bccc13d301f1f0d5cccb5348"; const STANDARDS_SYNC_SHA = "35f2684ac953794b854bac1959df00e74eeca1d9"; const REUSABLE_PATH = "melodic-software/ci-workflows/.github/workflows/osv-scanner.yml"; const REUSABLE_REFERENCE = `${REUSABLE_PATH}@${SHA}`; @@ -8993,6 +8994,38 @@ test("every reusable contract at the v0.30.1 tag copies its v0.29.1 entry forwar } }); +// v0.39.8 moves no input, secret, permission or routing field: the claude +// lanes bump claude-code-action, the sync lane and the markdownlint action bump +// setup-node, and the other reusables are byte-identical. +test("every reusable contract at the v0.39.8 tag copies its v0.39.3 entry forward verbatim", () => { + const contracts = BASE_POLICY.approvedReusableWorkflowContracts; + const reusables = [ + "intake-triage", + "intake-label-needs-triage", + "maintenance-sync-standards", + "pr-audit-workflows", + "pr-automerge-dependabot", + "pr-review", + "pr-review-security", + "pr-run-checks", + "pr-scan-dependencies", + ]; + for (const reusable of reusables) { + const workflowPath = `melodic-software/ci-workflows/.github/workflows/${reusable}.yml`; + const previous = contracts[`${workflowPath}@${LIVE_CI_WORKFLOWS_SHA}`]; + assert.ok(previous, `expected a v0.39.3 contract for ${reusable}`); + assert.deepEqual( + contracts[`${workflowPath}@${REPINE_LANE_SHA_V0_39_8}`], + previous, + `${reusable} at the v0.39.8 tag is not a verbatim copy of its v0.39.3 entry`, + ); + } + assert.equal( + Object.keys(contracts).filter((key) => key.endsWith(`@${REPINE_LANE_SHA_V0_39_8}`)).length, + reusables.length, + ); +}); + // Convergence as a property, never as a hardcoded SHA. The daily // claude-lanes-repin lane rewrites these components on every ci-workflows // release, and a test naming one revision would go red by construction on From 79f7abf0783475a92ba549744617ae163049718a Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Sat, 10 Oct 2026 17:55:31 -0400 Subject: [PATCH 2/3] ci: re-run checks on the ready head Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_01TRhsMPSTMFo99ik7gkdgQt From f357f5b9f4fa44205c8083a71b830753baf5cc58 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Sat, 10 Oct 2026 18:00:04 -0400 Subject: [PATCH 3/3] docs(runner-policy): record the v0.39.8 entries as hand-registered The lockstep's comparison found four surfaces unchanged, but its declines suppress every write, so all nine entries were added by hand. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_01TRhsMPSTMFo99ik7gkdgQt --- components/runner-policy/README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/components/runner-policy/README.md b/components/runner-policy/README.md index fb8d76ac..b12e5fbe 100644 --- a/components/runner-policy/README.md +++ b/components/runner-policy/README.md @@ -1159,9 +1159,10 @@ All nine are also registered at the v0.39.8 tag v0.39.3 entry: no reusable's `workflow_call` inputs, secrets, workflow or job permissions, or `runs-on` routing changed between the two tags. Four blobs are byte-identical (`intake-label-needs-triage`, `pr-scan-dependencies`, -`pr-audit-workflows`, `pr-automerge-dependabot`), and the claude-lanes lockstep -copies them. It declines the other five, which were signed off by hand on -2026-10-10. `intake-triage`, `pr-review` and `pr-review-security` bump +`pr-audit-workflows`, `pr-automerge-dependabot`), and the claude-lanes +lockstep's surface comparison finds them unchanged. It declines the other five, +and because any decline suppresses every lockstep write, all nine entries were +registered by hand and signed off on 2026-10-10. `intake-triage`, `pr-review` and `pr-review-security` bump `anthropics/claude-code-action` from v1.0.241 to v1.0.245 (`6fed3ca`) on the step that receives `CLAUDE_CODE_OAUTH_TOKEN`, so their credential references change; `pr-review` and `pr-review-security` also reword the rate-limit