Skip to content

feat(pr-pipeline): turn path-based merge holds off behind one switch (owner Q15) - #11058

Merged
kyle-sexton merged 8 commits into
mainfrom
feat/merge-path-holds-switch
Oct 29, 2026
Merged

kyle-sexton merged 8 commits into
mainfrom
feat/merge-path-holds-switch

Conversation

@kyle-sexton

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

Copy link
Copy Markdown
Member

No related issue: owner decision Q15 (owner-decisions.md:11)

Owner, verbatim (Q15, 2026-10-29): "We shouldn't really have any path restrictions at all... like that is just bullshit friction", then "We can go in and harden later".

Owner, verbatim (scope confirmation): "I want no paths to start so things just go through... we can harden once we get our issues to 0 and PRs to 0"

Owner, verbatim (Q16, no globs kept): "No fucking path restrictions"

Hardening trigger: once open issues = 0 and open PRs = 0, turn path holds back on by setting merge.diff-check.path-holds: true in docs/conventions/pr-pipeline.yaml. The default stays off.

Summary

This PR adds one switch, merge.diff-check.path-holds (boolean, default false). It sits beside denied-paths and high-path-floor, the other path switches of the pr-merge lane under merge.diff-check. While it is off, a changed path no longer holds a lanes PR just because of the path. Setting it to true brings back every hold exactly as it was. The hold code and the floor tables (FLOOR_CLASSES, HOLD_PATH_CLASSES, hold_patterns) are unchanged. The switch is read only at the points where the holds are decided. The babysit gate reads it at both the base commit and the default-branch head, and holds when either says true. ci-status reads it from the base commit. So a PR cannot turn off its own hold.

merge.person-held does not exist on main. It existed only on the superseded #10966 (lane-arm attestation) branch, so there was nothing to remove.

Fix

Sites the switch disables (file:line at the head):

  • babysit_risk.py:2194-2221: _score moves every is_path_hold reason into RiskResult.skipped. That covers high-path:<floor or configured glob> and review-path:<glob>. RiskInput.path_holds is at :207.
  • babysit_merge_policy.py:640, 885, 934, 1049, 1125, 1196: the PipelineConfig.path_holds field, how it is read, the stricter-of-base-and-main rule, and validation.
  • babysit_merge.py:3567: passes the switch to the pr-merge lane only. The local babysit lane keeps every path hold. babysit_verify_evidence.py:2472 passes it to enable-auto-merge's reader.
  • merge-holds.mjs:389-418 (pathHold, pathHoldsOf, readPathHolds, pathHoldKind, i.e. the HOLD_PATH_FLOOR match) and :1313-1318 (holds). The CLI at :1605-1618 reads PATH_HOLDS.
  • enable-auto-merge.mjs:1219 (decide) and :1519 (no lifter read for a path that no longer holds). :648-680 lifts a standing refusal that names only hold paths, for example "it changes .github/scripts/pr-merge/clear-escalations.mjs, a hold path". It also lifts a risk refusal whose every code is a path hold, and needs no approval for either. The lift goes through the existing liftBlocker checks.
  • pr-require-checks.yml:5585-5591: ci-status's merge-holds step reads the switch from pr-pipeline.yaml at BASE_SHA and passes it as PATH_HOLDS. This step is separate from hold_patterns.
  • report-outcome.mjs heldPaths (Q16): after feat(pr-pipeline): hold lanes App human-merge pull requests with a label only a listed person lifts #11036 (human-merge-hold label), report-outcome's denied-path match becomes a label that ci-status enforces. So with the switch off it denies no path. An unreadable config still holds.
  • pr-pipeline.yaml:1093-1101 sets path-holds: false. The schema adds the key, and the README documents it.

Measurability (§9, Q15's skipped-hold count): the gate report lists each skipped hold under risk.pathHoldsSkipped. enable-auto-merge and merge-holds.mjs each log one path holds are off (merge.diff-check.path-holds), so nothing holds it for this: <reason> line per PR.

Kept holds (not path restrictions):

  • both review lanes and their bound verdicts (security findings still hold)
  • ci-status checks and gitleaks
  • do-not-merge, body holds and member vetoes
  • cost holds (COST_PATHS / cost-review-required)
  • the breaker, the kill switch and the post-merge hub audit
  • the trusted-actor widening (trust-gate:), a content check
  • the manifest review and the secret-exposure, agent-surface and permission-widening checks, all content checks
  • kept, owner may drop: high-path:**, the unsafe or aliasing path check. It covers symlinks and segments such as .., : or non-ASCII characters that could alias a cost or other path.

Not changed:

  • ci-status's trust-path hold (hold_patterns), .github/trust-path-hold.json and the ci-workflows trust-paths. Another lane owns them, and they still apply.
  • clear-escalations. A refusal it would keep is lifted by enable-auto-merge's widening read when it names only path holds. Any other refusal clears as head-moved on the next push.

Verification

Related

🤖 Generated with Claude Code

kyle-sexton and others added 3 commits October 29, 2026 16:46
…(owner Q15)

merge.diff-check.path-holds, default false: no changed path holds a pull
request for its path alone in the pr-merge lane (babysit risk scorer's
high-path:/review-path: holds, enable-auto-merge's hold paths, ci-status's
merge-holds step). True restores them. Cost, unsafe-path, manifest,
trusted-actor, body, veto and do-not-merge holds stay. Skipped holds are
named in the gate report and the lane logs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…g with path holds off

With merge.diff-check.path-holds off, enable-auto-merge also lifts a standing
risk refusal whose every code is a path hold. The live-config risk tests and
the ci-status step test now read the switch; docs qualify the path floor.

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

chatgpt-codex-connector Bot commented Oct 29, 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-29T21:09:45.753374Z e0f35b2 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.

@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

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

Incremental security review of ecb0f1b against a1f05af. I reviewed only the two changed changelog fragments, .changes/pr-pipeline/feat-merge-path-holds-switch-3c1d7a20.md and .changes/source-control/feat-merge-path-holds-switch-8e52b4f9.md. I used the PR description for context.

The change is prose only. Both fragments move bump: minor to bump: major, change the heading from ### Added to ### Changed, and add a "Breaking:" line. The line says a config that lists denied-paths or review-path: globs and has no path-holds key no longer holds on them, and that merge.diff-check.path-holds: true restores the old behavior.

  • Trust controls: No code, workflow, config value or trusted-path file changed in this increment. The fragments sit under .changes/ and match no trusted-path glob. They widen no trust control and read by no gate as a hold, a token scope or a kill switch.
  • Merge-hold weakening: The path-hold switch, which defaults to off, is in files unchanged since the last review. The new text documents it and adds nothing. The changelog now states the default-off behavior more accurately, and the major bump marks it as breaking. That is a small gain in transparency, not a loss.
  • Instruction surface: The diff deletes and softens no standing instruction. The old "Added" wording is replaced by an accurate "Changed" description.
  • Manifests: No plugin.json or marketplace.json changed, so no manifest <field> lines apply.
  • PR context: The PR description contains no embedded directives aimed at this lane. Its quoted owner statements describe intent only.
  • Cost: A major bump in the release fragments sets the next release version. It starts no billed resource and no paid plan.

critical-findings: 0

@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

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

Incremental review of the two change files edited since a1f05af. I found nothing to report.

The edit changes bump: minor to bump: major, ### Added to ### Changed, and adds a "Breaking:" line to both fragments. That matches the PR: path-holds defaults to false, so a config with denied-paths or review-path: globs and no path-holds key stops holding on them. The migration note ("Set merge.diff-check.path-holds: true") names the right key. Both fragments say the same thing, and their front matter matches the existing fragments.

I did not check how the release tooling handles a major bump. These are the only two fragments under .changes that use bump: major, so the maintainers should confirm that is what they want released.

This change only edits release-note text, so it has no cost or security impact. I did not re-review the rest of the PR, which is unchanged since the last review.

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

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

@kyle-sexton kyle-sexton added do-not-merge Hard merge gate: do not merge while applied. and removed do-not-merge Hard merge gate: do not merge while applied. labels Oct 29, 2026
@melodic-automation-lanes

Copy link
Copy Markdown
Contributor

The pr-unblock lane stopped resolve-conflicts on this pull request: the merge stages the pull request's own .github/workflows/ changes together with the base's, which the lane token cannot push, so a session merges main by hand. The lane sets no label: the run ends in a failing pr-unblock/conflict status on the head the lane gated.

When a retry on this head can change the outcome, the lane runs one on its own, up to its per-head cap, and edits this comment if it stops again; a run that does not stop clears the status. When no retry can (a review thread the lane does not take or settle, or a failing check after the retries are spent), a person resolves the threads or gets the checks green, then dispatches the workflow below: that run finds the cause gone and clears the status. On a pull request the lanes App opened, the dispatchers start that run once per stop; on any other, a person does. A new commit to the branch starts clean.

To run it again on this head now, dispatch the pr-unblock workflow:

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

…th-holds switch (owner Q16)

#11036 turns report-outcome's hold into a human-merge-hold label that
ci-status enforces, so its denied-path match is a path hold too: with
merge.diff-check.path-holds absent or false it denies no path; an
unreadable config still holds.

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 a1f05af17eee9846cf4da00b6cbb39c228a661e1; the summary is in this lane's pull request comment.

claude-lane: claude-security-review

Comment thread docs/conventions/pr-pipeline.yaml Resolved
@github-actions github-actions Bot added the needs-human Human-in-the-loop required; autonomous sessions must not resolve items carrying this. label Oct 29, 2026
@github-actions

Copy link
Copy Markdown
Contributor

claude-security-review holds this pull request for a person (critical-security) at a1f05af17eee9846cf4da00b6cbb39c228a661e1.

The change weakens the pr-merge lane's path-based merge holds: merge.diff-check.path-holds is set to false in docs/conventions/pr-pipeline.yaml:1101 (hold logic in merge-holds.mjs, enable-auto-merge.mjs, babysit_risk.py and pr-require-checks.yml). Lanes-App PRs that change the token broker, kill switch, trusted-trigger check, merge-hold scripts or review workflows can now merge without a person. The PR cites owner decision Q15, but the review could not verify it.

claude-lane: claude-security-review

@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 a1f05af17eee9846cf4da00b6cbb39c228a661e1; the summary is in this lane's pull request comment.

claude-lane: claude-review

kyle-sexton and others added 2 commits October 29, 2026 17:58
The new default turns off holds an existing denied-paths config relied on,
so both fragments move to bump: major under Changed with a migration note.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kyle-sexton kyle-sexton removed the needs-human Human-in-the-loop required; autonomous sessions must not resolve items carrying this. label Oct 29, 2026
@kyle-sexton
kyle-sexton added this pull request to the merge queue Oct 29, 2026
Merged via the queue into main with commit 182cde0 Oct 29, 2026
71 of 72 checks passed
@kyle-sexton
kyle-sexton deleted the feat/merge-path-holds-switch branch October 29, 2026 22:26
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