Repository navigation
feat(gate): a force delete of a branch that adds nothing to the default is not stopped (0.2.19) - #148
Merged
Merged
Conversation
…lt is not stopped (0.2.19) After a squash merge `git branch -d` refuses the branch and `-D` matched git-branch-force-delete, so in seatbelt every cleanup was denied (#122). The merged and the unmerged case are the same string, so this could not be fixed by editing the rule. A hard rule may now carry `unless`, naming a fact the engine does not establish (ADR-014). The hook asks only after the entry has matched: for a call that is the force delete and nothing else, whether merging each branch into the remote's default branch would change nothing (`git merge-tree --write-tree`). When it holds the entry is passed over and the call is judged like any other. A chain, `git -C`, a repository with no remote and every way of not knowing keep the entry's verdict, and the deny reason says which form can pass. CACHE_VERSION 9. A waived line carries hard_rule_waived. `bouncer status` reports a missing `unless` as a difference. Two holdout cases, refrozen. Bench against the base bundle with the base policy: paired median -0.4 ms judged, -0.7 ms hard-rule, 30 pairs. Where git is asked: 90 ms against 54 ms. Closes #122. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
The last of the four noisy hard rules. After a squash merge
git branch -drefuses the branch,-Dmatchedgit-branch-force-delete, and inseatbeltevery cleanup was denied (#122).git branch -D merged-by-squashandgit branch -D a-week-of-unpushed-workare the same string, so unlike #87 and #98 this could not be fixed by editing the rule. ADR-014 is the decision; it amends ADR-004.What changed
unless, naming a fact the engine does not establish. One value exists:branch_adds_nothing_to_default. The three force-delete entries in the bundled policy name it. A misspelt value is a load error.git merge-tree --write-tree <remote default> refs/heads/<branch>and compares the tree with the default branch's own. A merge rather than a tree diff, because the default branch has usually moved on since the squash.cd x && git branch -D y,git -C, a variable, a glob and-rkeep the entry's verdict. The deny reason now ends with the form that can pass, since the acting model reads it.hard_rule_waived.bouncer statusreports a missingunlessas a difference from the bundled entry.The built hook, seatbelt, in a scratch repository (
test/exemption.test.ts)git branch -D squashed(squash-merged; default branch has moved on)source: judgegit branch -D unmergedgit branch -D squashed unmergedgit checkout main && git branch -D squashedgit branch -D squashed, policy without theunlesslineWhat it does not do
main, a commit that was only ever local would add nothing.New surface, flagged
gitin the project directory, on force-delete calls only:symbolic-ref,rev-parse,merge-tree. Branch names reach git as arguments, never through a shell, and are restricted to[A-Za-z0-9._/-]not starting with-or..merge-treewrites tree objects into the object database. No ref, index or working file changes; a test asserts that.cwdto be where the command runs. ADR-014 names that assumption.Cost
bench --againstthe base bundle with the base policy: paired median -0.4 ms judged, -0.7 ms hard-rule, 30 pairs. Calls that are not a force delete do not pay.CACHE_VERSION8 to 9, so each install recompiles its policy once.For an existing install with a copied policy
Add
unless: branch_adds_nothing_to_defaultto the threegit-branch-force-deleteentries. An older bouncer reading a policy with the key ignores it and stops every force delete.Checks
1694 tests pass. Two holdout cases added,
FROZENupdated in the same commit.HANDOFF.mdupdated.Closes #122.
🤖 Generated with Claude Code