fix(FAFF-375): harden merge-gate flag surface — drop --admin, fence --human-override/--allow-no-ci on a real TTY#285
Merged
alechill merged 2 commits intoJul 7, 2026
Conversation
…op --admin, fence --human-override/--allow-no-ci to real interactivity
…override/--allow-no-ci on a real TTY The merge interlock's value is not depending on caller discipline. Two flag-surface holes (FAFF-316 audit F2/F5) let an autonomous caller self-assert past the floor: - --admin sat in MERGE_FLAG_ALLOW and was forwarded to gh pr merge, bypassing the forge branch-protection backstop the floor itself leans on. Removed outright; any --merge-args "--admin" now lands in rejected → exit 2 via the existing token path. - --human-override / --allow-no-ci were fenced only by sibling argv flags. New pure fenceHumanFlags requires process.stdin.isTTY === true AND --interactive for both, checked before any gh call → exit 2 fail-loud naming the real-terminal remedy. decideFloor and the integrity-floor contract are untouched. Extends mergeGateSelftest + test/merge-gate.test.mjs, re-routes graft's interactive no-CI confirm to hand the human the command, and updates USAGE + docs/guide/cli.md (lint-cli-doc passes).
5 tasks
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.
Closes FAFF-375. Hardens the
faff merge-gateflag surface (FAFF-316 audit findings F2 + F5) so the mechanical merge interlock no longer depends on callers omitting a flag.What changed
--adminfromMERGE_FLAG_ALLOW— it bypasses the forge branch-protection backstop the floor leans on.--merge-args "--admin"now → exit 2 via the existing rejected-token path.fenceHumanFlags—--human-override/--allow-no-ciare honoured only whenprocess.stdin.isTTY === trueand--interactiveis present. A non-TTY (autonomous / agent-driven) invocation passing either → exit 2 fail-loud before anyghcall, naming the real-terminal remedy.decideFloorand theintegrity-floorcontract are untouched (pure-core/impure-shell split preserved).mergeGateSelftest+test/merge-gate.test.mjs(CLI-boundary, non-TTY by construction).docs/guide/cli.md(lint-cli-docpasses).Acceptance Criteria
MERGE_FLAG_ALLOWno longer contains--admin;--merge-args "--admin"→ exit 2Verified:
test/merge-gate.test.mjs"--merge-args "--admin" → exit 2" +merge-gate --selftestparseMergeArgs cases — passingfenceHumanFlagspure,{human_override,allow_no_ci,interactive,stdin_is_tty} → {ok,violations}Verified:
merge-gate --selftestfence table (7 legs) — passingdecideFloor/integrity-floorfixtures unchangedVerified:
git diff origin/mainshows no edit todecideFloor;contract integrity-floor --selftestpassingprocess.stdin.isTTY === trueafter arg validation, beforeghRepoSlug/anyghcall; violations → stderr + exit 2; applies under--check-onlyVerified: smoke
merge-gate ... --check-only --interactive --human-override(piped stdin) → exit 2, "stdin is not a TTY", no gh spawnedVerified: existing green-path tests + fence "neither flag → ok" selftest — passing
Verified:
plugin/skills/faff-graft/SKILL.mddiffmerge-gate --selftestexits 0, wired inREGION_SELFTEST_ARGVVerified:
regions selftest→ merge-gate PASSdocs/guide/cli.mdupdated;lint-cli-doc --selftestpassesVerified:
lint-cli-doc→ PASS (49 subcommands)Spec:
docs/specs/2026-07-07-FAFF-375-harden-merge-gate-flag-surface-design.md.