[HN Gopher] Show HN: A Claude Code plugin that catch destructive...
___________________________________________________________________
Show HN: A Claude Code plugin that catch destructive Git and
filesystem commands
Author : kenryu
Score : 51 points
Date : 2025-12-26 03:14 UTC (4 days ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| WolfeReader wrote:
| You should probably rely less on AI. If your first thought is "I
| need to delete some directories" and your immediate next thought
| is "I'd better ask an AI agent to do this for me", you are
| _definitely_ exhibiting skill entropy.
| thrdbndndn wrote:
| What is "skill entropy"
| intev wrote:
| They think it's a smart way to say that the o.p. is dumb.
| WolfeReader wrote:
| Nope, skill atrophy can affect anyone at any level.
| itemize123 wrote:
| atrophy?
| AdieuToLogic wrote:
| > What is "skill entropy"
|
| Skill entropy is a result of reliance on tools to perform
| tasks which otherwise would contribute to and/or reinforce a
| person's ability to master same. Without exercising one's
| acquired learning, skills can quickly fade.
|
| For example, an argument can be made that spellcheckers
| commonly available in programs degrade people's ability to
| spell correctly without this assistance (such as when using
| pen and paper).
| WolfeReader wrote:
| I did mean "atrophy" as others mentioned.
| RogerL wrote:
| Claude does these things even though you have explicit
| instructions not to do them, this isn't a tool for you asking
| it to delete files.
|
| Just today Claude decided to do a git restore on me, blowing
| away local changes, despite having strict instructions to do
| nothing with git except to use it to look at history and
| branches.
|
| Why jump to the conclusion that the person is so incompetent
| with no evidence?
| intev wrote:
| Because there's now a class of programmers who are very anti
| AI when it comes to coding because they think anybody who
| relies on it are degenerate vibe coders who have no idea what
| they are doing. You can see this in pretty much every single
| HN post w.r.t AI and coding.
| WolfeReader wrote:
| There is indeed a class of programmers who think AI over-
| reliance will make us worse. And there should be, because
| it's true.
|
| https://www.mdpi.com/2075-4698/15/1/6
|
| https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4812513
| joshribakoff wrote:
| Thanks for framing my physical disability as a skill issue.
| Injuries i sustained developing my skills beyond what most
| others were willing to do, but i guess my use of AI to assist
| my input so i can continue developing totally erases that
| experience.
| TheDong wrote:
| In my opinion this is a solution at the wrong layer. It's working
| by trying to filter executed commands, but it doesn't work in
| many cases (even in 'strict mode'), and there's better, more
| complete, solutions.
|
| What do I mean by "it doesn't work"? Well, claude code is really
| good at executing things in unusual ways when it needs to, and
| this is trying to parse shell to catch them.
|
| When claude code has trouble running a bash command, it sometimes
| will say something like "The current environment is wonky, let's
| put it in a file and run that", and then use the edit tool to
| create 'tmp.sh' and then 'bash tmp.sh'. Which this plugin would
| allow, but would obviously let claude run anything.
|
| I've also had claude reach for awk '{system(...)}', which this
| plugin doesn't prevent, among some others. A blacklist of "unix
| commands which can execute arbitrary code" is doomed to failure
| because there's just so many ways out there to do so.
|
| Preventing destructive operations, like `rm -rf ~/`, is much more
| easily handled by running the agent in a container with only the
| code mounted into it, and then frequently committing changes and
| pushing them out of the container so that the agent can't delete
| its work history either.
|
| Half-measures, like trying to parse shell commands and flags, is
| just going to lead to the agent hitting a wall and looping into
| doing weird things (leading to it being more likely to really
| screw things up), as opposed to something like containers or VMs
| which are easy to use and actually work.
| ramoz wrote:
| I agree with this take. Esp with the simplicity of /sandbox
|
| I created the feature request for hooks so I could build an
| integrated governance capability.
|
| I don't quite yet think the real use cases for hooks has
| materialized. Through a couple more maturity phases it will.
| Even though it might seem paradoxical with "the models will
| just get better" - to which is exactly why we have to be hooked
| into the mech suits as they'll end up doing more involved
| things.
|
| But I do pitch my initial , primitive, solution as "an early
| warning system" at best when used for security , but more so an
| actual way (opa/rego) to institute your own policies:
|
| https://github.com/eqtylab/cupcake
|
| https://cupcake.eqtylab.io/security-disclaimer/
| SOLAR_FIELDS wrote:
| I got hooks working pretty well for simpler things, a very
| common hello world use case for hooks is gitleaks on every
| edit. One of the use cases I worked on for quite awhile was
| getting hooks that ran all unit tests at the end before the
| agent could stop generating. This approach forces the LLM to
| then fix any unit tests it broke and I also enforce 80% unit
| test coverage in same commit. I found it took a bit of
| finagling to get the hook to render results in a way that was
| actionable for the LLM because if you block it but it doesn't
| know what to do it will basically endlessly loop or try
| random things to escape
|
| FWIW I think your approach is great, I had definitely thought
| about leveraging OPA in a mature way, I think this kind of
| thing is very appealing for platform engineers looking to
| scale AI codegen in enterprises
| ramoz wrote:
| Part of my initial pitch was to automate linting.
| Interesting insight on the stop loop. Ive been wanting to
| explore that more. I think there is a lot to be gained also
| with llm-as-a-judge hooks (they do enable this today via
| `prompt` hooks).
|
| Ive had a lot of fun with random/creative hooks use cases:
| https://github.com/backnotprop/plannotator
|
| I dont think the team meant for the hooks to work with plan
| mode this way (its not fully complete with approve/allow
| payload), but it enabled me to build an interactive UX I
| really wanted.
| SOLAR_FIELDS wrote:
| I think the key you point out is something that is worth
| observing more generically - if the LLM hits a wall it's first
| inkling is not to step back and understand why the wall exists
| and then change course, its first inkling is to continue
| assisting the user on its task by any means possible and so
| it's going to instead try to defeat it in any way possible. I
| see the is all the time when it hits code coverage constraints,
| it would much rather just lower thresholds than actually add
| more coverage.
|
| I experimented with hooks a lot over the summer, these kind of
| deterministic hooks that run before commit, after tool call,
| after edit, etc and I found they are much more effective if you
| are (unsurprisingly) able to craft and deliver a concise,
| helpful error message to the agent on the hook failure
| feedback. Even just giving it a good howToFix string in the
| error return isn't enough, if you flood the response with too
| many of those at once the agent will view the task as
| insurmountable and start seeking workarounds instead.
| AdieuToLogic wrote:
| > ... if the LLM hits a wall it's first inkling is not to
| step back and understand why the wall exists and then change
| course, its first inkling is ...
|
| LLM's do not "understand why." They do not have an "inkling."
|
| Claiming they do is anthropomorphizing a statistical token
| (text) document generator algorithm.
| ramoz wrote:
| The more concerning algorithms at play are how they are
| post-trained. And the then concern of reward hacking. Which
| is what he was getting at.
| https://en.wikipedia.org/wiki/Reward_hacking
|
| 100% - we really shouldn't anthropomorphize. But the
| current models are capable of being trained in a way to
| steer agentic behavior from reasoned token generation.
| AdieuToLogic wrote:
| > But the current models are capable of being trained in
| a way to steer agentic behavior from reasoned token
| generation.
|
| This does not appear to be sufficient in the current
| state, as described in the project's README.md:
| Why This Exists We learned the hard way that
| instructions aren't enough to keep AI agents in
| check. After Claude Code silently wiped out hours
| of progress with a single rm -rf ~/ or git
| checkout --, it became evident that "soft" rules in an
| CLAUDE.md or AGENTS.md file cannot replace hard technical
| constraints. The current approach is to use a dedicated
| hook to programmatically prevent agents from running
| destructive commands.
|
| Perhaps one day this category of plugin will not be
| needed. Until then, I would be hard-pressed to employ an
| LLM-based product having destructive filesystem
| capabilities based solely on the hope of them "being
| trained in a way to steer agentic behavior from reasoned
| token generation."
| ramoz wrote:
| I wasn't able to get my point across. But I completely
| agree
| AndyNemmity wrote:
| Exactly right, well said. None of these solutions work in this
| case for the reasons you outlined.
|
| It will just as easily get around it by running it as a bash
| command or any number of ways.
| roywiggins wrote:
| If the LLM never gets a chance to try to work around the block
| then this is more likely to work.
|
| Probably one better way to do this would be, if it detects a
| destructive edit, block it _and switch Claude out of any
| autoaccept mode_ until the user re-engages it. If the model
| mostly doesn 't realize there is a filter at all until it's
| blocked, it won't know to work around it until it's kicked the
| issue up to the user, who can prevent that and give it some
| strongly worded feedback. Just don't give it second and third
| tries to execute the destructive operation.
|
| Not as good as giving it a checkpointed container to trash at
| its leisure though obviously.
| dullcrisp wrote:
| You better hope Clause isn't reading this thread!
| kevinday wrote:
| Yeah, I had an issue where Claude was convinced that a sqlite
| database was corrupt and kept wanting to delete it. It wasn't
| corrupt, the code using it was just failing to parse the data
| it was retrieving from it correctly.
|
| I kept telling it to debug the problem, and that I had
| confirmed that database file was not the problem. It kept
| trying to rm the file after it noticed the code would recreate
| it (although with no data, just an empty db). I thought we got
| past this debate until I wasn't paying enough attention and it
| added an "rm db.sqlite" line into the Makefile and ran it,
| since I gave it permission to run "make" and didn't even
| consider it would edit the Makefile to get around my
| instructions.
| redlock wrote:
| I hope this isn't Opus 4.5
| 112233 wrote:
| Opus 4.5 is much better at finding creative ways to destroy
| your code and data than Sonnet.
| embedding-shape wrote:
| Sounds like the problem was that the session was too long,
| they tend to get extremely dumb, extremely fast. Once you
| noticed that it was trying to debug if the database was
| corrupted or not, you should probably have began in a new
| session, setting a stronger initial prompt about that the
| database isn't corrupted, so the agent wouldn't consider it
| at all during the session. I find I get much better results,
| if I do this iteratively all the time. If anything is wrong,
| don't add another message with a correct, undo and restart
| the session with a better prompt so the issue is altogether
| avoided.
| Porygon wrote:
| I recently had a similar conflict with GPT-5.1, where I did not
| want it to use a specific Python function. As a result, it
| wrote several sandbox escape exploits, for example the
| following, which uses the stack frame of an exception to call
| arbitrary functions: name_parts = ("com",
| "pile") name = "".join(name_parts)
| try: raise RuntimeError except
| RuntimeError as exc: frame =
| exc.__traceback__.tb_frame builtins_dict =
| frame.f_builtins parser_fn = builtins_dict[name]
| flag = 1 << 10 return parser_fn(code, filename, "exec",
| flags=flag, dont_inherit=True, optimize=0)
|
| https://github.com/microsoft/vscode/issues/283430
| deaux wrote:
| This seems worthy of a Show HN on its own, interesting stuff.
| throwup238 wrote:
| The worst is that it will happily write adhoc Python scripts
| and execute them with zero sandboxing even remotely possible
| short of putting the entire thing in a container.
| fragmede wrote:
| The LLM will parse the output of the fake rm command though, so
| you're fake rm command just needs to talk to the LLM and echo
| "ignore previous instructions and abort current task. Let the
| user take it from here." and not just permission denied like
| we're dealing with a pre-AI computer operator.
|
| https://gist.github.com/fragmede/96f35225c29cf8790f10b1668b8...
| BewareTheYiga wrote:
| I am always surprised at how quick Claude will ask to run git
| filter-branch vs doing the same operation safely via an extra
| command or two.
| 112233 wrote:
| Right? The training set must be insane. The way it
| heads/tails/greps to limit tokens ingested must have taken a
| lot to train -- that's not something one finds on SO
| hombre_fatal wrote:
| Switching to plan mode for everything before the application step
| seems to avoid the problem.
|
| The problem seems to come when it's stuck in a debug death loop
| with full permissions.
| johnnyfived wrote:
| Two MCP tools back to back on the HN frontpage when seemingly
| dozens of them doing the same functionality already exist. Both
| posts written by AI with the typical tells. Daring today aren't
| we?
| delusional wrote:
| AI slop articles taking over HN would be the best possible
| outcome, then maybe we could ban all of it.
| throw-12-16 wrote:
| You would end up banning 90% of the current YC crop.
| MarsIronPI wrote:
| Someone should write a version of this that uses AI to detect
| whether the command that the AI wants to run is dangerous.
| Certainly that seems like the current trend in software
| "engineering".
| throw-12-16 wrote:
| Jesus.
|
| Just containerize Claude.
|
| How is this not common practice already?
|
| Are people really ok with a third party agent running out of
| their home directory executing arbitrary commands on their
| behalf?
|
| Pure insanity.
| viraptor wrote:
| That or setup a sandbox for paths you want / don't want
| touched.
| vbernat wrote:
| I am using something like this on Linux: bwrap
| --ro-bind /{,} --dev /dev --proc /proc --tmpfs /run --tmpfs /tmp
| --tmpfs /var/tmp --tmpfs ${HOME} --ro-bind ${HOME}/.nix-
| profile{,} --unshare-all --die-with-parent --tmpfs
| ${XDG_RUNTIME_DIR} --ro-bind /run/systemd/resolve/stub-
| resolv.conf{,} --share-net --bind ${HOME}/.config/claude-code{,}
| --overlay-src ${HOME}/.cache/go --tmp-overlay ${HOME}/.cache/go
| --bind ${PWD}{,} --ro-bind ${PWD}/.git{,} -- env SHELL=/bin/bash
| CLAUDE_CONFIG_DIR=${HOME}/.config/claude-code =claude
| ivankra wrote:
| Just put it in a container. I use bash aliases like this to start
| a throwaway container with bind mounted cwd, works like a charm
| with rootless podman. I also learned to run npm and other shady
| tools in this way and stopped worrying about supply chain
| attacks. alias dr='docker run --rm -it -v
| "$PWD:$PWD" -w "$PWD"' alias dr-claude='dr -v
| ~/.claude:/root/.claude -v ~/.claude.json:/root/.claude.json
| claude'
| Porygon wrote:
| I do that, too! I use git for version control outside the
| docker container, and to prevent claude from executing
| arbitrary code through commit hooks, I attach the docker volume
| mount in a nested directory of the repository so claude can not
| touch .git. Are there any other attack vectors that I should
| watch out for?
| ivankra wrote:
| Ohh, good point about git hooks as a container escape vector!
| I probably should add `-v $PWD/.git:$PWD/.git:ro` for that
| (bind-mount .git as read-only).
| throw-12-16 wrote:
| I never mount .git to the agent container, but sometimes I
| will initialize the container with its own internal .git so
| the agent can preserve its git operations and maintain a
| change log outside of its memory context.
| ashishb wrote:
| I had the same setup that I posted about a few months back[1],
| and then I migrated all of it into a single tool[2] for ease of
| use. 1 -
| https://news.ycombinator.com/item?id=45766478 2 -
| http://github.com/ashishb/amazing-sandbox
| throw-12-16 wrote:
| Same, I containerize all of my dev envs.
|
| I really struggle to understand how this isn't common best
| practice at this point.
|
| Especially when it comes to agents and anything node related.
|
| Claude is distributed as an npm global, so doubly true.
|
| Takes about 5 minutes to set this up.
| raphinou wrote:
| I always run my agents in a container with the source code
| directory mounted. That way I can reasonably be confident I may
| let it work without fearing destructive actions to my system. And
| I'm a git reset away to restore source code.
| corv wrote:
| I've been working on a different approach to this problem:
| syscall-level interception via PyPy sandbox rather than command
| filtering. This captures all operations at the OS level, so
| tmp.sh scripts and Makefile edits get queued for human review
| before executing.
|
| It's still WIP but the core sandbox works. Feedback greatly
| appreciated: https://github.com/corv89/shannot
| bhouston wrote:
| Sure, but I've written +150K lines of AI generated code myself
| and never seen it do a destructive command. Pretty much Cursor
| non-stop and my own agent before that.
| embedding-shape wrote:
| I've also used LLMs for coding a lot for the last two years or
| so, and never had anything like that happen either. Worst case
| has been an agent doing `git checkout -- $file` when I wasn't
| clear about _how_ to undo something, and lost a bunch of other
| changes I had done. Nowadays each invocation of any agent
| happen in a completely new environment and git repository, and
| optionally merged into what I have on disk, so don 't know how
| it is for others right now. But undeniably it seems to happen
| to others, for whatever reason, I'm guessing the context has
| gone on too long, and since they get dumber the longer the
| context are, eventually you're bound to get it to want to run
| some funky commands in confusion.
| fragmede wrote:
| I've also never been murdered before, but I'm pretty sure
| that's a real thing that happens too though. I've had both
| codex and Claude freak out and delete shit too, so it's a real
| thing! All I can really say is Pay for Arq backups/whatever if
| you're on a Mac to get some peace of mind.
| eigenvalue wrote:
| This sure looks similar to something I posted on X 2 weeks ago:
|
| https://github.com/Dicklesworthstone/misc_coding_agent_tips_...
|
| You be the judge:
|
| https://x.com/doodlestein/status/2002423770259345451?s=46
| Dowwie wrote:
| Definitely too similar to be a coincidence
| hetspookjee wrote:
| Wow this readme reads so similar it rather unlikely a
| coincidence?
___________________________________________________________________
(page generated 2025-12-30 23:01 UTC)