RulesDb::classify matches patterns with a plain substring test:
if rule.patterns.iter().any(|pat| p.contains(pat.as_str())) {
Nothing anchors the pattern to a path component, so rules fire well outside where they were meant to:
/home/user/tmp/tax-return.pdf contains /tmp/ and comes back temp_file
~/photos/target/debug/raw.cr2 matches /target/debug and comes back build_artifact
Both then show up as reclaimable, and both are actionable (review is not gated).
There's already a TODO: replace with proper glob matching (globset crate) on the patterns field. Either that, or at minimum anchor patterns to the start of the path or to a /-delimited component boundary. Whichever way it goes, the existing rules in base.json need re-checking against it — some are written assuming the loose behaviour.
crates/diskern-core/src/rules.rs:43
RulesDb::classifymatches patterns with a plain substring test:Nothing anchors the pattern to a path component, so rules fire well outside where they were meant to:
/home/user/tmp/tax-return.pdfcontains/tmp/and comes backtemp_file~/photos/target/debug/raw.cr2matches/target/debugand comes backbuild_artifactBoth then show up as reclaimable, and both are actionable (
reviewis not gated).There's already a
TODO: replace with proper glob matching (globset crate)on thepatternsfield. Either that, or at minimum anchor patterns to the start of the path or to a/-delimited component boundary. Whichever way it goes, the existing rules inbase.jsonneed re-checking against it — some are written assuming the loose behaviour.crates/diskern-core/src/rules.rs:43