Guardrails
On this page
Guardrails watch the shell commands Claude runs and stop the risky ones before they run. They work in every session while Kotharo is on, with or without the team, and whatever the autonomy level.
A guardrail does one of two things:
- Hold: the command waits while Kotharo shows you what it would do, and runs only if you choose Proceed.
- Refuse: the command never runs, and Claude is told why.
What the core holds
| Command | Why |
|---|---|
git reset --hard | Throws away uncommitted work |
git clean | Deletes untracked files |
git push --force, -f, --force-with-lease or a + refspec | Overwrites the remote branch |
dotnet ef database update against a named or non-local database | Changes a shared database's schema |
Before it asks, Kotharo measures what the command would do, such as the files git clean would delete or the commits a force-push would drop, and shows that with the command.
The core refuses nothing outright. A team profile can add commands to hold or refuse, below.
How a hold works
A hold opens a pane, or draws in the band where there is no pane:
╭──────────────────────────────────────────────────────────────╮
│ ⚠ Guardrails · git reset --hard │
│ Command git reset --hard │
│ Would discard uncommitted changes in 3 files │
│ │
│ src/export.ts │
│ src/export.test.ts │
│ README.md │
│ │
│ 1 Proceed 2 Cancel Claude is waiting on your answer │
╰──────────────────────────────────────────────────────────────╯
- Cancel is the default, so pressing Enter by mistake runs nothing.
- Proceed runs the command as it was.
- A hold you don't answer in 10 minutes is cancelled. So is one that hits an error.
When a hold is cancelled, Claude is told the command didn't run, what it would have done, and not to retry it unless you ask. One hold shows at a time.
With teaching mode on, a hold or a refusal also says why the command is risky and what to do instead.
Add your team's own
A team profile can turn on more kinds in its own hooks/guardrail-rules.mjs:
| Field | What it does |
|---|---|
name | The name shown on holds and refusals |
destructiveGit | Hold the git commands above |
efDatabaseUpdate | Hold dotnet ef database update against a database that isn't local |
sqlcmd | Hold sqlcmd against a server that isn't local, unless the SQL can't write |
denyStacks | Refuse cdk deploy, cdk destroy and CloudFormation changes to the stacks listed, each with a reason |
cloudflareAccounts | Hold wrangler deploy to the Cloudflare accounts listed |
loggedInCloudflareAccount | The account wrangler falls back to, which must be one of those listed |
A profile also holds cdk commands with --all. Every kind is off unless the file turns it on. Turn each kind on in one plugin only, so a command is never held twice.
What guardrails are not
Guardrails catch commands. They sit beside the team's other safety rules, not in place of them: the actions that always ask, and the rules every session loads, such as never committing secrets and never pushing to main without your OK.
Next: Worklogs and continuity. All docs