Skip to content

fix: propagate rg exit code in rtk grep for CLI parity - #227

Merged
pszymkowiak merged 1 commit into
rtk-ai:masterfrom
polaminggkub-debug:fix/grep-exit-code-parity
Feb 20, 2026
Merged

pszymkowiak merged 1 commit into
rtk-ai:masterfrom
polaminggkub-debug:fix/grep-exit-code-parity

Conversation

@polaminggkub-debug

Copy link
Copy Markdown
Contributor

Summary

  • rtk grep returned exit 0 for all failure modes where rg returns non-zero
  • Now propagates exit codes: 1 (no match), 2 (error — bad regex, missing file)
  • Surfaces rg stderr on error so users see why it failed

Before / After

Scenario Before After rg native
No match exit 0 exit 1 exit 1
Bad regex ([) exit 0 exit 2 exit 2
Missing file exit 0 exit 2 exit 2
Match found exit 0 exit 0 exit 0

Test plan

  • rtk grep "zzz" file → exit 1 (no match)
  • rtk grep "[" file → exit 2 + stderr error message
  • rtk grep "alpha" /nonexistent → exit 2 + stderr error message
  • rtk grep "alpha" file → exit 0 (match found, unchanged)
  • cargo test grep_cmd — 8 tests pass
  • cargo test --all — 412 pass, 0 fail

Fixes #162

🤖 Generated with Claude Code

rtk grep previously returned exit 0 for all failure modes (no match,
invalid regex, missing file) where rg returns non-zero. This broke
shell workflows relying on exit code semantics.

Now propagates rg exit codes: 1 (no match), 2 (error) and surfaces
stderr for error cases so users see why the command failed.

Fixes rtk-ai#162

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@pszymkowiak

Copy link
Copy Markdown
Collaborator

LGTM — tested locally, all good.

  • 412 tests pass, no conflicts with master
  • 82/83 smoke tests pass (1 false positive: test script hardcodes expected test count)
  • Exit codes verified manually:
    • Match found → exit 0 ✅
    • No match → exit 1 ✅ (was 0)
    • Bad regex → exit 2 + stderr ✅ (was 0)
    • Missing file → exit 2 + stderr ✅ (was 0)
  • No regression on any other command (ls, git, gh, find, grep, cargo, curl, etc.)

Fixes #162. Ready to merge.

@pszymkowiak
pszymkowiak merged commit f1be885 into rtk-ai:master Feb 20, 2026
2 of 3 checks passed
heAdz0r added a commit to heAdz0r/rtk that referenced this pull request Feb 28, 2026
Upstream 0.22.2 sync (all previously missing fixes verified applied):
- fix(lint): propagate linter exit code (rtk-ai#207) — CI false-green fix
- feat: add rtk wc command for compact word/line/byte counts (rtk-ai#175)
- fix(playwright): JSON parser (specs layer) + binary resolution (rtk-ai#215)
- fix(grep): propagate rg exit codes 1/2 (rtk-ai#227)
- fix(git): branch creation not swallowed by list mode (rtk-ai#194)
- fix(git): support multiple -m flags in git commit (rtk-ai#202)
- fix(grep): BRE \| translation + strip -r flag (rtk-ai#206)
- fix(gh): smart markdown body filter for issue/pr view (rtk-ai#214)
- fix(gh): gh run view --log-failed flag passthrough (rtk-ai#159)
- feat(docker): docker compose support (rtk-ai#110)
- feat: hook audit mode (rtk-ai#151)
- feat: tee raw output to file (rtk-ai#134)

Version bump: 0.21.1-fork.19 → 0.22.2-fork.1

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
thehoff pushed a commit to thehoff/contextcrawler that referenced this pull request May 14, 2026
rtk grep previously returned exit 0 for all failure modes (no match,
invalid regex, missing file) where rg returns non-zero. This broke
shell workflows relying on exit code semantics.

Now propagates rg exit codes: 1 (no match), 2 (error) and surfaces
stderr for error cases so users see why the command failed.

Fixes #162

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
thehoff added a commit to thehoff/contextcrawler that referenced this pull request Jul 14, 2026
…ed, DoS (rtk-ai#227, rtk-ai#228, rtk-ai#231)

Authored by the Codex (gpt-5.6) worker in an isolated lane; driver-verified
(full lib suite 3257 pass/0 fail in clean env, clippy clean on both files).

rtk-ai#227 install detection: command text can no longer disable an enabled gate;
shell words reconstructed before classification; per-manager global options
consumed before locating the install verb; process substitutions recursively
inspected; newline is a command boundary, not package-list whitespace.

rtk-ai#228 fail-closed verdict + file safety: OSV errors -> Unavailable (not silent
Allow); remote PyPI/VCS separated from local editables and prompted as
unvettable; mutable cache entries are hints only, registry metadata revalidated;
finding fields + source labels credential-safe; UTF-8 suffix boundary-safe;
scrub/audit writes (scrub_logs_in in tirith_gate.rs) use O_NOFOLLOW reads,
NamedTempFile in-dir + atomic persist (no predictable symlink tmp), 0600.

rtk-ai#231 retries + cache trust: HTTP 429 joins 5xx/transport on the bounded
retry/backoff path; cache replacement atomic + 0600; timestamps before 2000
rejected as implausible.

Default-off behaviour unchanged; enabled benign/local installs still Allow.

Refs: rtk-ai#227, rtk-ai#228, rtk-ai#231
Co-Authored-By: Codex (gpt-5.6) via council
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K3SAimSBwPUp4MkRXaYXSU
thehoff added a commit to thehoff/contextcrawler that referenced this pull request Jul 14, 2026
…tk-ai#227, rtk-ai#228, rtk-ai#231)

Authored by the Codex (gpt-5.6) worker; driver-verified (full clean-env lib
suite 3275 pass/0 fail; clippy clean on the file). Addresses the non-author
council (mmax/deepseek/glm/agy) HOLD against round-1.

Fixed: manager-name line-continuation join; --registry/--userconfig/
--globalconfig/-C metadata-source mismatch (alternate registry -> unvettable
Ask, no untrusted value in findings); quoted remote-URL evasion; SCP/SSH and
git+http(s)/git+ssh source forms + credential-safe labels; tokenisation errors
now fail closed (unterminated quotes/subst/trailing escape -> unvettable);
cache revalidation is fail-closed (a mutable cache entry can force a
conservative Block but never justify Allow); ecosystem-specific boolean option
arity (npm/pnpm/yarn/bun/pip/uv) removes the over-block; missing/flag-shaped
`pip install -e` target is unvettable.

Rejected with evidence (Law-2): Y2K boundary already correct; split_attached_flag
and lexer::extract_process_substitutions exist; url/tempfile/libc are explicit
deps; far-future timestamp already rejected in round 1.

Default-off unchanged; benign enabled installs still Allow (explicit-package
tests, no network).

Refs: rtk-ai#227, rtk-ai#228, rtk-ai#231
Co-Authored-By: Codex (gpt-5.6) via council
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K3SAimSBwPUp4MkRXaYXSU
thehoff added a commit to thehoff/contextcrawler that referenced this pull request Jul 14, 2026
…rtk-ai#227, rtk-ai#228, rtk-ai#231)

Authored by the Codex (gpt-5.6) worker; driver-verified (full clean-env lib
suite 3282 pass/0 fail; clippy clean on the file). Closes the fail-opens found
by the round-2 confirming council (deepseek+mmax):

- pip/uv network-trust + index flags (--trusted-host, --cert, --client-cert,
  --proxy, --index-url/-i, --extra-index-url, --find-links/-f) now force the
  install unvettable (Ask) — closes a MITM/mirror bypass that nullified registry
  vetting. Option values/hosts/URLs/credentials are never copied into findings.
- extract_recursion_segments returns Result; a tokenisation error becomes a
  synthetic Unvettable finding instead of silently dropping nested-install
  tracking (`bash -lc '...'` fail-open closed).
- npx/pnpx/yarn dlx launchers -> local-only-caveat unvettable (they pull
  arbitrary packages).
- pnpm --frozen-lockfile + bare lockfile installs -> pnpm local-only caveat.
- SCP sources with any (non-`git`) username treated as remote; host/basename
  only in findings.
- unvettable source/config/trust caveats clear parsed package names so the
  install reports as one unvettable unit (no hybrid findings).

Law-2 rejects retained (with pinning tests): parse_iso8601 pre-2000 rejection
(intentional rtk-ai#231), -version ambiguous, LINE_CONT horizontal-only, general
tokenise failure -> Ask.

Default-off unchanged; named installs without caveats still Allow.

Refs: rtk-ai#227, rtk-ai#228, rtk-ai#231
Co-Authored-By: Codex (gpt-5.6) via council
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K3SAimSBwPUp4MkRXaYXSU
thehoff added a commit to thehoff/contextcrawler that referenced this pull request Jul 14, 2026
…l-open, DoS (rtk-ai#227, rtk-ai#228, rtk-ai#231)

Three Codex-authored rounds in an isolated lane, driver-verified + non-author
council-reviewed (r1 full HOLD, r2 confirming HOLD, r3 Law-2 judgement).
Install-detection evasions, OSV/remote/cache fail-open, credential leaks,
network-trust/index-flag MITM bypass, recursion/process-subst fail-open,
launcher (npx/dlx) + lockfile installs, 429 DoS, scrub symlink/0600. Default-off
unchanged. Refs: rtk-ai#227, rtk-ai#228, rtk-ai#231
thehoff added a commit to thehoff/contextcrawler that referenced this pull request Jul 14, 2026
Supply-chain gate hardening (rtk-ai#227/rtk-ai#228/rtk-ai#231) — completes the security audit
register rtk-ai#210-rtk-ai#233. Three Codex-authored rounds, driver-verified + non-author
council-reviewed. Install-detection evasions, fail-open verdicts, network-trust
MITM bypass, recursion/launcher/lockfile gaps, 429 DoS, credential-safe
findings. Gate remains default-off. See CHANGELOG.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K3SAimSBwPUp4MkRXaYXSU
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.

bug: rtk grep exit-code parity differs from rg (always 0 for key failure modes)

2 participants