Skip to content

feat(claude-lanes): pass allowed-bot-sender-ids to the review lanes at ci-workflows v0.40.0 - #773

Merged
kyle-sexton merged 3 commits into
mainfrom
feat/review-allowed-bot-sender-ids
Oct 11, 2026
Merged

kyle-sexton merged 3 commits into
mainfrom
feat/review-allowed-bot-sender-ids

Conversation

@kyle-sexton

Copy link
Copy Markdown
Member

No related issue: Phase 17 of the pr-unblock lane plan; ci-workflows v0.40.0

Hold: a human merges this.

Summary

ci-workflows v0.40.0 (a92020292976c2e9b50f7adc922693a45a6c1226) adds an optional allowed-bot-sender-ids input to pr-review.yml and pr-review-security.yml. A bot whose event sender id is listed passes the reusable's bot skip, and only that sender's login reaches the action's allowed_bots. This registers that input in runner policy and has the four review caller components pass the automation-lanes App's id, so a commit the App pushes to a pull request is reviewed.

Fix

  • components/runner-policy/policy.json: pr-review.yml and pr-review-security.yml at the v0.40.0 tag, each equal to its v0.39.8 entry plus allowed-bot-sender-ids in allowedInputs. Only these two reusables are registered at v0.40.0.
  • components/claude-lanes/claude-{review,security-review}.yml and components/claude-lanes-hosted/claude-{review,security-review}.yml: re-pinned from v0.39.3 to v0.40.0, passing allowed-bot-sender-ids: ${{ vars.AUTOMATION_LANES_APP_SENDER_ID }}; header comments updated.
  • components/runner-policy/README.md: rollout note for v0.40.0.
  • components/runner-policy/runner-policy.test.mjs: REPINE_LANE_SHA_V0_40_0 and a test that each v0.40.0 entry is its v0.39.8 entry plus the input, and that exactly two v0.40.0 keys exist.

Upstream diff v0.39.8 to v0.40.0 for both reusables: the new input, the job if: (bot actor admitted only when the input is non-empty, well-formed, and contains the sender id), and allowed_bots. No secret, workflow or job permission, runs-on, or reached composite action changed. The claude-lanes lockstep declines both on inputs, so the entries are registered by hand. Moving from v0.39.3 also takes the v0.39.8 changes reviewed in #762.

Consumers without the variable

The manifest syncs these components to 11 targets. Hosted callers: agent-plugins, ci-runner, claude-code-account-rotation, claude-code-plugins, codex-plugins, cursor-plugins. Fleet callers: claude-code-proxy, dotfiles, github-iac, medley, provisioning. Only claude-code-plugins sets the repository variable AUTOMATION_LANES_APP_SENDER_ID, and no org-level variable exists (checked with gh api .../actions/variables/AUTOMATION_LANES_APP_SENDER_ID on each). GitHub returns an empty string for an unset configuration variable (contexts reference, vars), and the reusable's if: requires a non-empty list, so in the other 10 targets the review lanes still skip every bot.

Verification

  • npm run test:runner-policy: 299/299 pass. With allowed-bot-sender-ids removed from one v0.40.0 contract, 5 tests fail: the new test and the four target-audit tests for the lane callers.
  • npm run lint:runner-policy: passed.
  • claude-lanes.test.sh (materialize into every target plus actionlint), repin-callers.test.sh, repin-policy-lockstep.test.mjs (23/23), and the pin-comment scan: pass.
  • Lefthook pre-commit (editorconfig, typos, markdownlint, gitleaks, biome): pass.

Related

🤖 Generated with Claude Code

…t ci-workflows v0.40.0

Register pr-review.yml and pr-review-security.yml at the v0.40.0 tag
(a92020292976c2e9b50f7adc922693a45a6c1226), each equal to its v0.39.8
contract plus the new allowed-bot-sender-ids input, and re-pin the four
review caller components (fleet and hosted) to that tag. Each caller passes
${{ vars.AUTOMATION_LANES_APP_SENDER_ID }}, so a commit the automation-lanes
App pushes is reviewed where a repository sets the variable; where it is
unset the value is empty and the reusable still skips every bot.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kyle-sexton added a commit that referenced this pull request Oct 11, 2026
…ape (#774)

No related issue: repair standards main after ci-workflows#733

## Summary

`check-pr-convention-copies` has been red on main since
melodic-software/ci-workflows#733 (merged 2026-10-11 17:13Z) changed the
pr-contract composite's `run.sh`, for example run 38159506436. The
gate's behavior with the default pattern is unchanged; the drift checker
was reading the old source shape.

## Fix

#733 changed four things the checker anchored on:

| Checker expectation | run.sh after #733 |
|---|---|
| `match(chunk, /(close\|...)[ \t]*:?[
\t]*([a-z0-9_.-]+\/[a-z0-9_.-]+)?#[0-9]+/)) break` | `match(chunk,
closing_regex)) break`, with `closing_regex = "(close\|...)" separator
ref` and `ref` from `ENVIRON["ISSUE_REF_PATTERN"]` (default
`DEFAULT_ISSUE_REF_PATTERN='([a-z0-9_.-]+/[a-z0-9_.-]+)?#[0-9]+'`) |
| `rest ~ /^(refs\|relates[ \t]+to):...#[0-9]+[ \t]*$/)` | `rest ~
non_closing_regex)` with `non_closing_regex = "^(refs\|relates[
\t]+to):[ \t]*" ref "[ \t]*$"` |
| `linkage_errors+=('Missing a native closing keyword` |
`linkage_errors+=("Missing a ${keyword_kind} closing keyword` |
| analyzer runs with no env | analyzer reads `ISSUE_REF_PATTERN`; unset,
`ref` became `()` and 347 sample bodies (`xcloses #12`, `Closes #12x`,
...) read as closing |

Changes, all in `components/pr-convention-policy/`:

- The extractors accept both shapes. Consumers pinned before #733 still
run the inline literal, so the pin audit must keep reading it. The new
shape is rebuilt from the keyword alternation, the default separator and
`DEFAULT_ISSUE_REF_PATTERN`.
- The behavioral run passes run.sh's default as
`ISSUE_REF_PATTERN`/`DEFAULT_ISSUE_REF_PATTERN`. A run.sh that reads the
variable without declaring, falling back to and exporting the default is
drift.
- New check: action.yml's `issue-ref-pattern` default must equal
run.sh's default (or be empty). Any other value flips the analyzer to
its custom-pattern separator for every caller that leaves the input
unset.
- Fixtures: `check-contract-run.sh.txt` is now ci-workflows 8b3cc4bf28.
It is verbatim apart from one `spellchecker:ignore-next-line` awk
comment, needed because this repository's typos lane flags `ture` in an
upstream comment. The previous fixture is kept as
`check-contract-run-literal-ref.sh.txt` for the older-pin shape.

## Verification

- `npm run test:pr-convention-lockstep`: 90 pass, 0 fail. Before the
fix, the new fixture produced 37 failures.
- `npm run lint:pr-convention-copies` against live ci-workflows main:
`every copy matches policy.json`.
- Real drift still fails, with new tests for: a missing or unexported
default, a default without the `#N` grammar (both the
enforcement-pattern probe and the behavior check catch it), a default
separator losing the optional colon (the behavior check catches it), and
a mismatched action.yml default. The existing mutation tests still pass
against the new fixture.
- Biome, typos, gitleaks and editorconfig pre-commit hooks pass.

## Related

- melodic-software/ci-workflows#733 (the change being tracked)
- #773 (blocked by the red main)

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@kyle-sexton
kyle-sexton marked this pull request as ready for review October 11, 2026 18:26
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 11, 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-11T18:28:36.133144Z 57b5e61 Draft marked ready
ℹ️ 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.

@claude

claude Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 1m 31s —— View job


Code review complete

  • Gather context (PR diff, changed files)
  • Review runner-policy/policy.json + tests
  • Review claude-lanes / claude-lanes-hosted caller YAML changes
  • Review runner-policy/README.md rollout note
  • Post findings

No high-signal correctness or maintainability issues found. Summary of what I checked:

  • components/runner-policy/policy.json: the two new pr-review/pr-review-security entries at a92020292976c2e9b50f7adc922693a45a6c1226 (v0.40.0) are each their v0.39.8 entry (594987a) plus allowed-bot-sender-ids appended to allowedInputs, with no secret/permission/routing drift — matches the PR's claim, and no other reusable is registered at that SHA.
  • components/runner-policy/runner-policy.test.mjs (lines 9031–9050): the new test asserts exactly this shape (previous entry + the one appended input) and that exactly 2 keys exist at the new SHA. Follows the same pattern as the existing v0.39.8 test immediately above it.
  • The four callers (components/claude-lanes{,-hosted}/claude-{review,security-review}.yml): all four are re-pinned from v0.39.3 directly to v0.40.0 (skipping straight past v0.39.8, consistent with the stated intent of picking up both bumps at once), each adds the same allowed-bot-sender-ids: ${{ vars.AUTOMATION_LANES_APP_SENDER_ID }} input and the same header-comment wording about the bot-skip exception. The hosted/fleet pairs stay differentiated only by runner: and the pre-existing comment/concurrency differences, as before.
  • components/runner-policy/README.md (lines 1174–1183): rollout note is consistent with the policy.json diff and the PR body's description of allowed_bots behavior.
  • Grepped the whole repo for allowed-bot-sender-ids / AUTOMATION_LANES_APP_SENDER_ID — no stray or missed references; all four callers, the policy, the README, and the test agree.

One thing worth flagging, not a defect: the PR body says AUTOMATION_LANES_APP_SENDER_ID is unset in 10 of 11 synced targets, so this change is a no-op for bot review there until each target sets the repo variable — the PR already documents this clearly, so no action needed here, just noting it's expected.

Verification: I could not execute npm run test:runner-policy / npm run lint:runner-policy myself in this sandbox (no Bash approval available), so the 299/299 pass and lint-clean results in the PR body are author-claimed and unverified by me. Static review of the policy/test diff shows the asserted shape is correct by inspection.

@claude

claude Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 2m 35s —— View job


Security review in progress

  • Gather context (diff, changed files, repo instructions)
  • Check skip gate — PR open, has security-relevant surface (bot-sender admission logic), proceeding
  • Review allowed-bot-sender-ids trust-boundary logic (hunter dispatched)
  • Review runner-policy.json/test consistency (hunter dispatched)
  • Check for instruction-surface deletions
  • Verify any candidate findings
  • Post final results

@github-actions

github-actions Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

claude-review has reviewed this pull request through 2a3db40; a later push is reviewed from there.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 57b5e61c2c

ℹ️ 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".

Comment thread components/claude-lanes-hosted/claude-review.yml
@github-actions

github-actions Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

claude-security-review has reviewed this pull request through 2a3db40; a later push is reviewed from there.

… bot skip

The review-lane composition convention, the distribution README and the
sync-manifest note said both lanes skip every bot. From ci-workflows v0.40.0
a bot whose sender id the caller lists in allowed-bot-sender-ids is reviewed;
the synced callers pass AUTOMATION_LANES_APP_SENDER_ID, empty where unset.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@claude

claude Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 1m 7s —— View job


Security review complete

  • Read .claude-lane/incremental.diff
  • Read current content of the three changed files
  • Check instruction-exception-register for instruction-surface deletions
  • Hunt for security-relevant logic/trust-boundary issues
  • Post final results

Scope: incremental lane, reviewing only what changed since 57b5e61 in conventions/review/ai-review-bot-composition.md, distribution/README.md, and distribution/sync-manifest.yml. Every other file in this PR was reviewed at 57b5e61 and is out of scope here.

Finding: none.

All three hunks are prose-only reconciliation of documentation with the allowed-bot-sender-ids behavior that was already implemented and reviewed in the code files (components/claude-lanes{,-hosted}/claude-{review,security-review}.yml, components/runner-policy/policy.json) as of 57b5e61:

None of the three hunks touch a workflow if:, permission, secret, or any other enforcement mechanism — they only narrate behavior the (already-reviewed) code enforces. This isn't an instruction-surface deletion: the text adds a description of an exception the code already implements, it doesn't remove or soften a standing control, and the underlying guardrail (the reusable workflow's bot-skip if:, requiring a non-empty, well-formed, matching sender id) is unchanged and still enforced in code outside this incremental slice. docs/conventions/instruction-exception-register/README.md is not present in this checkout, so the protected-class list itself wasn't consulted — noted per the skill's fallback instruction — but consequence-based review still finds no guardrail removed or weakened here.

No GitHub Actions hardening concerns (no workflow trigger, permission, or pin changed in this slice) and no injection/credential-handling surface in plain prose/comment edits.

@claude

claude Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 1m 26s —— View job


Incremental code review — 57b5e61...2a3db40

  • Read .claude-lane/incremental.diff (scope: changes since 57b5e61)
  • Review conventions/review/ai-review-bot-composition.md
  • Review distribution/README.md
  • Review distribution/sync-manifest.yml
  • Cross-check the three files against each other and against the actual caller YAML (components/claude-lanes{,-hosted}/claude-{review,security-review}.yml) for consistency
  • Post findings

Scope note: per the lane header, only the diff since 57b5e61 in these three files was in scope; everything else in this PR was reviewed at that commit.

What changed

Commit 2a3db40 addresses Codex's P2 finding that the new allowed-bot-sender-ids allowlist (added in 57b5e61) left the bot-exclusion documentation stale. It adds one sentence each to:

  • conventions/review/ai-review-bot-composition.md: the code-review-lane bullet now states the allowed-bot-sender-ids exception and that the security lane shares it.
  • distribution/README.md / distribution/sync-manifest.yml: the matching "security lane has no path gating" paragraph/comment now parenthetically notes the same exception.

Findings

None. The added text is accurate and internally consistent:

  • It correctly states the exception is keyed on allowed-bot-sender-ids (ci-workflows v0.40.0) and that the synced callers populate it via AUTOMATION_LANES_APP_SENDER_ID — matching what all four re-pinned callers actually pass (verified in components/claude-lanes/claude-review.yml, components/claude-lanes/claude-security-review.yml, and their -hosted counterparts).
  • The three files now agree with each other on the exception's scope and trigger version.
  • distribution/README.md/sync-manifest.yml only had a bot-related sentence in this one paragraph (confirmed via grep for "bot" in both files), so there's no second, now-inconsistent mention of the old bot-exclusion behavior left unupdated in either file.
  • No change to policy, tests, or workflow behavior in this increment — docs-only, matching the diff.
    · branch feat/review-allowed-bot-sender-ids

@kyle-sexton
kyle-sexton merged commit 39f9f7d into main Oct 11, 2026
22 checks passed
@kyle-sexton
kyle-sexton deleted the feat/review-allowed-bot-sender-ids branch October 11, 2026 18:45
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