Skip to content

fix(grep): hint when a zero-result literal search looks like a regex#47

Merged
RioPlay merged 1 commit into
mainfrom
fix/grep-literal-regex-hint
Jun 20, 2026
Merged

fix(grep): hint when a zero-result literal search looks like a regex#47
RioPlay merged 1 commit into
mainfrom
fix/grep-literal-regex-hint

Conversation

@RioPlay

@RioPlay RioPlay commented Jun 20, 2026

Copy link
Copy Markdown
Owner

Summary

Root-causes and fixes a silent false-negative in aden grep that I tripped over while auditing docs (it produced a wrong "aden ready doesn't exist" conclusion).

What happened: aden grep matches literal substrings by default; regex is opt-in (regex=true). A pattern like Ready|ready passed without that flag is searched literally — pipe included — and matches nothing. A human sees the empty terminal and self-corrects; an agent consuming {"total": 0} concludes the term is absent and acts on it.

Confirmed with a controlled experiment:

Query Result
"Ready|ready", regex:false (default) 0 hits
"Ready|ready", regex:true 173 hits
"ready", ignore_case:true 126 hits

The fix keeps literal-default semantics (auto-promoting to regex would break literal searches for code like a|b or foo()), but stops the silent miss: when a search returns zero results in literal mode and the pattern carries regex metacharacters (| [ ( \ .* .+), emit a hint to retry with regex=true (or ignore_case=true). Surfaced in both human output and the JSON envelope as a new hint field — present only when firing, so successful searches are unchanged and existing consumers are unaffected.

looks_like_regex deliberately skips bare . * + ? (too common in literal code searches to be a reliable signal). Unit tests cover both the flagged idioms and the literals that must stay quiet.

Verified end-to-end on the built binary:

  • zero-result literal alternation → total:0 + hint
  • same pattern --regex → 8 matches, no hint
  • normal literal hit → 14 matches, no hint field

Known follow-up (not in this PR)

Separately noticed: the [PATH] argument scopes only project-root discovery, not the searchgrep <pat> some/file.rs still searches the whole project (and can dump megabytes when it matches minified asset lines). Filed for its own investigation; not touched here.

Test plan

  • cargo test -p aden-cli green (new flags_regex_idioms / ignores_plain_literals pass)
  • cargo clippy --workspace clean
  • cargo fmt --all applied
  • Manual end-to-end on the built binary (above)

License checklist

  • No dependency changes — license checklist not applicable

aden grep matches literal substrings by default; regex is opt-in
(regex=true). A pattern like `Ready|ready` passed without that flag is
searched literally — pipe and all — and matches nothing. A human sees the
empty result and adjusts, but an agent consuming `{"total": 0}` concludes
the term is absent and acts on it. That exact footgun produced a
false-negative "aden ready doesn't exist" in this repo.

Keep the literal-default semantics (changing them would break literal
searches for code like `a|b` or `foo()`), but stop the silent miss: when a
zero-result search ran in literal mode and the pattern carries regex
metacharacters (| [ ( \ .* .+), emit a hint to retry with regex=true (or
ignore_case=true). Surfaced in both the human output and the JSON envelope
as a new `hint` field that is present ONLY when firing, so a successful
search is never cluttered and existing consumers are unaffected.

looks_like_regex deliberately skips bare . * + ? — they appear in literal
code searches too often to be a reliable signal. Unit tests cover both the
flagged idioms and the literals that must stay quiet.
@RioPlay RioPlay merged commit cb1bfeb into main Jun 20, 2026
6 checks passed
@RioPlay RioPlay deleted the fix/grep-literal-regex-hint branch June 20, 2026 16:20
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.

1 participant