Repository navigation
guard(repo_tests): route nine ls-files sites through tracked_paths (#15926) - #16057
Conversation
…15926) Nine guards each ran their own `git ls-files "*.py"` and re-decided the same three things: the pathspec, the env scrub, and how to split the output. All nine now call `tracked_paths`, which decides them once. The pathspec at every site is unchanged, and each site's Python-side filtering is preserved verbatim, so the population each guard sweeps is identical. Moving those filters into git-side `exclude=` is #15927 and is deliberately not done here. Two sites are strictly more correct than before: `no_tracked_path_into_worktrees` and `hard_optional_dependency_declared` split stdout on whitespace, which breaks a tracked path containing a space into two bogus entries. `tracked_paths` splits on lines. Not migrated, as a class rather than an oversight: the two guards that pass their enumerator to `declare(discover=...)`. `reach_declarations_test` drives that against an empty tree to prove the floor fires, and `tracked_paths` raises there instead of returning empty. MAX_DIRECT_INVOCATIONS 42 -> 33.
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Advanced Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
✅ SSOT Configuration Compliance: Passing🎉 No new hardcoded values of either class — Known backlog in |
Review — first human pass, at
|
…15928) The previous push failed by one file, and the failure is the argument. One floor serves two populations: `examined()` bounds what `discover` returned (5,601 tracked python files), `completed()` bounds what the guard finished (5,337, with 262 skipped as unreadable or unparseable). The floor has to clear the lower one while the meta-test measures the higher, so a single band of 500 spent 264 of itself on the skip gap before buying any growth headroom. The remainder lasted an hour. Raising it to 800 would have been the fix this change exists to prevent: a number chosen by feel. Splitting it is the fix -- `skips` for what a guard cannot complete, `growth` for what it may grow before a deliberate ratchet. Each is then chosen against one quantity and a reviewer can see which. audio-extension-allowlist declares skips=300, measured from the hook's own `completed 5337` against 5,599. env-var-bare-cast declares skips=200 and says in the comment that it is a guess, because that guard's `completed` count has never failed and the gap is unknown -- recorded as unmeasured rather than presented as measured. The failure message now names both numbers and says which to raise, since the whole defect was one number silently doing two jobs. `examined()` is deliberately untouched: #16057 documents an EmptyEnumeration collision in that function and the fix belongs to whoever takes it.
…6048) * chore: claim worktree for #15928 * guard(reach): pin every declared floor to its population (#15928) A floor far below what its own discovery returns fires only against total collapse, and total collapse is not the failure that happens. Partial loss is: a narrowed glob, a moved directory, a change propagated to some call sites and not others. Every floor examined in review during #15896, #15901 and #15913 fired correctly against an empty tree while tolerating the loss of most of a real one. Adoption did not fix this. Both guards that had already adopted _reach declared a number chosen by feel -- 1000 against 5,599 files and 500 against 3,152, 18% and 16% of their own populations. The mechanism was never the missing part. Adds Reach.growth and a meta-test asserting the live population sits within [floor, floor + growth]. growth=0 -- equality -- is the default because a floor at its population turns shrinkage into a deliberate line in a diff. A population ordinary work grows states a band instead, where a reviewer sees it, rather than being pinned low and quietly meaning nothing. Validated in the meta-test rather than in declare(): declaring would walk the tree once per imported guard, and the meta-test already enumerates every declaration, so the guarantee is the same and the cost is paid once. Both existing floors ratcheted to a band of 250, which absorbs ordinary churn in both directions while staying far below the size of any subtree whose loss the floor exists to catch. * guard(reach): pin the floor to the population that binds, not the one discovered (#15928) The pre-push hook rejected the first version and the rejection is the finding: one floor serves two populations. `examined()` bounds what `discover` returned -- 5,599 tracked python files -- while `completed()` bounds what the guard actually finished, 5,337, because 262 are skipped as unreadable or unparseable. A floor pinned to the discovered count clears the first check and fails the second. So the meta-test added here is necessary and not sufficient: it can only see the higher population, and `completed()` remains the binding constraint. Both declarations carry a band of 500 rather than the 250 ordinary churn alone would need, precisely to absorb that gap. Separating the two floors is the fuller fix and is deliberately not this change. Stating the limitation in the test rather than leaving it for the next author to rediscover by the same hook failure. * guard(reach): give the skip gap its own name instead of a wider band (#15928) The previous push failed by one file, and the failure is the argument. One floor serves two populations: `examined()` bounds what `discover` returned (5,601 tracked python files), `completed()` bounds what the guard finished (5,337, with 262 skipped as unreadable or unparseable). The floor has to clear the lower one while the meta-test measures the higher, so a single band of 500 spent 264 of itself on the skip gap before buying any growth headroom. The remainder lasted an hour. Raising it to 800 would have been the fix this change exists to prevent: a number chosen by feel. Splitting it is the fix -- `skips` for what a guard cannot complete, `growth` for what it may grow before a deliberate ratchet. Each is then chosen against one quantity and a reviewer can see which. audio-extension-allowlist declares skips=300, measured from the hook's own `completed 5337` against 5,599. env-var-bare-cast declares skips=200 and says in the comment that it is a guess, because that guard's `completed` count has never failed and the gap is unknown -- recorded as unmeasured rather than presented as measured. The failure message now names both numbers and says which to raise, since the whole defect was one number silently doing two jobs. `examined()` is deliberately untouched: #16057 documents an EmptyEnumeration collision in that function and the fix belongs to whoever takes it. * guard(reach): measure env-var's skip gap instead of guessing it (#15928) It is 0. That guard discovers 3,152 files and parses 3,152 -- every file it enumerates, it completes -- so the 200 it shipped with was slack buying nothing. Worse than useless: it sat beside audio's measured 300, where it inherited an authority it had not earned. A number chosen by feel, under the name this change added to stop numbers being chosen by feel. Declaring it honestly as a guess was weaker than measuring it, which is the pushback I asked for and got. With no gap the floor can pin near the real population rather than below a phantom one, so MIN_FILES_SCANNED goes 2850 -> 3000: slack 152 against a growth band of 400, and the floor still clears completed by 152. The derivation and the command to repeat it are recorded beside the constant, so the next person re-derives rather than re-guesses. If a completed failure ever appears there, that is the moment to raise it -- with the number the failure hands you, which is the mechanism this PR builds.
…efusing (#15897) Two reds, two causes. #15925: line 41 re-derived the root from __file__ instead of calling repo_root(). One spelling exists now; this is one line. The second is a collision between two correct mechanisms. tracked_paths raises EmptyEnumeration rather than returning [], because an empty enumeration reported as a clean tree is the defect it exists to prevent. reach_declarations_test hands every declaration an empty repository on purpose and needs an empty RESULT to compare -- its own docstring asks for 'an empty result to compare instead of an exception that ends the test early and proves nothing'. Caught locally rather than changed in either shared mechanism. Both are right and both stay as they are: 46 has an open analysis on where the general resolution belongs (#16057), and pre-empting it from inside a consumer would decide a question that is not this PR's to decide. Returning [] does not weaken the refusal, it relocates it. REACH's floor of 300 then raises ReachFloorError, which is the typed refusal the meta-test is built around and a stronger signal than the bare assertion it would otherwise accept. An empty tree still fails -- it fails as the mechanism intends rather than one layer above it.
#15897) (#16068) * chore: claim worktree for #15897 * guard(size): count the oversized files the size hook's exclusions hide (#15897) EXCLUDED_PREFIXES removes autobot-infrastructure/ and autobot-backend/code_analysis/ from the size sweep. Both are tracked source, and 47 files in them exceed the 600-line ceiling with no entry in KNOWN_LARGE -- the largest at 2,341 lines, 3.9x the limit. Not because anyone decided they should be exempt, but because the enumeration never offered them to be decided. That is #15897's thesis: the baseline records exemptions, and these are exemptions it was never shown. Counted rather than grandfathered, because adding 47 entries to KNOWN_LARGE would reverse two rulings this change has no standing to overturn: that mapping's docstring says it only ever shrinks and no entry may be added to make a file pass, and EXCLUDED_PREFIXES is mirrored in .pre-commit-config.yaml and pinned by a test, so narrowing it widens the pre-commit hook for every committer -- a scope decision, not a visibility one. A grandfathered ceiling and an unscanned tree are also different claims, and conflating them would lose the difference. So the debt gets its own number, pinned by equality so headroom cannot hide the next one, with the failure message saying which direction moved and what to do about each. Dogfoods #15928: the reach floor is declared through declare() with growth stated separately, and the enumeration goes through tracked_paths (#15926) rather than a thirty-fourth hand-rolled git ls-files. * guard(size): honour the one root spelling, and let the floor do the refusing (#15897) Two reds, two causes. #15925: line 41 re-derived the root from __file__ instead of calling repo_root(). One spelling exists now; this is one line. The second is a collision between two correct mechanisms. tracked_paths raises EmptyEnumeration rather than returning [], because an empty enumeration reported as a clean tree is the defect it exists to prevent. reach_declarations_test hands every declaration an empty repository on purpose and needs an empty RESULT to compare -- its own docstring asks for 'an empty result to compare instead of an exception that ends the test early and proves nothing'. Caught locally rather than changed in either shared mechanism. Both are right and both stay as they are: 46 has an open analysis on where the general resolution belongs (#16057), and pre-empting it from inside a consumer would decide a question that is not this PR's to decide. Returning [] does not weaken the refusal, it relocates it. REACH's floor of 300 then raises ReachFloorError, which is the typed refusal the meta-test is built around and a stronger signal than the bare assertion it would otherwise accept. An empty tree still fails -- it fails as the mechanism intends rather than one layer above it.
Refs #15926. Does not close it — this is 9 of 42; criteria 2 and 4 stay open.
Single-issue rationale: this is one batch of a 42-site migration against a single issue; there is no second issue to batch with, and splitting it further would put one CI suite behind each call site.
What Changed
Nine guards each ran their own
git ls-files "*.py"and re-decided the same three things: the pathspec, whether to scrub the ambient git environment, and how to split stdout. All nine now calltracked_paths, which decides them once.MAX_DIRECT_INVOCATIONS42 → 33. Net −56 lines.no_duplicate_dict_keys·python_file_size_ratchet·bandit_exclude_anchoring·credential_vault_resolution·enum_union_guard·man_page_indexer_path_resolves·no_tracked_path_into_worktrees·hard_optional_dependency_declared*.pydependabot_requirements_coverage*requirements*.txtThinking Path
The pathspec at every site is unchanged and each site's Python-side filtering is preserved verbatim, so every guard sweeps an identical population. Two sites filter
.worktrees/in Python and still do; moving such filters into git-sideexclude=is #15927 and is deliberately not done here. Keeping the migration to the subprocess call is what makes population equality checkable by inspection rather than by argument.Two sites are strictly more correct than before.
no_tracked_path_into_worktreesandhard_optional_dependency_declaredsplit stdout with.split()— whitespace — so a tracked path containing a space became two bogus entries.tracked_pathssplits on lines.Behaviour on a broken enumeration changes deliberately. These sites raised
CalledProcessErroron git failure and returned[]on empty. They now raiseRuntimeErrorandEmptyEnumeration. Refusing to report an empty enumeration as a clean tree is the helper's purpose.Two guards deliberately not migrated, as a class rather than an oversight
audio_extension_allowlist_testandenv_var_bare_cast_testpass their enumerator todeclare(discover=...), andreach_declarations_test.test_no_guard_can_succeed_against_an_empty_treedrives that against an empty tree to prove the floor fires.tracked_pathsraises there instead of returning[], so migrating them breaks the test that proves their floors work.That is the empty-population tension the census file already documents, reached from the other side: there the empty result is the failure, here it is the evidence. Both mechanisms are right, which is why this needs a decision in
_reach.py— most likely teachingexamined()to treatEmptyEnumerationas the collapse it is already testing for — rather than anallow_empty=flag, which the census comment correctly calls the obvious and wrong fix. Recorded in the ratchet comment; not attempted here.Verification
_TRACKED_PY_FLOOR,_MIN_FILES_SWEPT = 4_000,scanned > 4000. Those floors passing is the population check: a migration that changed what a guard enumerates fails them.enum_union_guard_test.pyfell 805 → 801 and the push was blocked until both recorded ceilings were lowered, inscripts/python_file_size_known_large.pyandrepo_tests/python_file_size_ratchet_baseline.py. Both now read 801, matchingwc -l."ls-files"argv occurrences inrepo_tests/*.pywent 53 → 44, exactly the nine claimed.repo_tests/*.pyparses clean.Model Used
Claude Opus 5 (1M context)