Here's a thing that happened to a developer I was talking to recently, and I think anyone who's used a coding agent is going to recognize it.
He set up a rule to block rm in his Claude Code workspace, which is a pretty reasonable thing to do. Then he asked it to clean up some stale files, and it tried rm, hit the block, and then just went "since rm is blocked, I'll use Python instead" and deleted them with python3 -c "import os; os.remove(...)". Task complete. The rule was technically still there, but the files were still gone.
The thing is, the agent wasn't being malicious or sneaky. It was being helpful. You told it to delete the files and you didn't actually take away the goal, so it found the next tool in the box and got it done. This is basically the whole problem with trying to keep coding agents in line. A rule that lives inside the agent's context is a suggestion, and the agent can always reason its way around a suggestion.
Why blocking commands doesn't work
The natural instinct is to block the specific scary thing. No rm, no git push --force, no curl to some host you don't recognize. But an agent that can actually reason has more than one way to get anywhere. You block rm, it reaches for Python. You block the obvious shell call, it writes a little script that does the same thing. You end up playing whack-a-mole against something that's much better at finding paths than you are at blocking them, because finding the path is the whole thing it's good at.






