Goal: a saved prefix rule must provably cover the current command and nothing risky. Otherwise fall back to an exact-command rule, or offer no rule.
New crates/execpolicy/src/amend.rs
BANNED_PREFIXES covers:
- shells, bare or with
-c/-lc
- interpreters, bare or with
-e/-c: python, node, ruby, perl, bun, deno, pwsh, cmd /c
- git, rm, sudo, doas, env, xargs, eval, exec
- package runners:
npm run/exec, npx, pnpm (including dlx), yarn, uv run, cargo run, make
Reuse PASSTHROUGH_WRAPPERS/SHELL_NAMES from shell_expand.rs.
verify_proposed_prefix(proposed, command, ruleset, workspace) checks, in order:
- Complex shell never gets a prefix. Redirection,
$(…), backticks, leading VAR=, globs, heredocs, or process substitution all fall back to exact.
- The banned list.
- No destructive offers. Never offer a prefix for a command that is destructive according to
analyze_command.
- Coverage proof. Run a simulated ruleset that includes the candidate rule. Every segment must evaluate to Allow and match no deny.
Where the proposed prefix comes from: an optional model prefix_rule on exec_shell. If none is given, use classify_command on the first segment.
Matcher change: an allow rule with command_exact=false never matches complex shell. Deny matching is unchanged.
Compatibility
- Saved rules use only existing fields, because
permissions.toml is deny_unknown_fields.
- The CHANGELOG must note that existing allow-prefix rules now prompt again when the command uses complex shell.
Tests
banned_prefix_is_never_saved
prefix_must_cover_every_segment
complex_shell_never_prefix_matched
destructive_prefix_never_offered
verified_prefix_round_trips_permissions_toml
existing_exact_repo_rules_unchanged
Size: M. Blocked by: A1. Spec: codewhale-ops approvals/specs/A-grants-authority-0.11.md (A2).
Goal: a saved prefix rule must provably cover the current command and nothing risky. Otherwise fall back to an exact-command rule, or offer no rule.
New
crates/execpolicy/src/amend.rsBANNED_PREFIXEScovers:-c/-lc-e/-c: python, node, ruby, perl, bun, deno, pwsh,cmd /cnpm run/exec, npx, pnpm (includingdlx), yarn,uv run,cargo run, makeReuse
PASSTHROUGH_WRAPPERS/SHELL_NAMESfromshell_expand.rs.verify_proposed_prefix(proposed, command, ruleset, workspace)checks, in order:$(…), backticks, leadingVAR=, globs, heredocs, or process substitution all fall back to exact.analyze_command.Where the proposed prefix comes from: an optional model
prefix_ruleonexec_shell. If none is given, useclassify_commandon the first segment.Matcher change: an allow rule with
command_exact=falsenever matches complex shell. Deny matching is unchanged.Compatibility
permissions.tomlisdeny_unknown_fields.Tests
banned_prefix_is_never_savedprefix_must_cover_every_segmentcomplex_shell_never_prefix_matcheddestructive_prefix_never_offeredverified_prefix_round_trips_permissions_tomlexisting_exact_repo_rules_unchangedSize: M. Blocked by: A1. Spec: codewhale-ops
approvals/specs/A-grants-authority-0.11.md(A2).