Your agent isn't reckless. It just can't see the blast radius.

2026年8月20日2 次浏览来源:Dev.to阅读原文

I've been running Claude Code as a daily driver for about three months now.

It writes Ansible I'd have taken a week to write.

It reads a codebase faster than I do.

It is, genuinely, very good.

It also once wanted to force-push to , and it wanted to for an extremely good reason.

Sit with that for a second, because it's the whole post.

The rebase was stuck.

Force-pushing would have unstuck it.

Every link in that chain of reasoning is sound.

The agent wasn't being careless, wasn't hallucinating, wasn't "drifting" or whatever we're calling it this month.

It made a locally correct decision with a non-local consequence, which is the exact category of mistake that human code review is worst at catching — because the diff looks fine.

It could see the command.

It could not see the crater.

The thing I stopped doing For a while my answer was to read everything.

Every diff, every command, eyes on the screen, hand hovering over Ctrl-C like a man watching a toddler near a staircase.

This does not scale, and the reason it doesn't is embarrassing when you say it out loud: reviewing output scales with how much the agent writes.

That number is going exactly one direction, and it isn't down.

So I flipped it.

Instead of reviewing what it produces, I started writing down what it must never do.

And here's the good news that took me way too long to notice: that list is short.

Not "short for a security policy" short.

Short like you can fit it on a napkin.

Here's mine: A credential it read an hour ago gets inlined into a source file.

A rebase gets stuck, and the fastest route to a green terminal is . runs on the one machine where never got set.

A version bump gets typed straight into , because that's the file the version number is visibly in.

A failing test quietly grows a and CI goes green.

Someone runs "just to see which variables exist." That last one is my favourite, and I'll come back to it.

None of these are the agent being stupid.

Every single one is a reasonable move by something that can't see two feet past the command it's about to run.

Claude Code will let you say no This is the part I think a lot of people don't know exists. is a hook that fires before any tool call.

Your script gets the whole thing on stdin: And you can refuse it: Now, the bit that genuinely surprised me.

That string?

The agent reads it.

And acts on it.

Say "blocked" and it shrugs and retries with slightly different syntax, like a cat testing a closed door.

Say "change the manifest and run " and it goes and does that, first try, no argument.

Which reframes the whole thing.

A denial isn't just a fence.

It's the highest signal-to-noise teaching moment you will ever get, because it lands at the precise second the agent was about to be wrong.

Nobody reads documentation at that moment.

Everybody reads an error.

So every guard I wrote has to answer two questions, not one: what's wrong, and what to do instead.

Thirteen of them They live here: claude-guardrails Guard Blocks Credential-shaped literals written into source Reading , , into the session in a repo where was never gitignored to , , , , , , where could be empty `curl … \ {% raw %} Editing a migration that's already committed Unbounded /, ad-hoc Destructive with no Introducing , , Hand-editing and friends Zero dependencies.

Nothing to configure.

Node reading a JSON payload and occasionally saying no.

Four of them turned out more interesting than I expected when I started writing them.

1.

Reading a secret is worse than writing one My first instinct was to guard the write — stop the key from landing in a file.

Then I thought about it for another minute and realised I had it backwards.

The write path has a code review in front of it.

Someone, eventually, looks at that diff.

The read path has nothing.

When an agent runs to check which variables exist, it gets a completely reasonable answer to a completely reasonable question — and every value in that file is now sitting in a transcript.

Transcripts get stored.

Synced.

Occasio

分享