Destructive Commands Need A Policy, Not A Gut Feel
Every team eventually hits the same problem: an AI coding agent asks to run a command that is technically valid and operationally risky at the same time.
The answer is not to ban every shell command. Claude Code and Codex need real tools to do useful work. The answer is to define which commands are allowed, which commands need approval, and which commands should stop the run until a human decides.
Junction is useful here because the command request, the live output, and the approval decision all sit in one control surface while the code still runs locally on the daemon machine.
Define What Destructive Means In Your Repo
Start with a concrete list. In most repos, destructive commands include:
- deleting files or directories,
- resetting branch history,
- force pushing,
- dropping or rolling back data,
- rewriting generated assets without review,
- and anything that changes shared state outside the current checkout.
For some teams, a database migration is not destructive by itself. For others, it is a human-only action. The policy should reflect your actual blast radius, not a generic fear of shell commands.
The point is to make the decision before the prompt arrives.
Separate Safe, Review, And Destructive Actions
A simple three-part policy usually works better than a giant list of exceptions.
| Category | Example | Default response |
|---|---|---|
| Safe | Read files, run focused tests, inspect git status | Allow |
| Review | Edit release notes, run a package command, create a branch | Review first if unclear |
| Destructive | rm -rf, git reset --hard, force push, data rollback |
Human approval required |
You can expand that into a fourth category for shared-state changes if your team needs it.
The key is that the agent should not have to infer which bucket a command belongs to.
Use A Policy The Agent Can Repeat Back
If the policy is too abstract, nobody will remember it when they need it.
Write something like this:
Destructive command policy:
1. Safe commands may run without extra review when the scope is local and obvious.
2. Review commands need a human check if they touch release files, shared state, or external systems.
3. Destructive commands require explicit approval and a clear rollback path.
4. If the command affects more than the current repo or worktree, stop and ask.
5. If you cannot explain the command in one sentence, do not run it.That fits in an issue, a team doc, or a prompt template. It is short enough to use and specific enough to matter.
Good And Bad Examples
Good examples of reviewable commands:
- running a focused test for the changed package,
- regenerating a known asset after the code path changed,
- creating a new branch for a scoped fix,
- or formatting files that are already part of the task.
Good examples of destructive commands:
- removing a generated directory that will be recreated from source,
- resetting a local branch that has not been shared,
- or rolling back a local experiment before re-running the task.
Bad examples are the ones that expand the blast radius:
- deleting a branch that other people may still need,
- force pushing over work you have not reviewed,
- or dropping data because the agent inferred that it was convenient.
The decision should be boring. If it feels clever, it is probably too broad.
Make The Approval Prompt Carry The Context
The policy works only if the approval prompt shows enough context to judge the command.
Ask for:
- the exact command,
- the repo or worktree,
- the intended effect,
- and the rollback plan if the command cannot be undone.
That is where Junction helps. The approval flow is tied to the actual session, so you can review the command in context instead of reconstructing it from a chat log.
If you want the deeper approval workflow behind this policy, How to Approve AI Agent Actions Safely is the right companion read.
Example: A Command That Should Wait
Suppose the agent is fixing a failing release note and asks to run a command that rewrites a shared generated file and force pushes the branch.
That is not a normal helper command. Even if the change looks small, the combination of shared output and branch history should move it into human approval territory.
The better response is to narrow the task:
- edit the source file,
- regenerate the output locally,
- review the diff,
- and push only after someone accepts the result.
That sequence keeps the destructive step visible.
Tradeoffs
Stricter command policy adds friction. That is real.
The tradeoff is that every forbidden command saves you from at least one cleanup problem later. Teams usually only appreciate the policy the first time it prevents a bad reset or an accidental overwrite.
The other tradeoff is that the agent may need to ask more often. That is acceptable. A local-first workflow should be bounded, not silent.
Where Junction Fits
Junction keeps the repo local, the command visible, and the approval decision close to the work. That makes destructive command policy practical instead of theoretical, especially when Claude Code or Codex is running on a machine you are not sitting in front of.
If you are setting this up for the first time, start with the setup guide and then compare pricing if you need more daemons or Switchboard. For adjacent workflow design, turning local AI agent runs into pull requests is a useful next step.