Skip to content

feat(runner-policy): register the claude-lanes contracts for ci-workflows v0.65.14 - #889

Merged
kyle-sexton merged 1 commit into
mainfrom
chore/runner-policy-lane-contracts-v0.65.14
Oct 26, 2026
Merged

kyle-sexton merged 1 commit into
mainfrom
chore/runner-policy-lane-contracts-v0.65.14

Conversation

@kyle-sexton

Copy link
Copy Markdown
Member

Refs: #844

Summary

This PR registers the runner-policy contracts that the claude-lanes re-pin
(#844) needs at
ci-workflows v0.65.14
(3180217076b19bbdfccc43026c7f91c604da673d). The lockstep declined
pr-review.yml and pr-review-security.yml, because their inputs changed
since 3a2c748 (v0.55.0). It withheld maintenance-sync-standards.yml. Each of
the three is registered at the new SHA as a verbatim copy of its newest entry.

Fix

  • policy.json: pr-review and pr-review-security at 3180217 copy their
    v0.62.0 (2fe38c0) entries. maintenance-sync-standards at 3180217 copies
    its v0.55.0 (3a2c748) entry. Every earlier entry stays.
  • README.md: one rollout record after the existing v0.65.14 pr-review-cli
    record.
  • runner-policy.test.mjs: adds REPINE_LANE_SHA_V0_65_14 and a verbatim
    copy-forward test for the three paths. The feat(runner-policy): register the ci-workflows v0.65.14 pr-review-cli contract #885 v0.65.14 pr-review-cli test
    asserted that exactly one contract sits at 3180217, and this PR adds three
    more. That count is dropped. The test's deepEqual copy-forward assertion
    stays.

Security review, v0.55.0 (3a2c748) to v0.65.14 (3180217)

Both revisions of each file were parsed and compared on on,
workflow_call inputs, secrets and outputs, top-level and job permissions,
runs-on, needs, job if, and which steps reference which secrets.

Change Class Evidence
New input credential-name (string, default CLAUDE_CODE_OAUTH_TOKEN). It holds a secret's name, never its value (a) optional, not passed by any caller, not allowed pr-review.yml@3180217:205-214, pr-review-security.yml@3180217:183-192
New input fallback-credential-name (string, default empty) (a) optional, not passed, not allowed pr-review.yml@3180217:215-222, pr-review-security.yml@3180217:193-200
New step first-attempt-outcome (report-lane-outcome, no secret). It runs only when the fallback attempt runs, which needs fallback-claude-code-oauth-token, and no allowed caller maps that secret (a) no new trust pr-review.yml@3180217:1030-1043
claude-code-action f27be6b (v1.0.252) to 5eb090f3 (v1.0.253) in both credential steps. It is one upstream commit that bumps the Claude Code and Agent SDK versions none. Already hand-reviewed at v0.59.1 (README record) pr-review.yml@3180217:861,1050
Isolation install step: gains id: isolate, uses one bounded apt-get deadline, and fails without socat. The status job classifies a failure there as install-failed none, no secret, no permission pr-review.yml@3180217:804-838,1397,1421-1425
The result step raises a findings count that is below the summary's manifest <field>: flag lines none pr-review.yml@3180217:1227-1241
report-lane-outcome ($/ action) writes the lane-outcome record. It uses no new secret, network call or exec, and keeps the same actions/github-script pin none .github/actions/report-lane-outcome/action.yml@3180217:191
workflow_call secrets, outputs, on, workflow permissions (contents: read), job permissions (contents: read, pull-requests: write, id-token: write) unchanged parsed at both SHAs
maintenance-sync-standards.yml unchanged. The blob 93c4c18 is the same at both SHAs contents API

There is no class (b), meaning a removed or renamed input that a component
still passes, and no class (c), meaning a change that widens trust.

Verification

  • At this commit, node --test components/runner-policy/*.test.mjs components/claude-lanes/*.test.mjs
    passes 391 of 391, claude-lanes.test.sh passes 86 of 86, and
    repin-callers.test.sh passes 165 of 165.
  • I applied a simulated re-pin in a scratch worktree: all nine caller pins moved
    from 3a2c748 to 3180217. On top of this commit, the same suites pass, and
    so does managed-files-guard.test.sh (175 of 175). With this PR's
    policy.json reverted, 5 runner-policy tests fail, including "every managed
    target of a claude lane caller admits that caller".

Related

Owner decisions not taken here

  • The allowed inputs are copied verbatim, so they still admit some inputs that
    no synced component passes: incremental-review and model-args on both
    lanes, and manifest, standards-ref and environment on the sync
    reusable. This keeps the copy-forward shape. It also keeps admitting any
    consumer-owned caller that passes them. Narrowing them is a separate decision.
  • No component maps fallback-claude-code-oauth-token. Only the pr-review-cli
    contracts (v0.65.12 and later) allow FALLBACK_CLAUDE_CODE_OAUTH_TOKEN. The
    chore(claude-lanes): re-pin callers to ci-workflows v0.65.14 #844 re-pin alone therefore gives the pr-review and pr-review-security
    lanes no fallback attempt. Getting one takes a component change plus an
    allowed-secret addition.

🤖 Generated with Claude Code

…lows v0.65.14

The claude-lanes re-pin (#844) moves pr-review, pr-review-security and
maintenance-sync-standards off v0.55.0. Register each at the v0.65.14 tag
3180217 as a verbatim copy of its newest entry: the review lanes from
v0.62.0, whose only change since is the isolation install step's id and
its install-failed class, and maintenance-sync-standards from v0.55.0,
byte-identical at both tags. No input, secret, caller permission or
routing widens.

The v0.65.14 pr-review-cli test no longer counts every contract at the
tag, which this registration adds to.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-26T09:44:51.182866Z aa6b1b1 PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions

Copy link
Copy Markdown

claude-security-review reviewed aa6b1b151def7c608fac159feb368ec63c2f126e: 0 finding(s), 0 as inline comments.

No security findings in this PR.

critical-findings: 0

What the PR changes. It adds three entries to the approvedReusableWorkflowContracts allowlist in components/runner-policy/policy.json, all at ci-workflows 3180217076b19bbdfccc43026c7f91c604da673d (v0.65.14): pr-review.yml, pr-review-security.yml and maintenance-sync-standards.yml. It also adds a README rollout record and a copy-forward test.

Why I found nothing. I compared each new entry with its stated predecessor in the file: pr-review and pr-review-security against the 2fe38c0 (v0.62.0) entries, and maintenance-sync-standards against the 3a2c748 (v0.55.0) entry.

  • Each new entry is a verbatim copy of its predecessor, field for field. That covers routing, runnerInput, allowedInputs, allowedSecrets and allowedCallerPermissions.
  • Nothing widens who or what the policy admits: no new input, no new secret mapping, no permission change.
  • The new credential-name and fallback-credential-name inputs, and FALLBACK_CLAUDE_CODE_OAUTH_TOKEN, stay unallowed on these entries. No caller can pass them, which is the same posture as before.
  • The only trust-relevant change is that the v0.65.14 SHA is now an admitted pin for these three workflows. That is the stated purpose of the PR. The same SHA is already admitted for pr-review-cli through feat(runner-policy): register the ci-workflows v0.65.14 pr-review-cli contract #885.
  • The test change drops the "exactly one contract at this SHA" count, because three more now sit there. The deepEqual copy-forward assertion stays, and the new test applies it to all three paths, so a later edit that widens one of these entries would fail the test.

Limits of this review.

  • I did not independently confirm that 3180217 is the v0.65.14 tag. The API call needed approval, so I skipped it. The PR body and the existing pr-review-cli entry for the same SHA agree on it.
  • I did not re-read the upstream ci-workflows diff. The PR's own comparison of upstream v0.55.0 to v0.65.14 is data to me, not something I verified.
  • The runner-policy component is not on the listed trusted or hold paths and is not an instruction surface. No plugin manifests changed.
  • The PR body is ordinary description text. It contains no embedded instructions aimed at the reviewer.

Owner decisions the PR raises, neither of which is a finding: the verbatim copy still admits incremental-review, model-args, manifest, standards-ref and environment, which no synced component passes. And the pr-review and pr-review-security lanes get no fallback credential attempt until a later component change.

@github-actions

Copy link
Copy Markdown

claude-review reviewed aa6b1b151def7c608fac159feb368ec63c2f126e: 0 finding(s), 0 as inline comments.

No findings. I reported nothing inline.

What I checked

  • I compared the three new policy.json entries with the entries they claim to copy, by reading them in the file. The comparison was by eye, not a programmatic diff.
    • pr-review@3180217 matches pr-review@2fe38c0: same routing, the five allowed inputs, the CLAUDE_CODE_OAUTH_TOKEN secret and the caller permissions.
    • pr-review-security@3180217 matches pr-review-security@2fe38c0.
    • maintenance-sync-standards@3180217 matches maintenance-sync-standards@3a2c748.
  • In runner-policy.test.mjs, the new REPINE_LANE_SHA_V0_65_14 constant is the same SHA the policy.json keys use. The REPINE_LANE_SHA_V0_55_0 and REPINE_LANE_SHA_V0_62_0 constants it relies on already exist. The new copy-forward test uses deepEqual against each predecessor and asserts that the predecessor exists, so a missing or drifted entry fails with a named message.
  • The PR drops the "exactly one contract at 3180217" count from the feat(runner-policy): register the ci-workflows v0.65.14 pr-review-cli contract #885 pr-review-cli test. That assertion would fail now that four contracts share the SHA, and the PR body explains the drop. The deepEqual copy-forward check in that test stays.
  • The README rollout record matches the policy entries and the PR body: credential-name and fallback-credential-name stay unallowed, and maintenance-sync-standards is byte-identical at both tags.
  • Closing issues: the PR says Refs: #844, so there is no closing issue and no acceptance criteria to check.
  • The PR body follows the contract: it opens with a Refs: line and has the Summary, Fix, Verification and Related sections.
  • There is no plugin manifest change, so there are no manifest <field> lines.
  • Paved paths: I did not resolve the standards index. The diff adds no second way of doing something.

Not run
The sandbox blocked node --test. The test counts in the PR body (391/391, 86/86 and so on) are author-claimed and I did not confirm them.

Security scope
The PR's v0.55.0 to v0.65.14 trust analysis (new optional inputs, a new step with no secret, an action bump) is the author's own. I did not check it against the upstream workflows. The policy entries it registers add no new allowed inputs, secrets or caller permissions over their predecessors.

@kyle-sexton
kyle-sexton merged commit fc516bf into main Oct 26, 2026
22 checks passed
@kyle-sexton
kyle-sexton deleted the chore/runner-policy-lane-contracts-v0.65.14 branch October 26, 2026 09:53
kyle-sexton added a commit that referenced this pull request Oct 26, 2026
…sfying lockstep (#890)

No related issue: the defect was found while the claude-lanes repin lane
PR (#844) stayed on the human checklist after the contracts were
registered (#889).

## Summary

`planLockstep` declined any re-pinned caller whose security surface
changed from its old pin. It never checked whether `policy.json` already
holds a reviewed contract for `<workflowPath>@<newSha>`, though
`copyReusableContract` does. The repin lane PR (#844) carried
"Runner-policy lockstep requires a human" from 2026-10-22 and kept it
after #889 registered the v0.65.14 contracts, with CI green.

## Fix

`planLockstep` takes a `hasContract(path, sha)` predicate (default:
none). After the renamed-path decline, a pin whose new-SHA contract
exists is skipped: neither declined nor copied, and no upstream fetch.
The renamed-path decline is unchanged, since a rename always needs a
hand-reviewed entry. `main` passes a lookup into
`policy.approvedReusableWorkflowContracts`.

## Verification

- `node --test components/claude-lanes/repin-policy-lockstep.test.mjs`:
26 pass, including three new cases (surface changed with an existing
contract is satisfied; surface changed with none is still declined; a
rename with a contract at the new path is still declined).
- `bash harness/shell/run-tests.sh
components/claude-lanes/repin-callers.test.sh`: pass.
- `npx biome check components/claude-lanes/`: clean.

## Related

Refs: #844, #889

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01DpzEJAE4EMndcWQXiKSZYn

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant