refactor(hooks): inject the permission verdict so rewrite_cmd tests don't read ~/.claude/settings.json - #2636
Conversation
beaff1f to
7cf623b
Compare
7cf623b to
42a1c18
Compare
|
Independent reproduction on Hit this today on a machine with Isolating I see 2 of the 3 failures you describe, not 3: none of my deny rules match I wrote this fix independently before finding your PR and converged on the same shape: |
…ttings The unattestable_passthrough tests called evaluate() → check_command(), which reads the host's real Claude/rtk permission rules. On a machine with a deny rule for 'rm -rf' or an allow rule for 'git status', the outcomes flipped (Deny/Allow instead of the expected Passthrough/Ask), failing 3 tests locally while passing on default-config CI. Extract evaluate_with_verdict() so tests inject the verdict (the same seam check_command_with_rules already provides), making them machine-independent. Adds explicit Deny/Allow verdict coverage now that it's testable. Production behavior is unchanged: evaluate() still calls check_command(cmd) and delegates. The split is a refactor, not a behavior change.
42a1c18 to
f8838fe
Compare
Problem
rewrite_cmd.rs'sunattestable_passthroughtests callevaluate(cmd, …), which callscheck_command(cmd)→permissions::load_permission_rules()— reading the host's real Claude permission rules at test time. So 3 of 6 tests fail on any machine with ordinary deny/allow rules (adenyforrm -rfpre-empts the expectedPassthrough; anallowforgit statusturns the expectedAskintoAllow) while passing on default-config CI — "green on CI, red on my box."Root cause + fix
evaluatemixes the permission verdict (I/O — reads host settings) with the rewrite/passthrough decision (pure logic over the command string), with no seam. This extractsevaluate_with_verdict(cmd, verdict, excluded, transparent)holding the existing body;evaluatebecomescheck_command(cmd)+ delegation. Production behavior is byte-identical; tests inject an explicitPermissionVerdict(Askneutral for the passthrough/rewrite branch;Deny/Allowto pin the verdict-dependent branches that were previously untestable without real rules). This mirrors the permission layer's owncheck_command_with_rulesinjection pattern.Files
src/hooks/rewrite_cmd.rs— split outevaluate_with_verdict; test module injects the verdict.Test plan
cargo fmt --all --check && cargo clippy --all-targets && cargo testcargo test --bin rtk rewrite_cmd::tests::unattestable_passthrough— 8 pass on any machine regardless of~/.claude/settings.json(was 3 failing locally).Deny→RewriteOutcome::Deny(short-circuit),Allow→RewriteOutcome::Allow(_).Context
The exact bug (rewrite_cmd permission tests reading host settings) is unreported, but it is the same class of test-isolation defect upstream is already fixing for telemetry: #2106 (telemetry tests write a real
.device_salt) and #2603 (adds telemetry test-isolation helpers — the same injection pattern). Filed as a sibling to that work; see also the related issue. Test-only, no production behavior change.Closes #2640.