Repository navigation
Normalize claim scopes and enforce them at push time - #19
Merged
Merged
Conversation
Ports the scope fixes from PR #10 (review findings 3 and 4) onto the approval-authority work in #12. PR #10's self-approval and worktree reclaim changes are not carried over; #12 covers those. - Scope globs are normalized when a claim is made (./, //, leading /, backslashes, ..) and stored in that form. Overlap compares normalized prefixes case-insensitively. Scopes that escape the repository root are refused. - The pre-receive hook rejects a push to a claimed branch when the new commits (newrev --not --all) touch paths outside the claim's scopes. --cc means a merge commit counts only the paths it changed itself, so merging the base branch in is not blamed on the claim holder. The scope and hook functions are identical to PR #10's; _pushed_paths adds check=False to match main's lint baseline. Tests are PR #10's scope tests, and all 26 fail without the port. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SrukvuPz7kpbore3kkKpQ3
Deep-Sixed
marked this pull request as ready for review
September 29, 2026 22:35
Deep-Sixed
pushed a commit
that referenced
this pull request
Sep 29, 2026
…rned scopes main now carries #19, which rejects pushes that touch paths outside the claim's scopes. This branch makes those pushes approval-governed instead. Resolution keeps both: - #19's scope normalization/validation, case-insensitive overlap, and path_in_scopes matcher replace this branch's duplicate glob matcher. - This branch's git_objects path derivation (shared with approve prepare) replaces #19's _pushed_paths, so the hook and the planner agree on hashes. - Out-of-scope pushes are still rejected by default, with #19's wording, but can now proceed with an out_of_scope_push approval. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0142xh1CDDPxBvB1EHu6PN3m
This was referenced Sep 29, 2026
Deep-Sixed
pushed a commit
that referenced
this pull request
Sep 29, 2026
…e ref-transaction binding main's content governance (#23) can require several approvals for one ref update, where this branch recorded one operation and one approval. Resolved by keeping main's derivation (governed_operations over git_objects.changed_paths) and binding all of it to the transaction: - pre-receive derives the update's paths from the received objects, records them with the update, and consumes nothing. - The reference-transaction `prepared` stage re-derives the operations from those recorded paths against current governance state and consumes one approval per operation. Recording the paths matters in a non-atomic multi-ref push: by `prepared`, earlier refs have moved, which would change which commits look new and so the hashes. - Every consumed approval is linked in ref_update_approvals, so an abort (or `doctor --repair` of an aborted update) restores all of them. This branch's own scope enforcement and path helpers are dropped in favour of main's (#19, #23). The ref_updates migration is renumbered from 003 to 006: main already ships 004 and 005, and a gap-filling 003 would apply after them on existing stores but before them on new ones. The README now requires Git 2.28 (for the reference-transaction hook) instead of #18's 2.17. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014R4wfmENrMnt36KN1Kj6Fx
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
Carries the scope fixes from #10 (review findings 3 and 4) onto
main, which now includes the approval-authority work from #12.#10 itself is left untouched. Its self-approval and worktree-reclaim changes are not carried over because #12 covers them. Its later commits (a
reference-transactionhook protocol overlapping #9, a stricter schema check, and doctor reconciliation) aren't included either.Changes
Scopes are canonical at claim time (
work.normalize_scope,validate_scope,scopes_overlap)./src/**,/src/**,src//**,src\**andsrc/../src/**all normalize tosrc/**before being stored and compared.../other/**) are refused.Scopes are enforced at push time (
gate.enforce_claim_scopes,work.path_in_scopes)newrev --not --all) must match one of the claim's scopes, or pre-receive rejects the push and lists the offending paths.--ccmeans a merge commit counts only the paths it changed itself, so merging the base branch in is not blamed on the claim holder.**spans directories,*and?stay within one segment,[...]is a character class, and a scope without wildcards covers that file or directory.The scope and hook functions are identical to #10's, compared by AST. The one change is
check=Falseon_pushed_paths'subprocess.run, to matchmain's pinned-ruff lint gate.Not included from #10
create_task/add_agent, andhandoff create --last-commitsemantics. These are independent of scopes and could follow as a separate small PR.Validation
python -m pytest -q: 148 passed (122 onmain+ 26 new intests/test_scope_enforcement.py)pyright: 0 errors, 0 warningsruff checkwith the pinned ruff 0.16.9: cleanThe new tests are #10's scope tests: normalization, overlap across spellings, escape refusal,
./scopes classified as overlapping and stored normalized, glob matching, and two real-push hook tests (out-of-scope commits rejected, merge commits not attributed, new claimed branches covered).🤖 Generated with Claude Code
https://claude.ai/code/session_01SrukvuPz7kpbore3kkKpQ3