Global filters (~/.config/rtk/filters.toml) were loaded without any
integrity verification, unlike project-local filters which require
SHA-256 trust. A supply-chain attack (e.g. npm postinstall script)
could write to ~/.config/rtk/ to suppress security scanner output
or rewrite command output via replace/match_output rules.
Now: first load silently records a SHA-256 baseline. If the file
changes unexpectedly, RTK warns and refuses to load until the user
runs `rtk trust --global` to review and accept.
Ref: issue #640 (H-3 finding)
Signed-off-by: Patrick Szymkowiak <patrick@rtk-ai.app>
Signed-off-by: Patrick szymkowiak <patrick.szymkowiak@innovtech.eu>
Keep develop's [Unreleased] section on top, followed by master's
released versions (0.34.3, 0.34.2).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Drop-based ChildGuard doesn't run on signals with panic=abort (release
profile). Register a signal handler that stores the child PID in an
AtomicU32 and kills it on SIGINT/SIGTERM, then re-raises the signal
with default handler for correct exit status propagation.
Fixes orphan processes when rtk proxy is killed by Claude Code, process
managers, or manual kill — the root cause behind issue #897.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Telemetry details are already documented in the README privacy section.
No need to print them during init.
Signed-off-by: Patrick szymkowiak <patrick.szymkowiak@innovtech.eu>
Also fixes flaky test_rewrite_rtk_disabled_warns_on_stderr: the subprocess part relied on target/debug/rtk being current, but cargo test doesn't rebuild the standalone binary.
Added mtime guard -> skips when binary is older than test executable.
Command::output() sets stdin to Stdio::piped() by default, creating an
empty pipe instead of inheriting the terminal. SSH signing tools
(1Password, YubiKey, gpg-agent with pinentry) need TTY access on stdin
for passphrase prompts or agent communication. This caused signatures
to be silently dropped — commits succeeded but without gpgsig headers.
Fix: add .stdin(Stdio::inherit()) to git commit and git push commands
so they inherit the parent's stdin (terminal or hook pipe). Output
capture via stdout/stderr pipes is preserved.
Signed-off-by: Patrick szymkowiak <patrick.szymkowiak@innovtech.eu>
Previously, commands not in any deny/ask list were auto-allowed. This
bypassed Claude Code's least-privilege default where unlisted commands
should prompt the user for confirmation.
Permission precedence is now: Deny > Ask > Allow (explicit) > Default (ask).
Changes:
- permissions.rs: load allow rules from settings.json, add Default variant
- rewrite_cmd.rs: treat Default same as Ask (exit 3)
- hook_cmd.rs: add permission checks to Copilot VS Code hook (ask/allow/deny),
add deny check to Gemini hook (no ask mode available in Gemini CLI)
Gemini CLI limitation: only supports allow/deny, no ask mode. Codex: ask
is parsed but fails open. These tools document the limitation.
Signed-off-by: Patrick szymkowiak <patrick.szymkowiak@innovtech.eu>
pr_merge() was using run_filtered with a filter_fn that ignored stdout
and always returned "ok merged". This made AI agents believe PRs were
merged when they weren't.
Switch to run_passthrough so the real gh output is shown. gh pr merge
is a destructive action — the user must see exactly what happened.
Signed-off-by: Patrick szymkowiak <patrick.szymkowiak@innovtech.eu>
When RTK runs via Claude Code's PreToolUse hook, grep/rg subprocesses
inherit the hook's open stdin pipe. They block waiting for EOF and never
terminate, accumulating memory unboundedly (reported: 514GB on 96GB Mac,
kernel panic).
Fix: set stdin(Stdio::null()) on both rg and grep fallback commands so
subprocesses get immediate EOF instead of inheriting the parent pipe.
Signed-off-by: Patrick szymkowiak <patrick.szymkowiak@innovtech.eu>
Add check-test-presence.sh script and CI job that fails if any *_cmd.rs
file added or modified in a PR is missing a #[cfg(test)] block.
- New CI job runs with no dependencies (parallel to all other jobs, <10s)
- Uses --diff-filter=AM to catch both added files and test deletions
- --self-test mode for local verification
- Add missing tests to wget_cmd.rs (17 tests) and env_cmd.rs (12 tests)
covering pure functions: compact_url, format_size, parse_error,
extract_filename, mask_value, is_lang_var, is_cloud_var, etc.
Fixes the enforcement gap: CONTRIBUTING.md required tests but CI did not
check. Now 34/34 *_cmd.rs modules have #[cfg(test)].
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Florian BRUNIAUX <florian@bruniaux.com>