Repository navigation
feat(claude-lanes): admit listed bot pushers through an allowed-bots input - #665
kyle-sexton wants to merge 1 commit into
Conversation
…input Gate review jobs on the PR author rather than the pusher, and pass the same allowed-bots list through to claude-code-action so cursor[bot] pushes on human-owned PRs can be reviewed. Co-authored-by: Kyle Sexton <kyle-sexton@users.noreply.github.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 finished @kyle-sexton's task in 2m 22s —— View job Security review — no issues found
Scope: Instruction-surface check: the Gate logic (
No CRITICAL, IMPORTANT, or SUGGESTION findings. GitHub Actions hardening concerns (trigger types, permission scopes, pin freshness) are zizmor's lane and out of scope here; this review covered only the logic/trust-boundary reasoning static analysis can't do. |
|
Claude finished @kyle-sexton's task in 4m 25s —— View job Claude code review
Scope reviewed: What the change does: restructures the FindingPosted as two inline comments (same root cause, duplicated in both workflows): Summary: Everything else — the gate restructuring itself, the |
|
PR body contract — issue linkage This PR body does not yet satisfy the issue-linkage contract:
Edit the body and this comment updates itself on the next run. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 28b86ab302
ℹ️ 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".
| && (!endsWith(github.actor, '[bot]') | ||
| || contains(format(',{0},', inputs.allowed-bots), format(',{0},', github.actor))) }} |
There was a problem hiding this comment.
Normalize list entries before matching allowed bots
When a caller uses conventional comma-separated formatting such as cursor[bot], renovate[bot], the wrapped input becomes ,cursor[bot], renovate[bot],, which does not contain ,renovate[bot],; pushes by that explicitly listed bot therefore skip the job. The same expression appears in both review workflows, so normalize or validate whitespace before applying the gate.
Useful? React with 👍 / 👎.
|
claude-security-review has reviewed this pull request through 28b86ab; a later push is reviewed from there. |
| && github.event.pull_request.draft == false | ||
| && !endsWith(github.event.pull_request.user.login, '[bot]'))) | ||
| && (!endsWith(github.actor, '[bot]') | ||
| || contains(format(',{0},', inputs.allowed-bots), format(',{0},', github.actor))) }} |
There was a problem hiding this comment.
Correctness: every allowed-bots entry after the first is silently dropped when the list has a space after the comma.
contains(format(',{0},', inputs.allowed-bots), format(',{0},', github.actor)) only matches when the wrapped actor sits between two bare commas. Given allowed-bots: 'cursor[bot], dependabot[bot]' — a natural way to write a comma-separated list — the wrapped list is ,cursor[bot], dependabot[bot],. Looking up dependabot[bot] wraps to ,dependabot[bot],, but the character immediately before dependabot in the list is a space, not a comma, so that substring never appears. cursor[bot] (the first entry) is admitted; dependabot[bot] is quietly skipped even though it's in the list, with no error anywhere.
This fails closed (worst case the job just skips a bot that should have run), so it isn't a security issue, but it's a silent footgun, and the new test suite (claude-lane-job-gates.test.cjs) only ever exercises a single-entry allowed-bots list, so this never gets caught.
Fix: either document that entries must have no surrounding whitespace (cursor[bot],dependabot[bot]), or make the match whitespace-tolerant, and add a test with 2+ entries — with and without a space after the comma — asserting both are admitted.
Same construct, same bug, at claude-security-review.yml:160.
| && github.event.pull_request.draft == false | ||
| && !endsWith(github.event.pull_request.user.login, '[bot]'))) | ||
| && (!endsWith(github.actor, '[bot]') | ||
| || contains(format(',{0},', inputs.allowed-bots), format(',{0},', github.actor))) }} |
There was a problem hiding this comment.
Same comma-wrap matching bug as claude-review.yml:167: contains(format(',{0},', inputs.allowed-bots), format(',{0},', github.actor)) requires a bare comma immediately before the wrapped actor name. With allowed-bots: 'cursor[bot], dependabot[bot]' the list wraps to ,cursor[bot], dependabot[bot], — the space after the first comma means ,dependabot[bot], never appears as a substring, so dependabot[bot] is silently never admitted even though it's listed. Only the first entry (or any entry with no space after its preceding comma) reliably matches.
No test in claude-lane-job-gates.test.cjs covers a multi-entry allowed-bots list, so this is untested. Either document "no spaces around commas" explicitly, or make the match whitespace-tolerant, and add coverage for 2+ entries.
|
claude-review has reviewed this pull request through 28b86ab; a later push is reviewed from there. |
…669) No related issue: Phase 4 of the GitHub Actions conventions program (tracking: melodic-software/standards#672) ## Summary Renames this repository's workflows and actions to the org naming convention (`<stage>-<function>[-<modifier>]`, `name:` = file stem), as recorded in standards `components/github-actions-conventions/rename-map.json`. It also folds the three `-self` dogfood callers into thin jobs in `pr-require-checks.yml` (formerly `ci.yml`). This is the content of the v0.34.0 restructure release; consumers keep working on their SHA pins until they repin. ## Fix - `d1b5dc0`: `git mv` of 45 files to their mapped paths, `job_renames` applied (including `needs:` and `needs.<id>.result`), and reusables reference their own actions with `$/.github/actions/<x>` instead of a pinned full path. - `a724617`: deletes `claude-review-self.yml`, `claude-security-review-self.yml` and `issue-triage-label-self.yml`; adds jobs `pr-review`, `pr-review-security` and `intake-label-needs-triage`, each pinned to the v0.33.0 SHA of its old path with the same permissions and the one secret the `-self` file passed. It adds the `ready_for_review` and `issues: [opened, reopened]` triggers and the event guards, keeps the three folded jobs out of `ci-status`, and deletes `composites-head`, because `$/` from a `./` call already runs HEAD's composites. - `6c7ba42`: the two standards-synced composites (`comment-hygiene` and `machine-specific-paths`) are reached through `$/`. Their directories keep their old names until the standards sync destinations move. - `b2f99f9`: the folded review jobs run only on opened, synchronize, reopened and ready_for_review, which is what the `-self` files ran on. - `ci-status` keeps its job id and stays the only required check. ## Verification - Fresh-context verifier: 8 of 9 criteria pass. The ninth fails on one pre-existing naming-lint warning (job id `plan` in `maintenance-sync-standards.yml`). It is non-blocking, and the job id is unchanged from main. - `actionlint`: only the `$/ ... ref is missing` errors, which standards#675 waives through the synced config. - `node --test .github/scripts/*.test.cjs`: 192/192 pass. - naming-lint enforcing: only the two sync-managed directories remain, and they move with the standards sync-destination change. - The github-iac governance-verify draft (github-iac#598) passes against this branch. ## Related - Prerequisites, all merged: standards#675 (actionlint `$/`), #676 (lockstep drift), #677 (repin path mapping), #678 (runner-policy `$/`), and the Dependabot ignores in six repos. - Lands in lockstep with github-iac#598, followed by a self-repin PR and the v0.34.0 release. - Open PRs #663, #664 and #665 touch renamed paths and need a rebase after this merges. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
|
Closing: stale agent PR built on pre-rename paths (v0.34.0 renamed the workflows); superseded by the conventions migration. |
Closes #637.
Problem
Since #622, both Claude review lanes skip any event whose
github.actorends in[bot]. That checks who pushed, not who authored the PR. So acursor[bot]push to a PR a human opened is never reviewed.Changes
Both
claude-review.ymlandclaude-security-review.ymlnow have:workflow_callinput,allowed-bots, with an empty default, so current callers see no change.pull_requestevent, the PR must come from this repo, must not be a draft, and its author must not be a bot. A bot pusher runs the job only if it appears inallowed-bots.claude-code-actionasallowed_bots. Without it,checkHumanActorthrows for any bot actor not on the list.SECURITY MODELheaders and the README Claude lanes contract (inputs table and skips).Notes:
containsavoids partial-name matches. An empty input or*can't admit anything, because,*,never contains,cursor[bot],.author_associationclause.Testing
claude-lane-job-gates.test.cjsevaluates the gate for four combinations:dependabot[bot]It also checks that
allowed_botsis wired to the same input.node --test .github/scripts/*.test.cjs .github/actions/claude-lane-outcome/*.test.cjspasses 219 of 219.actionlint1.7.12 reports nothing on both workflows.Follow-ups outside this repo (acceptance criteria)
melodic-software/standardsrunner-policy contract must allow callers to passallowed-botsat the new pin.cursor[bot]push to a human-owned same-repo PR runs both lanes, and a Dependabot PR still skips.This PR and #664 edit the same two workflow files in different places. They merge together without conflicts.