Skip to content

cmux guards: a merge goes to the landing gate installed from cmuxterm-hq; the repository keeps no merge guard - #23858

Merged
teamleaderleo merged 6 commits into
feat-cmux-nextfrom
lane-host/merge-guard-installed
Oct 26, 2026
Merged

teamleaderleo merged 6 commits into
feat-cmux-nextfrom
lane-host/merge-guard-installed

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 21, 2026 •

Copy link
Copy Markdown
Collaborator

After hq#2830, #23472 at 7e68847 still got "could not read #23472". Its hook already runs scripts/ci/guards-from-base.sh from origin/feat-cmux-next (#23316), but the merge guard it runs is a copy in this repository. A copy here reaches a worktree only through a fetch or a base merge, so a fix in it can lag behind. Decision (deputy-2, 2026-10-21): every merge guard runs from the copy guards-sync installs from cmuxterm-hq main (every 10 minutes), never from a copy in a worktree.

The installed landing gate (require-cmux-guards, cmuxterm-hq tools/agent-guards) already enforces every rule merge_compile_guard.py did, on the exact head of a feat-cmux-next PR that changes Swift:

  • It requires a green cmux-next Release compile (Xcode 26), using the same Swift file set.
  • Its gh reads bypass the PATH guard's repeat throttle (CMUX_GH_GUARD_DISABLE=1).
  • All its reads share one bounded budget.

Any merge merge_compile_guard.py refused, the gate refuses too, so its rules have nothing left to move.

So this PR:

Not carried over: merge_compile_guard let a fleet compile-check pass stand in for a queued Release compile. Neither the installed gate nor next-autoland ever accepted that, so it was already dead wherever the gate is installed. Accepting it would loosen the gate, and that is a separate decision.

Takes back #22947: it added the in-repo merge guard and its CI test entries; this PR removes that guard on purpose, since the installed landing gate from cmuxterm-hq judges every merge.
Takes back #23423: only its edit to tests/test_merge_compile_guard.py, which goes with the guard.
Takes back #23827: only its edit to tests/test_merge_compile_guard.py, which goes with the guard.
Takes back #24265: only its edits to the removed guard and its test; its rules (only a red compile refuses, everything else warns) are kept in guards-from-base.sh.

Base merge (2026-10-26, adopted by the stall reconciler): the merge with feat-cmux-next conflicted with #24265, which had loosened the repository guard this PR removes. I resolved it toward both: the repository still keeps no merge guard, and guards-from-base.sh follows #24265's rules (above). #24265's tests were ported to the installed gate. tests/test_guard_hooks_from_base.py passes 22/22 and tests/test_base_merge_warning.py passes at aa84860.

Earlier tests (cmux16; the test needs timeout on PATH, which Linux CI has and macOS lacks):

  • Red at 476c453: 10 of 15 failed.
  • Green at a8230d0: tests/test_guard_hooks_from_base.py passes 15/15 on Python 3.13 and on /usr/bin/python3 3.9, and tests/test_base_merge_warning.py passes 10/10.

Agent session: agent session

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

Merges are now judged by the landing gate installed from cmuxterm-hq (require-cmux-guards), never by a copy of the merge guard in this repository.

For a merge, guards-from-base.sh defers to the gate when registered in this account's settings, runs the installed gate file when present but not registered, and refuses the merge with install instructions when the gate is missing. The update-branch warning still runs from origin/feat-cmux-next.

Removed: scripts/ci/merge_compile_guard.py, its hook, tests, and the CI step that ran them. The old guard let a fleet compile-check pass stand in for a queued Release compile; the installed gate never accepted that, so that behavior is dropped too.

Written for commit a8230d0. Summary will update on new commits.

View guided diff Turn on auto-fix

teamleaderleo and others added 2 commits October 21, 2026 16:32
… refused when none is installed (red)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-hq; the repository keeps no merge guard

After hq#2830, #23472 still ran a merge_compile_guard.py copy without its
gh-throttle fix: a guard here reaches a worktree only through a fetch or a
base merge (deputy-2, 2026-10-21). Every rule it enforced is in the landing
gate guards-sync installs from cmuxterm-hq main every 10 minutes
(require-cmux-guards: the green Release compile on the exact head for a Swift
change, its gh reads past the PATH guard's throttle, one bounded budget), so
guards-from-base.sh defers to that gate when the account registers it, runs it
when only its file is installed, and refuses the merge when it is missing,
naming guards-sync and install.py. The update-branch warning still runs from
origin/feat-cmux-next.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@teamleaderleo teamleaderleo added the risk:low Risk tier (docs/ci/risk-tiers.md) label Oct 21, 2026
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Bead cx-bsped created for this PR by the cmux coordinator.

@github-actions github-actions Bot added risk:normal Risk tier (docs/ci/risk-tiers.md) and removed risk:low Risk tier (docs/ci/risk-tiers.md) labels Oct 21, 2026
@teamleaderleo

teamleaderleo commented Oct 21, 2026 •

Copy link
Copy Markdown
Collaborator Author

Owned by an agent session · session

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Orphaned: no activity for 14 h, and no lane holds a lease on it. The orphan sweep could not merge feat-cmux-next in: conflicts in .github/workflows/cmux-next.yml, scripts/ci/guards-from-base.sh, scripts/ci/merge_compile_guard.py, tests/test-execution.toml, tests/test_guard_hooks_from_base.py, tests/test_merge_compile_guard.py. Listed for a lane to resolve.

Conflicts with #24265 (merge-compile-guard: only a compile that finished red refuses) resolved toward
both: the repository still keeps no merge guard, and guards-from-base.sh takes #24265's rules. A gate
that is not installed, crashes or can't be read is a warning and the merge goes ahead; a refusal still
wins and is printed before the update-branch warning runs; every warning is joined into one answer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-707fe4a5f156f632733f
@github-actions

github-actions Bot commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

cmux status (one comment, edited in place; each line is updated by the job that owns it)

Review de377cf: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr23858 -f ref=lane-host/merge-guard-installed -f platform=macos -f backend_mode=local

teamleaderleo and others added 2 commits October 26, 2026 20:09
…cher can't be read; the merge fetch uses gtimeout where timeout is missing

From the Codex review of #23858: when origin/feat-cmux-next:scripts/ci/guards-from-base.sh could not be
read, the settings hook warned and let the merge through without running an installed but unregistered
landing gate, so its refusal was lost. And stock macOS has no timeout, so the merge-time fetch never ran
there. tests/test_guard_hooks_from_base.py: the two new tests fail on the previous hook (2 errors of 24)
and pass with this one (24/24).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-707fe4a5f156f632733f
…y under a matcher that covers Bash

From the second Codex review of #23858:
- mergePullRequest and enablePullRequestAutoMerge (gh api graphql) count as merges in both the settings
  hook and guards-from-base.sh, so an installed but unregistered gate judges them.
- guards-from-base.sh defers to a registration only when its PreToolUse matcher covers Bash.
- With no launcher to read, the settings hook runs an installed gate whether or not it looks registered
  (at worst a second read), so its refusal is never lost.
tests/test_guard_hooks_from_base.py: the new tests fail on the previous code (3 failures, 1 error of 27)
and pass with this (27/27).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-707fe4a5f156f632733f
@cursor

cursor Bot commented Oct 26, 2026

Copy link
Copy Markdown

Bugbot needs on-demand usage enabled

Bugbot uses usage-based billing for this team and requires on-demand usage to be enabled.

A team admin can enable on-demand usage in the Cursor dashboard.

…ot one that mentions it

From the third Codex review of #23858: this repository's own settings hook names require-cmux-guards.sh in
its fallback, so an account whose settings carried that hook read as registered and nothing judged the
merge. A command counts only when one of its words (shlex) is the gate's file, as install.py writes it
(bash '<hooks>/require-cmux-guards.sh'). The new test fails on the previous code (1 of 28) and passes with
this (28/28).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-707fe4a5f156f632733f
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (Codex gpt-6-astra xhigh, via review-router): SHIP at 81033a4

Four rounds. Rounds 1 to 3 said FIX FIRST, and each finding was fixed with a regression test that fails on the code before it:

  • ee1ba22: when the settings hook couldn't read the launcher, an installed gate's refusal was lost. Also, the merge fetch now falls back to gtimeout where macOS has no timeout.
  • de377cf: merges through GraphQL (mergePullRequest, enablePullRequestAutoMerge) now reach the gate. A registration now counts only under a matcher that covers Bash.
  • 81033a4: a registration is now a command that runs the gate's file, not one that only mentions it.

Round 4 found nothing. tests/test_guard_hooks_from_base.py passes 28/28 and tests/test_base_merge_warning.py passes.
Out of scope: disguised commands such as gh pr me''rge. Base matches merges the same way, and these hooks guard against mistakes by cooperating agents, not deliberate evasion.

@teamleaderleo
teamleaderleo merged commit e93a030 into feat-cmux-next Oct 26, 2026
107 of 108 checks passed
@teamleaderleo
teamleaderleo deleted the lane-host/merge-guard-installed branch October 26, 2026 20:42
@github-actions

github-actions Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant