fix(merge-guard): bind privileged flags (--admin/-R/--no-verify) to the approval (#1042)#1048
Merged
michael-wojcik merged 8 commits intoJun 27, 2026
Conversation
…OT (Synaptic-Labs-AI#1042) Add PRIVILEGED_FLAGS (op-class-scoped MUST-BIND denylist) and a linear extract_privileged_flags scanner, surfaced as a bound_flags key on extract_command_context (computed once; both hook arms inherit). Behaviour-neutral foundation for never-escalate flag binding.
…te (Synaptic-Labs-AI#1042) _token_matches_command refuses when executed bound_flags differ from approved (added privilege or dropped constraint), checked after op-type and before target. Closes the --admin/-R/--no-verify ride-past bypass. Repairs 10 pre-existing tests that incidentally used now-bound flags; axis-under-test preserved.
…ynaptic-Labs-AI#1042) _mint_context_from_bundle widens the privileged-flag scan to the full selected-option text so a flag after a quoted argument is not lost to region truncation; op/target stay region-anchored. Restores read/mint scan symmetry.
…g binding (Synaptic-Labs-AI#1042) Add the privileged-flag bypass RED matrix (read-arm REFUSE for --admin / -R / --no-verify / git-abbreviation / combined-short clusters; positive AUTHORIZE form-invariance; scanner canonical-form pins; multiplicity-attribute), A1 mint-symmetry through the real mint seam, an extract_privileged_flags linearity witness, and restore non-vacuity to 5 PR-mismatch siblings. Per-mechanism non-vacuity measured by source-revert (C2 gate -> 22 RED, C3 mint -> 1 RED, is_git_surface mutation -> 9 RED). Full suite 9756 passed, 0 errors.
…witness (Synaptic-Labs-AI#1042) Review-cycle coverage hardening from the coverage-matrix pass: add the previously-uncovered -R=value short =-joined scanner branch (read-arm bypass + merge/close scanner pins + positive form-invariance) and a governed CLOSE -R real-mint witness (round-trip AUTHORIZE + redirect-add REFUSE), removing the op-agnostic-transfer dependency for the value-flag class on a second op-class.
…raint case (Synaptic-Labs-AI#1042) Add --match-head-commit (value-taking) to the merge denylist. An approval carrying --match-head-commit <sha> that is then executed without it now REFUSES via set-equality on the bound flag, closing the silent head-SHA-constraint drop.
…d-commit (Synaptic-Labs-AI#1042) Add TestMatchHeadCommitDroppedConstraint: approve-with/execute-without REFUSE, added-direction REFUSE, value-mismatch REFUSE (proves the value binds), identical AUTHORIZE, plus spaced + =-joined scanner pins. Non-vacuity measured: a source-only revert of the denylist entry reds exactly 5 of these. The approval token is scanner-derived (not hand-built) so the refusal is provably coupled to the binding.
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.
Summary
Closes a SACROSANCT merge-guard bypass: privileged flags (
--admin,-R/--repo,--no-verify) rode past the(operation, target)authorization binding because the shared command-context extractor dropped all dash-flags. An approved force-merge and the same command executed with--adminbound identically — so a branch-protection-bypassing flag executed undetected. Same binding-integrity class as #1031/#1032.What landed
merge_guard_common.py):PRIVILEGED_FLAGSop-class-scoped denylist + a linearextract_privileged_flagsscanner, surfaced as abound_flagsdimension computed once in the shared SSOT — both hook arms inherit it (un-driftable).bound_flagsis a pair attribute, never part of pair identity.merge_guard_pre.py): a never-escalate set-equality gate onbound_flagsin the read path — any added privilege OR dropped constraint refuses, unconditionally.merge_guard_post.py): the mint widened to scan the full selected-option surface (flag after a quoted argument not lost; read/mint symmetry).--match-head-commitbound (value-taking) — closes the dropped-constraint direction (approve carrying a head-SHA pin, execute without it → refuse).write_token → check_merge_authorizationpath, scanner-linearity witness,-R=value/--match-head-commitform coverage, and a--end-of-options over-block witness.The fix decomposes "privileged flag" into three effect-classes — privilege (
--admin), target-identity (-R/--repo), side-effect (--delete-branch) — bound by one set-equality mechanism. Combined-short clusters (-dR owner/repo) and the git-only unambiguous-prefix abbreviation under-block (--no-verif→--no-verify) are handled; op-trigger flags already bound viaop_typeare excluded.Verification
is_git_surface=Falsemutation → 9 abbreviation RED / 11 exact GREEN;--match-head-commitrevert → 5 RED (scanner-derived token, provably coupled).#797lifecycle / SEAM /hooks.json) verified UNCHANGED againstgit diff.Peer review
Unanimous PASS — 0 Blocking across an independent four-arm review (CODE-phase auditor + architect design-fidelity + test-engineer coverage-matrix + security-engineer adversarial, the last under an independence guard). The one residual under-block found — the dropped-constraint
--match-head-commitcase — was closed in-cycle (commits above), then verify-only re-reviewed GREEN. One Future item remains: shell-quote obfuscation of the command token, a pre-existing boundary of the guard's literal-string threat model (op-token obfuscation already bypasses the whole guard), accepted by design — not a #1042 regression.Bumps plugin 4.4.43 → 4.4.44 (PATCH — security hardening). Completes the acceptance criteria of #1042; closure pending a post-install live-probe of the installed v4.4.44 merge_guard (runtime-hook gate, per the #1031/#1032 precedent).