Conversation
…-coded copy tools/auto_merge.py hard-coded ["tests/CLAUDE.md", "tools/CLAUDE.md"] when resolving merge conflicts -- a re-typed copy of tools/generated_paths.py, the exact duplication that registry exists to prevent. PR #757 adds tools/INDEX.md to the registry; auto_merge would never have known. fix_branch() now imports generated_paths as a MODULE and calls generated_paths() at call time, so the tool tracks whatever the registry currently holds rather than freezing a copy at import. tests/test_auto_merge_registry.py adds two guards: - behavioural: injects a sentinel entry into the registry at runtime and asserts fix_branch resolves it (a copy cannot see the sentinel); shrinking the registry to empty resolves nothing - structural (durable): AST source scan over tools/ failing any module that re-types the registry as a literal collection, with its own falsifiability tests (planted copy is caught; a broader overlapping list such as merge_telemetry contended-files is not a false positive) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This branch has not been deployed
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
tools/auto_merge.py:97hard-coded['tests/CLAUDE.md', 'tools/CLAUDE.md']whenauto-resolving merge conflicts — a re-typed copy of
tools/generated_paths.py, which isthe single registry of repo-generated files and exists precisely to prevent this
duplication.
tools/merge_queue.pyalready imports the registry;auto_merge.pydid not.The copy was already drifting: PR #757 registers
tools/INDEX.mdas a generated path.Once it lands,
merge_queuewould restoretools/INDEX.mdbutauto_mergewould leave abatch conflicting on it unresolved — silently, with no gate to notice.
Fix
fix_branch()importsgenerated_pathsas a module and callsgenerated_paths()atcall time, so the tool tracks whatever the registry currently holds instead of freezing
a copy at import. This works whether or not #757 has landed — nothing in
generated_paths.pywas touched.
Conflict resolution stays path-by-path and registry-bounded: still no
git stash(sharedstash stack across worktrees) and no blanket checkout of the whole tree; an unregistered
conflicted file still aborts the merge rather than being discarded.
TDD
Both guards were written first and fail on the pre-fix code (3 red), then pass:
fix_branch()must act on it (resolving--theirsfor the sentinel). A hard-coded copycannot see the sentinel, so this fails on the duplicated list and passes only on a live
read. A second case shrinks the registry to empty and asserts nothing is resolved.
tools/failing any modulethat re-types the registry as a literal collection. This is the part that stops the same
class of duplicate returning the next time someone needs the list. It carries its own
falsifiability tests: a planted copy IS caught, and a broader overlapping list (e.g.
merge_telemetry.check_contended_files, which addsREADME.md/RELEASE-NOTES.mdandmeans something different) is NOT a false positive.
Gates green:
secret_scan --staged,import_resolution_check,verify_test_suite_count --check,encoding_lint --check,subprocess_guard --check --baseline,claudemd_lint --root .,claudemd_sync_gate --check,gen_tool_index --check,verify_test_coverage --check.Scope
tools/auto_merge.py(+ itsINDEX:docstring line and the regeneratedtools/INDEX.md),its new test, and the suite-count line regenerated by
verify_test_suite_count --regenerate.tools/generated_paths.py,tools/merge_queue.pyandtools/commit_lint.pyare untouched.Noted, not fixed here (out of lane)
tools/import_resolution_check.pycannot resolve sibling imports insidetools/(no
__init__.py, and thesys.path.insert(script_dir)pattern isn't modelled). Stagingan unmodified
tools/auto_merge.pyon pristineorigin/mainmakes the gate reportfrom subprocess_common -> not found. It happens not to bite at push time because thegate reads
git diff --cached, which is empty once work is committed — so the guardrailis effectively inert as a pre-push gate. Worth its own lane.
tools/commit_lint.py --rangeraisesrun_subprocess() got an unexpected keyword argument 'capture_output'(PR guard: fix commit_lint --range crash (caller migrated to current run_subprocess signature) #720's file).🤖 Generated with Claude Code