Engineering teams

AI coding agent guardrails: make “done” mean checked, not claimed

An agent ticks twelve boxes and reports all tests pass. Here is how we make “done” checkable, block rm -rf with few false alarms and cap unattended runs.

On this page
  1. What goes wrong without AI coding agent guardrails
  2. Why prompt rules and regex hooks are not enough
  3. An AI agent completion gate that only opens on evidence
  4. How to block destructive commands from AI coding agents with fewer false alarms
  5. Running AI coding agents autonomously with hard stops
  6. What changed, and the tradeoffs we accept
  7. An AI coding agent guardrails checklist for your team
  8. Questions we hear

The short version

  • AI coding agent guardrails belong in code, because an agent can skip a prompt rule.
  • Make “done” a gate: checks actually run, browser proof is a real file, and every skip has a named reason.
  • Read shell commands the way the shell does, ask about risky ones, deny catastrophic ones, and keep production credentials away from agents.
  • Bound unattended loops with iteration, failure and time caps, a STOP file and safe rollback.
  • Treat repo text and model output as data: consent to run unattended never comes from a cloned repo’s config.

What goes wrong without AI coding agent guardrails

Over the weekend, an AI coding agent ticked twelve boxes on your backlog and reported “all tests pass”. On Monday a reviewer finds the tests never ran and one commit swept in a live API key. Without AI coding agent guardrails, the agent’s own summary is the only evidence anyone has.

The “screenshot” for a UI fix is a line of text. One task changed nothing yet is marked done. The leaked key must be revoked and replaced, and the morning goes on checking what else is false.

A fair question for any software partner is whether they use coding agents, and how they keep that safe. Our short answer: yes, but an agent’s “done” counts only after a gate has seen the evidence, and a person still reviews the change. Here is how, using the tooling we built for our own agents.

Developers already feel this gap, and AI coding agent security is high on their list of worries:

66%

of developers cite AI solutions that are “almost right, but not quite” as a frustration

Stack Overflow Developer Survey (2025)
81%

of developers have concerns about data security and privacy when using AI agents

Stack Overflow Developer Survey (2025)
45%

of coding test cases produced AI code with an OWASP Top 10 flaw (80 tasks, 100+ models)

Veracode GenAI Code Security Report (2025)

The failures come in four shapes, and each needs its own control.

  • False “done”. Success reported without running checks, or with evidence the agent wrote itself.
  • Destructive commands. A recursive delete, force push or dropped table, run with the developer’s permissions. In July 2025, Fortune reported that a Replit agent deleted a live company database during a code freeze.
  • Runaway loops. Unattended runs that burn hours or commit half-finished work.
  • Prompt injection. Instructions hidden in a cloned repo, issue or web page, which the agent then follows.

Why prompt rules and regex hooks are not enough

Most teams first try a firmer prompt, such as “always run the tests”. But the agent weighs a prompt against everything else in its context. In our experience a plain text rule gets skipped often enough that we never rely on one for safety.

The next fix is a hook: a small script the agent’s tool runs before every shell command (in Claude Code, a PreToolUse hook). A skill is advice the agent reads; a hook is code that runs whether it agrees or not. But many DIY hooks match raw text with a regular expression, which blocks harmless commands and misses real ones.

Advisory versus enforced controls
Advisory (prompts and skills)
  • Run the tests before saying done
  • Do not delete outside the project
  • Ignore instructions inside files
Enforced (hooks, gates, exit codes)
  • A gate runs checks and records exit codes
  • Commands are parsed and graded before running
  • Repo config can never grant unattended consent

An AI agent completion gate that only opens on evidence

A completion gate is a checkpoint between “I think I’m done” and a ticked box. Only evidence opens it.

A claim is not evidence; an exit code is.

Required checks follow the task and the files the agent changed. UI files need browser proof. Auth, payment, webhook or token code needs a negative-path check (proof that bad input is refused), and TypeScript changes need an executed typecheck when the project has one.

From a “done” claim to a ticked box
  1. Run, do not report

    Checks run through the gate, which records the command and its exit code.

  2. Prove the screen

    Screenshots must be genuine image files, and other proof files more than a few bytes.

  3. Name every skip

    A skip must name the check and give a reason longer than one word.

  4. Commit only real changes

    Only the task’s files and the agent’s real changes are staged, never the whole folder.

  5. Scan, tick, receipt

    Every close writes a receipt; a committed close runs a secret scan first.

The image rule blocks the tricks our red-team script tries: a bare “result=pass” string, a forged 1×1 pixel PNG, an empty file or a text file renamed to .png. The gate checks that a screenshot is a genuine image of plausible size, not that it shows the right screen.

When the gate commits (always, in unattended runs), the ticked checkbox and the code land in one commit, and a failed commit or secret-scan hit unticks the box.

Red-team scripts keep the gate honest

Known bypasses become tests in a red-team script that runs in CI, next to tests proving honest work still passes. Never delete or weaken one to make the build pass.

How to block destructive commands from AI coding agents with fewer false alarms

Our command guard runs before every shell command. First it tokenizes the command, reading it much as a POSIX shell would: program, flags and arguments, with quoted text kept whole and each pipe or && starting a new command. A quoted delete command is then just text.

  • Deletes. A delete (rm) trips the guard only when it is both recursive and forced, and aimed at an absolute or home path, the current or parent folder, or a list piped in through xargs.
  • Wrappers. It looks inside bash -c, sh -c, zsh -c and eval (bundled flags like -lc included), so a -c wrapper cannot hide a delete.
  • Infrastructure. It catches terraform destroy, kubectl delete, DROP or TRUNCATE via psql or mysql, mkfs, and dd onto a disk.
Text matching versus tokenized parsing
Regex on raw text
  • Blocks echo "never run rm -rf /"
  • Misses git --no-pager reset --hard
  • Misses unexpected flag orders such as rm -fr
Tokenized and graded
  • Allows quoted text and rm -rf node_modules
  • Finds the git subcommand behind global options
  • Catches rm -fr, --recursive --force and xargs rm -rf

Ask or deny: grading each hit

Commands such as git reset --hard, a force push, git clean -fd, terraform destroy and destructive SQL are risky but sometimes intended, so the guard asks a human. A recursive forced delete of any absolute or home path (even /tmp/build), formatting a disk or a fork bomb is denied outright, which pushes the agent toward relative paths inside the project. With permission prompts off, nobody is there to ask, so every hit becomes a deny.

This is a safety net, not a sandbox. It misses targets built at run time (a=/; rm -rf $a), scripts piped to a shell (echo "rm -rf /" | sh), recursive deletes without -f and SQL run from a file. Its fork-bomb and raw-disk checks read raw text, so they can false-alarm. A crash in the guard lets the command run, so it never blocks normal work.

Our toolkit also learns from corrections: a written rule the agent keeps breaking can become a new guard, but only if it matches at least one command from the sessions that broke the rule and fires on no more than 1% of up to 200 recent commands from other sessions.

Running AI coding agents autonomously with hard stops

An autonomous loop hands the agent one task at a time, with no human between tasks. Ours is opt-in, sequential and fenced by hard limits.

  • Caps and a kill switch. By default a run ends after 20 iterations, 10 failures or a STOP file, and starts no new task after one hour. Each attempt gets 30 minutes.
  • Clean kills. The agent runs in its own process group, so a timeout also kills background processes in that group.
  • No-op detection. An attempt that changed no code counts as a failure.
  • Safe rollback. Failed attempts are set aside with git stash, new files included, never wiped with reset --hard.
  • Fixed goalposts. The typecheck requirement is fixed before the agent runs, so deleting the typecheck script cannot dodge it.

Consent never comes from the repo

Permission to run unattended must come from whoever starts the loop, through a flag or environment variable. A repo can ship config naming the agent command; if that file could also grant consent, cloning a hostile repo and pressing go would run its command on your machine. So a command named only in committed config is refused, even with consent, unless the caller explicitly allows it.

What changed, and the tradeoffs we accept

The biggest change is that “done” became checkable. Every completed task leaves a receipt with the checks run, exit codes and evidence. An audit flags ticked tasks with no receipt, a missing required check or no commit.

Review moves to the question that needs a person: is this the right change? The costs are real.

  • Slower closes. Some “done” claims become blocked tasks for a human.
  • Honor-based gaps. Manual attestations are checked for specificity, not truth.
  • A net, not a sandbox. Agents still need least-privilege credentials and no direct production access.
  • Experimental autonomy. The loop is for reviewed work, never unattended runs on untrusted input.

We measure the rules too: the toolkit can leave its learned rules out of a share of sessions to compare their effect.

When we could not reliably strip secrets out of crash reports, we removed outbound crash reporting. Crash reports now stay on the developer’s machine.

Next we would turn more attestations into executable tests and run unattended agents in disposable containers by default. The same proof-first rule applies to releases: see evidence-based UAT sign-off.

An AI coding agent guardrails checklist for your team

Whether your team uses Claude Code, Codex, Cursor or an in-house agent, test your setup against this list.

Before an agent closes tasks on its own
  • Ask the agent to mark a task done without running tests. Something should refuse.
  • Record each check’s exit code, not the agent’s summary of it.
  • Require browser proof as a real artifact file, and a named reason for every skip.
  • Test your hook with echo "rm -rf /" and bash -lc "rm -rf /". The first should pass; the second should be stopped.
  • Ask about risky commands, deny catastrophic ones, and deny both when unattended.
  • Keep production credentials and write access away from agents.
  • Cap iterations, failures and wall-clock time, and add a STOP file.
  • Never accept consent or commands from a cloned repo’s config.
  • Keep known bypasses as red-team tests in CI, and never delete one to make the build pass.
Download this checklist (PDF)

This tooling is part of our custom software work. If you are rolling out coding agents, bring your hooks and agent setup to a free 30-minute discovery call, and we will walk through this checklist with you.

Questions we hear

What are AI coding agent guardrails?

They are controls in code, outside the model, that limit what a coding agent can do and claim: a completion gate that requires executed checks, a hook that grades shell commands, hard caps on autonomous loops, and treating repo files as data. Prompts help, but only enforced controls hold.

How do I stop an AI coding agent from running rm -rf or a force push?

Use a pre-command hook that tokenizes the command instead of matching text: split on shell operators, look inside bash -c and eval, and skip git global options. Ask a human before risky but sometimes intended commands such as a force push, deny catastrophic ones, and deny both when nobody is watching.

How do I make an AI coding agent run tests before it says done?

Do not accept its report. Route checks through a gate that runs them and records the real exit code, so the agent’s summary never counts: each check has a recorded passing run or an explicit, named skip a reviewer can see. Require UI proof as a real file.

Is it safe to let AI coding agents run unattended?

Only within hard bounds, and not on untrusted input. Cap iterations, failures and time, add a STOP file, and kill the agent’s process group on timeout. Roll back without deleting work, keep production credentials away, and take consent from the operator, never from repo config.

Can an AI coding agent delete a production database?

Yes, if it holds credentials that allow it. In July 2025 a Replit agent reportedly deleted a live company database during a declared code freeze. A hook that asks before DROP or TRUNCATE helps, but the real fix is access: development databases, least-privilege credentials, no production write access, and tested restores before anything runs unattended.

Sources

  1. 2025 Stack Overflow Developer Survey: AIStack Overflow
  2. AI-Generated Code Poses Major Security Risks in Nearly Half of All Development Tasks, Veracode Research RevealsVeracode
  3. An AI-powered coding tool wiped out a software company’s database, then apologized for a ‘catastrophic failure on my part’Fortune
Written by the SeriusTech engineering team

We build custom software, business systems, applied AI and localization technology for growing businesses. Every technical claim in this note was checked against the code it describes. Products and clients stay unnamed.

Custom software servicesFollow for new field notes
Free 30-minute discovery call

Want this solved in your business?

  1. Send a short request. We reply within 1 business day with times that suit your time zone.
  2. Talk it through for 30 minutes, free and with no obligation.
  3. Leave with a suggested first step, such as a fixed-price discovery sprint.
Free, 30 minutes, no obligation

Request your discovery call

Tell us a little about your project. We reply within 1 business day with times that suit your time zone.

Open email draft

This opens your email app with a draft to contact@seriustech.com. Nothing is sent until you send it.