fix(branch): honor --gate-review in gx branch finish - #677
Merged
NagyVikt merged 2 commits intoJul 9, 2026
Merged
Conversation
`gx branch finish` passed its argv straight to agent-branch-finish.sh via invokePackageAsset, bypassing src/finish/index.js where runReviewGate lives. Two consequences: the script exits 1 on the unknown `--gate-review` argument, and its --via-pr path merges the moment the PR opens (the unconditional `gh pr merge` before the wait/auto fallbacks). So the documented default workflow could never gate, and merged fail-open. Split the gx-level gate flags out of the script's argv and run runReviewGate before invoking the script. It throws on a dirty review, red CI, or a PR GitHub will not merge, so the script -- and the merge -- never runs. Unrelated flags (--auto-resolve, --no-preflight, ...) still reach the script untouched. This is the gap that let lifted.sk-storefront PR #298 merge with its `review` check skipped. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Code review caught a wrong-merge-target hazard. The gate resolved the base with resolveBaseBranch, which only knows the explicit --base, the global config, and the detected default. agent-branch-finish.sh instead honors the per-branch branch.<name>.guardexBase when --base is omitted (agent-branch-finish.sh:504), as does `gx finish` via resolveFinishBaseBranch. With `branch.agent/x.guardexBase=dev` and no --base, the gate would open and review a PR against main while the shell merged into dev — reviewing one base and merging into another. Use resolveFinishBaseBranch so both agree. Cover it, plus the inline --branch=/--base= form and the no-gate-flag passthrough that every repo depends on. The suite's git stub now exposes resolveFinishBaseBranch, so a regression to the old helper fails loudly. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
NagyVikt
deleted the
agent/claude/branch-finish-honor-gate-review-2026-07-09-12-52
branch
July 9, 2026 12:31
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
gx branch finishpassed its argv straight toagent-branch-finish.shviainvokePackageAsset, bypassingsrc/finish/index.jswhererunReviewGatelives. Two consequences:--gate-reviewargument.--via-prpath callsgh pr merge --squashunconditionally right after opening the PR (agent-branch-finish.sh:1267), before the wait/auto fallbacks — i.e. it merges fail-open.So the workflow every repo's CLAUDE.md documents as the default could never gate, and merged without one.
review-gate.js's own header already noted this ("can fail open (it merged PR #610 to main with red preflight tests)") — the gate existed, but onlygx ship/gx finishever ran it.This is the gap that let
lifted.sk-storefrontPR #298 merge to production with itsreviewcheck skipped.Change
runReviewGatebefore invoking the script. It throws on a dirty review, red CI, or a PR GitHub will not merge, so the script — and the merge — never runs.--auto-resolve,--no-preflight, …) still reach the script untouched.resolveFinishBaseBranch, matching how the shell resolves an omitted--base(per-branchbranch.<name>.guardexBase). Resolving it differently would review one base and merge into another.Verification
test/branch-gate-review.test.js(8 tests): gate runs, flag stripped, fail-closed (a throwing gate never invokes the script), opt-outs, HEAD fallback, per-branch base, inline--branch=/--base=, and a byte-for-byte passthrough guard for callers without the flag.branch.js.mainbaseline (this repo is baseline-red; the failing set is byte-identical).gx branch finish --gate-reviewon a storefront branch refused to merge when the review provider errored — "Refusing to merge."Known follow-ups (from review, not blocking)
options: {}hard-codes providercodex+requireChecks;--review-provider/--allow-no-checksare not parsed on this path and would reach the shell as unknown args.GUARDEX_AUTO_SHIP=1does not enable the gate here, thoughargs.jsdocuments that it should.🤖 Generated with Claude Code