Skip to content

feat(pr-pipeline): arm native auto-merge for lane pull requests - #9399

Merged
kyle-sexton merged 26 commits into
mainfrom
feat/pr-pipeline-arm-merge
Oct 23, 2026
Merged

kyle-sexton merged 26 commits into
mainfrom
feat/pr-pipeline-arm-merge

Conversation

@kyle-sexton

@kyle-sexton kyle-sexton commented Oct 23, 2026 •

Copy link
Copy Markdown
Member

Refs: #9276

Summary

PR 8 of the #9276 plan: lane pull requests merge through GitHub's native auto-merge. The new enable-auto-merge activity arms each clean lanes App pull request right after the issue lane opens it, and refuses or disarms one that carries a hold. ci-status, which since #9361 fails on needs-human and requires both review lanes on the head, is the gate auto-merge waits on.

Fix

  • .github/scripts/pr-merge/enable-auto-merge.mjs (no model): lists open pull requests into main and calls enablePullRequestAutoMerge(SQUASH, expectedHeadOid) on each one that the lanes App opened from this repository, that is not a draft, that opens with Closes #<issue>, and that carries no hold. A hold is the do-not-merge label, the tracker's human-gated label (needs-human), or a body hold under the gate's own rule (BODY_MERGE_HOLD_RE: a Hold: line or the do-not-merge phrase). Each candidate is also refused while a member's newest comment, review or inline comment vetoes the merge (babysit_merge.human_veto_logins, ported with a parity test), while its head changes a path in merge.diff-check.denied-paths (read from the files the head changes at each run, through report-outcome's readHoldPaths), and while a person has turned its auto-merge off. It calls disablePullRequestAutoMerge on an armed one that now fails any of those rules. It writes nothing while merge.report-only is true.
  • .github/workflows/pr-merge.yml: a new enable-auto-merge job with its own broker token (lane pr-merge, effect merge), woken by a new workflow_run trigger on work-resolve-issue completion (the merge job ignores it), by a listed human's edited/unlabeled/ready_for_review (so a new Hold: line disarms at once), and by the 15-minute schedule, which arms or disarms anything the events missed.
  • docs/conventions/pr-pipeline.yaml: the enable-auto-merge activity (effect merge) in the pr-merge lane. README section "Native auto-merge".
  • Deviations from the plan text:
    • The activity is named enable-auto-merge, not arm-merge.
    • It runs in pr-merge.yml, not work-resolve-issue.yml, because the broker mints merge only for pr-merge.yml. Basis: azure-iac src/lanes-token-broker/src/claims.mjs MERGE_CALLER = "pr-merge.yml" and authorize.mjs:308.
    • Outside the schedule the broker mints only for a listed human (authorize.mjs checkActors). An issue run started by the lanes App's own agent-ready label is therefore armed by the next scheduled run, within 15 minutes.
  • ci-status holds lanes App pull requests on their text (decision A): the new step Fail a lanes App pull request its body or a member holds in pr-require-checks.yml fails a lanes App pull request (author id 337595936, type Bot, read live) on a body hold or a member veto, on each pull_request event and in the merge_group run, so a hold added after arming fails ci-status and the merge queue removes the pull request. It reads the body, comments, reviews and inline comments live (all pages, REST, as the Python gate reads them) and runs .github/scripts/pr-merge/merge-holds.mjs as main has it (the queue's base in a merge group, the live base of a pull request into main otherwise; a pull request into another branch is not read), so a pull request cannot rewrite its own hold or run its own module with the ci-status token. An unreadable author, and a module exit 0 without its verdict line, fail closed. That module now holds BODY_HOLD, HUMAN_VETO and the newest-comment-per-member rule, and enable-auto-merge.mjs imports it, so arming and ci-status share one rule. Unreadable reads fail closed. Lifting works as before: remove the body line (the edited event re-runs ci-status), or post a later comment as the same person. A comment fires no pull_request event, so a veto posted while armed takes effect when the queue builds the group, and ci-status needs a re-run after a veto is lifted. ci-status timeout-minutes goes from 7 to 9 for the new reads' retries. AGENTS.md and the README say ci-status now reads these two holds on lanes App pull requests.
  • This reverses plan decision OD-7 ("enforce Hold: at arm/disarm" only), which the session decided. The reason: native auto-merge merges without pr-merge's gate, so a hold enforced only at arm/disarm left a window of up to 15 minutes (the schedule) in which a hold added by the lanes App or an unlisted account did not stop the merge (Codex P1 on pr-merge.yml, and pr-verify). The orchestrator chose option A for the owner.

Verification

  • node --test .github/scripts/pr-merge/*.test.mjs: 203/203 pass, plus report-outcome.test.mjs. Contract test: report-outcome's own decide() PR body arms when clean; its hold-line, hold-path and Refs: bodies do not, and changing the first-line rule fails the test. Tests that failed before their fixes cover the veto (and the regex's parity with HUMAN_MERGE_VETO_RE), a person's manual disable, hold paths on the current head, and report-only when the key is missing.
  • Decision A (48340a6, hardened in c86f268): scripts/ci-lanes-pr-hold.test.sh (new, 40 cases) runs the step body against stub gh; it fails on the base workflow (no step). It covers a Hold: line and "do not merge" in the body, a MEMBER, OWNER, COLLABORATOR, review-summary and inline veto failing, NONE, CONTRIBUTOR and bot vetoes not holding, a later comment by the same person lifting (an empty review does not, another member does not), the merge_group path failing on a body hold and a veto and passing once lifted, a person's PR and a PR into another branch skipped before any module read, and fail-closed reads. The lanes App id is checked against pr-pipeline.yaml merge.agent-identity in trusted-actors.json. scripts/check-affected.sh on eea9401: 10 passed, 3 skipped (--tests: every selected suite passes except ci-test-node-stop-commands.test.sh, which needs PyYAML this machine lacks). actionlint clean, zizmor no findings, lane coverage passes.
  • Security review of decision A (review:security-reviewer, Opus): FAIL on one P2, fixed in c86f268: a PR event read the module at the payload's base, so a lanes App PR into a branch it pushed could run its own module with ci-status's token. Also fixed: two fail-open edges (an author-less pull read, a module exit 0 without its verdict). Not fixed, for the owner: the lanes App can itself delete a Hold: line or edit its own body to lift a hold (text holds have no untrusted-lifter check like the label's); .github/scripts/pr-merge/** is not in CODEOWNERS or the babysit HIGH floor, so a lanes PR could weaken merge-holds.mjs; enable-auto-merge.mjs does not apply the HIGH path floor.
  • scripts/check-affected.sh --tests on 2f6b030: 10 passed, 4 skipped. check-lane-coverage, check-read-caller-keys, check-orphaned-fixtures, check-line-citations, check-killswitch-hoist and check-silent-skips pass. actionlint is clean. zizmor --offline .github/workflows/pr-merge.yml reports no findings.
  • Broker pin: azure-iac's pinned resolver (resolve-config.pin = 39fed34a, fetched with scripts/deploy/fetch-resolve-config.sh) runs loadConfig and resolveGrant against this branch. It accepts the config, and pr-merge:enable-auto-merge resolves to effect merge with contents/pull-requests/issues write. MERGE_EVENTS includes workflow_run. No azure-iac re-pin is needed.
  • The repository has allow_auto_merge: true.
  • UNVERIFIED: no sandbox canary has run for a lanes App token calling enablePullRequestAutoMerge, or for how expectedHeadOid interacts with the merge queue. merge.report-only is false, so this goes live when it merges.
  • Security review (review:security-reviewer, Opus): no CRITICAL.
    • Its one HIGH was checked and is incorrect. It said ci-status does not require the review lanes, but the step "Require both review lanes on this head" (pr-require-checks.yml:3357-3376, from feat(pr-pipeline): turn on review-lane holds and require both review lanes in ci-status #9361) fails on a missing, pending or failed review. The babysit_merge.py:271 comment it cited predates that step.
    • Fixed after review: the human-comment veto, the re-arm after a manual disable, and the fail-open on a missing report-only (689f2bb). Hold paths on later pushes, from pr-verify (2f6b030).
    • Not fixed: disarming may not dequeue a pull request that is already in the merge queue. The post-arm window is closed by the ci-status step above.

Related

🤖 Generated with Claude Code

kyle-sexton and others added 6 commits October 23, 2026 02:41
The pr-merge lane's new enable-auto-merge activity turns on GitHub's
native auto-merge (squash, expectedHeadOid) for each open lanes App pull
request into main that closes an issue and carries no hold, and turns it
off on an armed one that now carries a Hold: line, do-not-merge or the
human-gated label. pr-merge.yml runs it in its own job when the issue lane
finishes, on a listed human's PR edit, and on the schedule.

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

# Conflicts:
#	.github/scripts/pr-merge/workflow.test.mjs
…omments

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

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The arm rule reads the first body line as Closes #<issue>; feed it the
body report-outcome builds, clean, with its hold line, and as Refs, so
a change on either side that stops lane pull requests from arming fails
a test. Also pin that enable-auto-merge never runs on a push to main.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kyle-sexton
kyle-sexton marked this pull request as ready for review October 23, 2026 13:04
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 23, 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-23T13:06:12.648081Z ec4936f 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.

@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: ec4936f705

ℹ️ 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 .github/scripts/pr-merge/enable-auto-merge.mjs
Comment thread .github/workflows/pr-merge.yml
@github-actions

github-actions Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

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

Code review: PR #9399, arm native auto-merge for lane pull requests

I found no blocking or advisory findings, so I am not holding this pull request.

What I read: the full diff (all 14 files, .claude-lane/pr.diff) and the PR context. I also read .github/workflows/pr-merge.yml at the head to check which jobs the new workflow_run trigger could wake. I ran no tests or tools. Every verification result in the PR description (203/203, 40 shell cases, actionlint, zizmor) is author-claimed and I did not confirm it.

What I checked:

  • Trigger scope. workflow_run wakes only the new job. merge is excluded by github.event_name != 'workflow_run'. gate-check and dispatch-full-run both depend on merge, and neither passes its if when merge is skipped. post-merge-dispatch is limited to schedule and workflow_dispatch.
  • Arming rules. Hold labels, body hold, Closes #n on the first line, draft, cross-repository, head SHA shape, discussion completeness, denied paths and a person's manual disable all fail closed. Unreadable inputs leave an unarmed PR unarmed. An armed PR is disarmed only on a positive hold or on unreadable hold paths, which fails safe.
  • ci-status step. It reads the module, config and trusted actors at the base commit, never the PR head. A PR into a branch other than main is skipped before any module read. Author, base SHA, head SHA, file count and the module's verdict line each fail closed. File names are escaped before they reach a workflow command.
  • Manifests. The diff changes no plugin.json or marketplace.json, so the manifest checks do not apply. The change-fragment bump: minor fits a new activity.
  • Closing issues. The PR says Refs: #9276 and closes no issue, so there are no acceptance criteria to check.
  • Hold classes. No cost, trust-gate or critical-security hold applies. The diff adds no model call and touches no CODEOWNERS, .gitmodules or trusted-actors file. .github/standards/trusted-actors/trusted-actors.json is only read by the new code, not changed.

Notes, not findings:

  • The PR description says the ci-status timeout-minutes goes from 7 to 9. The diff changes it from 9 to 11, and the workflow comment matches the diff. The description is stale.
  • The PR author lists three unfixed items. The lanes App can lift its own text hold, .github/scripts/pr-merge/** is not in CODEOWNERS, and enable-auto-merge.mjs does not apply the HIGH path floor. Their security review is the right place for them, and I did not re-review them here.
  • The PR reports that no canary has run for enablePullRequestAutoMerge with a lanes App token, and that merge.report-only is false, so this goes live on merge. A person should weigh that risk. It is not a code defect.

@github-actions

github-actions Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

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

Security review: PR #9399 (native auto-merge for lanes App pull requests)

I found no CRITICAL issues, so I am not holding the merge. I read the full diff (.claude-lane/pr.diff) and the PR context. I did not run any code.

critical-findings: 0

Scope.

  • No plugin.json or marketplace.json changed, so there are no manifest <field> lines.
  • None of the trust-gate paths changed: .github/standards/trusted-actors/**, .github/actions/check-trusted-trigger/**, CODEOWNERS and .gitmodules.
  • The new workflow_run trigger, the new job's token request and the permissions block are GitHub Actions hardening, which zizmor's advisory lane covers. I do not repeat them. The PR reports zizmor clean.
  • I checked these and found them sound:
    • The ci-status step runs merge-holds.mjs from the base commit, not from the PR, and only for the lanes App's numeric id with type Bot.
    • A PR into a branch other than main is skipped.
    • Inputs reach the shell through env.
    • The files, discussion and config reads fail closed.
    • expectedHeadOid closes the gap between reading the head and arming it.
    • The hold-path glob handles dot-prefixed segments and renamed-from paths.
    • The workflow only ever runs main's copy of the script, and workflow_run is gated on a listed human or the schedule.

Findings

  1. SUGGESTION: unescaped file names in enable-auto-merge.mjs log lines. This has an inline comment on the file. A hold reason that names a changed file is logged without escapeCommand, so a file name containing a newline can start a workflow command on a new line.

  2. SUGGESTION: the lanes App can lift its own text hold. The PR description already discloses this. The Hold: and "do not merge" rules read the live body, and the lanes App authors and can edit that body. The Hold: line that report-outcome writes for humanMerge is not covered by any other check, such as an untrusted-lifter check. Hold paths and member vetoes are checked independently of the body, so they are not affected. The lanes App PR would first need a way to edit its own body, such as a prompt-injected follow-up lane running as the lanes App. That makes this a hardening gap rather than a demonstrated exploit. A fix would be to record the Hold: decision outside the editable body, for example as a label only a listed human can remove, and read it in merge-holds.mjs.

  3. SUGGESTION: native auto-merge skips merge-gate checks the diff does not replace.

    • The arm path and the new ci-status step re-implement only these checks: the path floor, body hold, member veto, label holds and review-lane presence. The merge gate in babysit_risk.py also checks:
      • a changed-file cap (max_changed_files, default 8);
      • Pulumi directories (pulumi_dirs);
      • the C2 contradiction checks;
      • the line caps;
      • the blast-radius check (blast_radius).
    • I found no equivalent in ci-status. I searched pr-require-checks.yml only for pulumi and the file cap and found no matches.
    • A clean Closes #N lanes PR that touches infrastructure-as-code or many files, and no denied path, would arm and merge once ci-status is green. The merge gate would have held it for a person.
    • The PR notes this ("enable-auto-merge.mjs does not apply the HIGH path floor"). The PR also lists as unverified that a lanes App token has never been canaried against enablePullRequestAutoMerge, and merge.report-only is false, so it goes live on merge.
    • I recommend either porting the missing checks into merge-holds.mjs or keeping merge.report-only: true until item 9 retires the gate. This is a control reduction the owner should accept knowingly.

I could not read docs/conventions/instruction-exception-register/README.md through the tools I was given. This diff only adds a rule and widens an AGENTS.md sentence to say ci-status now also fails on text holds for lanes App PRs, so the register lens does not change the result.

Findings not posted inline (their path, line or side is malformed):

  • .github/scripts/pr-merge/enable-auto-merge.mjs:254: severity: SUGGESTION

Unescaped changed-file names in workflow-command-capable log lines. reason from pathHold is it changes ${held}, a hold path, where held is a file name from the PR. It is printed with plain console.log on the left: line here, on the report-only would ... line, and on the disarmed: line. Only the ::error lines go through escapeCommand.

merge-holds.mjs escapes the same value (escape(...)) and has a test for it. Git allows a newline in a file name. A lanes PR that adds a file named x<newline>::add-mask::... or ::stop-commands::... starts a workflow command on its own line in the job that holds the merge-effect App token. The impact is mostly log spoofing and suppressing later annotations. set-env and add-path commands are disabled, so I don't see secret exposure. It is still an inconsistency with the sibling module.

Fix: pass reason through escapeCommand before logging (lines 254, 259, 268), or escape it inside decide.

Comment thread .github/scripts/pr-merge/enable-auto-merge.mjs
Comment thread .github/scripts/pr-merge/workflow.test.mjs
Comment thread .github/workflows/pr-merge.yml
kyle-sexton and others added 3 commits October 23, 2026 09:17
Native auto-merge skips the gate's human veto, so the arm rule now reads
each candidate's comments, reviews and inline comments and applies
babysit_merge.human_veto_logins: a member's newest comment with text
saying "do not merge" holds it (disarming an armed one), a later comment
lifts it, and a discussion it cannot read whole is not armed. Auto-merge
a person turned off is not turned back on. A missing merge.report-only
now reaches the script as report-only instead of being rewritten to
false, and the workflow test pins the workflow_run filter positively.

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

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
report-outcome's Hold: line covers only the files at opening, and native
auto-merge stays armed across later pushes. The arm rule now reads the
files the head changes now (renamed-from paths included) against the
merge lane's denied paths from the resolved config, using report-outcome's
readHoldPaths; a match leaves it unarmed or disarms it, and unreadable
hold paths or more than 300 changed files arm nothing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread docs/conventions/pr-pipeline.yaml
kyle-sexton and others added 6 commits October 23, 2026 09:48
…mber veto

Native auto-merge merges a lanes App pull request without pr-merge's gate,
so ci-status now fails on the two text holds that gate honours, on each pull
request event and in the merge queue: a body hold (a Hold: line or "do not
merge") and a member's newest comment saying not to merge. The rules move to
.github/scripts/pr-merge/merge-holds.mjs, which enable-auto-merge.mjs arms by
and ci-status runs from the base commit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A pull request event read merge-holds.mjs at the payload's base, so a lanes
App pull request into a branch it pushed could run its own module with the
ci-status token. The step now reads only pull requests into main, at their
live base, and the queue's base in a merge group. It also fails closed on an
unreadable author and on a module exit 0 without its verdict line.

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

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

claude-security-review: 1 inline finding(s) on eea9401e5bd6a519dd241b19d1c5cbba09b3e691; the summary is in this lane's pull request comment.

claude-lane: claude-security-review

Comment thread .github/scripts/pr-merge/enable-auto-merge.mjs
Comment thread .github/scripts/pr-merge/merge-holds.mjs
Comment thread .github/workflows/pr-require-checks.yml
kyle-sexton and others added 3 commits October 23, 2026 10:16
…status

ci-status's lanes App hold step now also reads the live changed files,
renamed-from paths included, against main's merge.diff-check.denied-paths
plus the floor resolve-config forces, so a push that adds a hold path after
arming fails ci-status on its own head instead of waiting for the next
scheduled enable-auto-merge run. The rule is merge-holds.pathHold, which
enable-auto-merge.mjs now imports, so arm time and ci-status share it.

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

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

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

claude-review: 1 inline finding(s) on c40ddedc62a9ccdffa4d59ec0e6cd83a409d5d87; the summary is in this lane's pull request comment.

claude-lane: claude-review

Comment thread .github/workflows/pr-require-checks.yml

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

claude-security-review: 1 inline finding(s) on c40ddedc62a9ccdffa4d59ec0e6cd83a409d5d87; the summary is in this lane's pull request comment.

claude-lane: claude-security-review

Comment thread .github/workflows/pr-require-checks.yml
kyle-sexton and others added 2 commits October 23, 2026 10:39
…old path

A hold path on a lanes App pull request failed ci-status with no way for a
person to merge it short of an admin bypass. A person on the trusted-actor
list (as main has it) now lifts it by approving the head: their newest
deciding review of the head must approve. It lifts no body hold, veto or
unreadable file list.

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

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

claude-security-review: 1 inline finding(s) on bdb63361f772160903a7a0d2de706584543482b9; the summary is in this lane's pull request comment.

claude-lane: claude-security-review

Comment thread .github/scripts/pr-merge/merge-holds.mjs Outdated
@melodic-automation-lanes melodic-automation-lanes Bot added the needs-human Human-in-the-loop required; autonomous sessions must not resolve items carrying this. label Oct 23, 2026
@melodic-automation-lanes

Copy link
Copy Markdown
Contributor

The pr-unblock lane stopped on this pull request and needs a person: a conflicted path is a workflow, submodule config or a settings file, which the lane does not resolve.

  • Reason: protected-path-conflict
  • Resume key: bdb63361f772160903a7a0d2de706584543482b9 (the head the lane stopped on)

To resume, deal with the reason above, remove the needs-human label (and do-not-merge, if set), then dispatch the pr-unblock workflow with pr-number=9399 and activity=resolve-conflicts:

gh workflow run pr-unblock.yml -R melodic-software/claude-code-plugins -f pr-number=9399 -f activity=resolve-conflicts

kyle-sexton and others added 2 commits October 23, 2026 10:50
path.matchesGlob has no dot option, so `.github/**` skipped
`.github/workflows/.x.yml` and a lanes App pull request adding one armed and
passed ci-status. matchesHoldPath marks a segment opening with "." the same
way on both sides before matching.

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

# Conflicts:
#	.github/workflows/pr-require-checks.yml

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

claude-security-review: 2 inline finding(s) on 27c4aafac2ebc998943dfcaac13176e36c377d33; the summary is in this lane's pull request comment.

claude-lane: claude-security-review

Comment thread .github/scripts/pr-merge/enable-auto-merge.mjs
Comment thread .github/scripts/pr-merge/merge-holds.mjs Outdated
kyle-sexton and others added 2 commits October 23, 2026 11:01
A held file name can carry a newline, which printed into the step log could
start a workflow command. Escape %, CR and LF in the ::error:: reasons and the
lift line.

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

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

claude-review: 1 inline finding(s) on 3e5ba980a15bbd9574313d33e7ad9fa64ab6728c; the summary is in this lane's pull request comment.

claude-lane: claude-review

Comment thread .github/workflows/pr-require-checks.yml

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

claude-security-review: 2 inline finding(s) on 3e5ba980a15bbd9574313d33e7ad9fa64ab6728c; the summary is in this lane's pull request comment.

claude-lane: claude-security-review

Comment thread .github/scripts/pr-merge/merge-holds.mjs Outdated
Comment thread .github/scripts/pr-merge/merge-holds.mjs
@melodic-automation-lanes

Copy link
Copy Markdown
Contributor

The pr-unblock lane escalated this pull request as protected-path-conflict, and that no longer holds at 3e5ba980a15bbd9574313d33e7ad9fa64ab6728c: GitHub reports no conflict with main. pr-merge removed needs-human, so the lanes run on it again. To keep a person on it, add needs-human back: a label a person adds is never removed.

@melodic-automation-lanes melodic-automation-lanes Bot removed the needs-human Human-in-the-loop required; autonomous sessions must not resolve items carrying this. label Oct 23, 2026
kyle-sexton and others added 2 commits October 23, 2026 11:09
…-status

The lanes App hold paths now add CODEOWNERS, .gitmodules and every plugin
manifest (a path-wide stand-in for the gate's executable-key check) to the
forced denied paths, at arm time and in ci-status. ci-status sets up Node
from main's .node-version before the hold step, so path.matchesGlob comes
from the pinned Node, not the runner image's.

Co-Authored-By: Claude Opus 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