Skip to content

An include spelled with ./ is the scope it names to the self-match check, as it already was to the scan - #344

Merged
HackingGate merged 2 commits into
mainfrom
an-include-spelled-with-dot-selects-what-it-names
Oct 10, 2026
Merged

HackingGate merged 2 commits into
mainfrom
an-include-spelled-with-dot-selects-what-it-names

Conversation

@HackingGate

Copy link
Copy Markdown
Owner

Rule selection compared each files.include entry to "." as a string. Any other spelling of the same scope kept its CurDir component: ./policy stayed a path starting with ., and ./ alone was not the whole tree. The component-wise selects() therefore answered false for every path under such an entry, while the scan, which joins the entry onto the repository root, still read the right files. selects() has one caller, the self-match check at load. A require_regexp satisfied by its own declaration was refused under include = ["policy"] and silently accepted under ["./policy"] or ["./"]; the scan then found the requirement in the policy file's own text and reported policy checks passed. The policy file was exempt from its own rule.

Each entry is now read once, by component, into the repository-relative path it names. ./ parts are dropped, so policy, ./policy, policy/ and ./policy/. are one path; ., ./ and the empty string are the whole tree; an entry with .., an absolute path, or a drive prefix reads as outside the tree. That one reading feeds both selects() and search_roots, so the two cannot disagree on a spelling again. .. and absolute entries are refused by the scan with the same message as before, and selects() answers "not selected" for them. The under helper, which judged "inside the repository" after the join, is removed; it had no other caller.

Tests:

  • config::a_require_regexp_that_satisfies_itself_is_refused_however_its_include_is_spelled: the self-matching rule is refused under policy, ./policy, policy/, ./policy/, ., ./ and "", and still loads under src, ./src and src/.
  • selection::every_spelling_of_one_include_is_one_scope_to_the_scan_and_the_scope_test: every spelling of policy, and every spelling of the whole tree, gives the same selects() answer, the same search_roots, and the same selected files.
  • selection::an_include_that_climbs_out_and_back_is_refused_by_the_scan_and_selects_nothing: policy/../policy, ./../policy and /etc are refused by the scan and select nothing.

docs/REFERENCE.md: the self-match section now says the scope test reads include the same way the scan does.

https://claude.ai/code/session_01TG5hbR4Re6gcEZTpBCBymc

…eck, as it already was to the scan

The scan and the scope test behind the self-match check each read
files.include on their own, and each recognised the whole tree by
comparing an entry to "." as a string. They parted on any other
spelling. The scan joined ./policy to the root and searched the policy
directory; the scope test kept ./ as a leading path component that no
repository-relative path starts with, so it answered "not selected" for
every path, and ./ alone selected nothing at all. A require_regexp that
matched its own declaration was refused at load under include =
["policy"] and loaded under ["./policy"] or ["./"], and the scan then
found the requirement in the policy file's own text and printed policy
checks passed: the file exempted itself silently.

Each entry is now read once, by component, into the repository-relative
path it names. CurDir parts are dropped, so policy, ./policy, policy/
and ./policy/. are one path, and ".", "./" and the empty string are the
whole tree. Both search_roots and the scope test use that one reading,
so the two cannot disagree on a spelling again.

An entry with a .. anywhere, an absolute path, or a drive prefix reads
as outside the tree. search_roots refuses it at scan time with the
message it already gave, which is where the codebase already refuses an
include that leaves the repository; nothing at load validates include,
and this change adds nothing there. A .. that climbs back in, such as
policy/../policy, was already refused and still is. The scope test
answers "not selected" for such an entry rather than refusing, since a
run that reaches a scan stops on it there.

The helper under, which decided "inside the repository" by stripping the
root from the joined path and looking for a ParentDir, is removed: the
component reading answers that question before any join, and it had no
other caller.

The self-match section of the reference says the scope test reads
include as the scan does.

Claude-Session: https://claude.ai/code/session_01TG5hbR4Re6gcEZTpBCBymc
@coderabbitai

coderabbitai Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 28 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: fbfa4add-114f-44ee-aef8-d37f1bf572c9

📥 Commits

Reviewing files that changed from the base of the PR and between 4d42ff0 and 71a3b5e.


📒 Files selected for processing (3)
  • docs/REFERENCE.md
  • src/config.rs
  • src/selection.rs


  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov-commenter

codecov-commenter commented Oct 10, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.43%. Comparing base (4d42ff0) to head (71a3b5e).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #344      +/-   ##
==========================================
+ Coverage   94.41%   94.43%   +0.01%     
==========================================
  Files          46       46              
  Lines       23251    23318      +67     
==========================================
+ Hits        21953    22020      +67     
  Misses       1298     1298              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@HackingGate
HackingGate merged commit 5bbd941 into main Oct 10, 2026
12 checks passed
@HackingGate
HackingGate deleted the an-include-spelled-with-dot-selects-what-it-names branch October 10, 2026 02:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants