# Walk the command

Blocking `rm` outright is a blunt instrument -- agents delete build artifacts all day, legitimately. What you want is a judgment call: how many files does this `rm` actually hit, and are they recoverable? That's not a pattern; that's a walk over the parsed command. `evt.command` gives you one:

``` python
from captain_hook import Event, HookResult, PreToolUseEvent, Tool, on


@on(Event.PreToolUse, only_if=[Tool("Bash")])
def recoverable_rm(evt: PreToolUseEvent) -> HookResult | None:
    for call in evt.command.calls("rm"):
        if call.targets.expand().exhausted:
            return evt.block("rm targets too broad to verify -- narrow the glob")
        # rewrite `rm` to `trash`, targets and quoting intact: a mistake becomes a restore
        return call.sub("rm", "trash", args=call.targets)
    return None
```

This is the heart of the `rm` guard the shipped `general` pack runs. `calls("rm")` finds every `rm` across `&&`, `;`, and pipes; `targets.expand()` resolves the arguments -- globs included -- against the working directory; [sub](../../reference/files-commands.md#captain_hook.Call.sub) rewrites the call to `trash`, quoting intact, so a mistake is a restore instead of a loss.

The widget below runs that guard for real: the full pack source, shown read-only, walks a declared virtual filesystem in your browser, and every preset verdict is parity-tested byte-for-byte against the real engine on a materialized copy of the same tree. The Trash toggle decides the recoverable lane: with a trash binary the guard rewrites `rm` to `trash`; without one it blocks. A command that needs more world than the demo declares (a brace expansion, a `sh -c` wrapper, an absolute path outside the tree) gets an honest "outside this demo" card instead of a guess:


A rewrite is a third verdict you haven't seen yet: not allow, not block -- the command runs, but not the command the agent typed. Rewrites beat blocks when a safe variant exists, because the agent's task keeps moving.

[Next: gate the session itself.](../../docs/tutorial/stop-gates.md)
