Skip to content

fix: grep fallback in search_files — enable ERE and skip --exclude-dir on hidden roots - #48878

Open
luxles wants to merge 1 commit into
NousResearch:mainfrom
luxles:fix/grep-fallback-bugs
Open

fix: grep fallback in search_files — enable ERE and skip --exclude-dir on hidden roots#48878
luxles wants to merge 1 commit into
NousResearch:mainfrom
luxles:fix/grep-fallback-bugs

Conversation

@luxles

@luxles luxles commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes two bugs in _search_with_grep() (tools/file_operations.py) that cause search_files to silently return zero results when ripgrep is unavailable.

Bug 1: BRE mode

grep -rnH uses BRE mode where | is a literal character. ripgrep's Rust regex treats | as alternation. Fix: add -E for ERE.

Bug 2: --exclude-dir='.*' skips hidden search roots

GNU grep applies --exclude-dir to command-line directories too, so searching ~/.hermes skips the entire root. Fix: only add --exclude-dir when basename doesn't start with ..

Verification

Before: grep -rnH --exclude-dir='.*' --include config.yaml 'write_approval|guard_agent' ~/.hermes → EXIT=1

After: grep -rnHE --include config.yaml 'write_approval|guard_agent' ~/.hermes → config.yaml:387-388 matched, EXIT=0

See commit message for full details.

@alt-glitch alt-glitch added type/bug Something isn't working tool/file File tools (read, write, patch, search) P2 Medium — degraded but workaround exists labels Jun 19, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Related: #18473 (hidden-root exclude-dir bug), #18645 and #34017 (open PRs fixing the same hidden-root --exclude-dir issue on a different code path scope).

This PR fixes the same --exclude-dir-on-hidden-root problem AND additionally adds the ERE (-E) flag so alternation (|) works in the grep fallback — an orthogonal second bug the other PRs don't address. Verified both bugs are still live on main (_search_with_grep still uses "grep -rnH" with no -E and an unconditional --exclude-dir). Marked related rather than duplicate because of the added ERE layer.

… search roots

Two bugs in _search_with_grep() when ripgrep is unavailable:

1. BRE mode: grep -rnH uses Basic Regular Expression mode, where | is a
   literal character. ripgrep ships with Rust regex (| = alternation), so
   patterns with alternation silently fail on the grep fallback.
   Fix: add -E to enable ERE (Extended Regular Expression) mode.

2. --exclude-dir='.*': GNU grep applies this to all directory components
   INCLUDING command-line arguments, so a search under ~/.hermes/workspace
   skips the entire tree because .hermes matches .*. Ripgrep only applies
   globs to subdirectories, not the root.
   Fix: only add --exclude-dir when no path component is hidden, mirroring
   the logic already used by _search_files (merged in NousResearch#16672).

Both bugs produce silent false-negatives: search_files returns
total_count=0 without any error. Cross-reference NousResearch#18473, NousResearch#18645, NousResearch#34017.

Fixes NousResearch#18473
@luxles
luxles force-pushed the fix/grep-fallback-bugs branch from ff71ec2 to a42764c Compare June 19, 2026 07:13

@tonydwb tonydwb left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Summary

Verdict: Approved

Small, focused fix. The grep fallback now enables ERE (-E) and skips --exclude-dir on hidden root directories, which is the correct behavior for search_files. Well-scoped change, no issues.

Looks Good

  • Minimal diff (8 lines, 1 file)
  • Targeted fix addressing a specific edge case in grep fallback
  • No test changes needed for this type of fix

Reviewed by Hermes Agent

@luxles

luxles commented Jun 19, 2026

Copy link
Copy Markdown
Contributor Author

PR has been approved by @tonydwb. I do not have write access to this repo — could a maintainer please squash-merge? Thanks!

@teknium1

Copy link
Copy Markdown
Contributor

Thanks for identifying two real grep-fallback defects: current main still uses grep -rnH and unconditionally adds --exclude-dir='.*' in tools/file_operations.py:2391-2395.

Problems

  • The new hidden-root branch disables --exclude-dir entirely whenever a root has a hidden ancestor. That also permits hidden descendants below the requested root, such as .hub or .git. This reverses the security invariant documented in tests/tools/test_search_hidden_dirs.py:1-13. Current main's analogous file-search fallback handles hidden roots by post-filtering descendants in tools/file_operations.py:2173-2187.
  • The PR has no regression tests. Existing tests only cover the safe hidden-root behavior for the find fallback in tests/tools/test_file_operations.py:720-757; grep needs equivalent coverage plus an ERE-alternation case.

Suggested changes

  • Keep -E, but preserve hidden-descendant filtering after allowing an explicit hidden root, following the current _search_files approach.
  • Add forced-grep tests for visible content under a hidden root, nested hidden-content exclusion, and | alternation.

Automated hermes-sweeper review.

@teknium1 teknium1 added sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data sweeper:blast-contained Sweeper blast radius: contained — one narrow path / opt-in / few users labels Jul 14, 2026
@alt-glitch alt-glitch removed the sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data label Jul 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P2 Medium — degraded but workaround exists sweeper:blast-contained Sweeper blast radius: contained — one narrow path / opt-in / few users tool/file File tools (read, write, patch, search) type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants