# Guardrails for AI agents that run while I sleep

**Topic:** agent safety · **Published:** October 2026 · **Reading time:** 7 min

An agent that runs without me must not do damage while I am away, and it must not stop and wait for me for no reason. Both failures are real. This article lists the guardrails I use on a team of long-running AI agents for a regulated fintech platform, with the incident behind each one.

Prompt rules are not enough for this. An agent can read a rule, agree with it and break it later after its context compacts. So most of these guardrails are code that runs before or after the agent acts.

## 1. A hook that blocks commands before they run

Claude Code can run a check before each tool call. I use one such hook on every agent account. It refuses two kinds of command:

- **A directory change joined to another command** (`cd somewhere && ...`). This shape triggered a permission prompt, and an agent waiting on a prompt does nothing until a human sees it.
- **A foreground sleep of more than 30 seconds.** An audit of one day counted 422 foreground sleeps, which cost about 121 minutes of agent time per day, plus 140 calls that sat at the 10-minute tool limit, which cost about 1,462 minutes per day. The hook stops the sleeps. The long calls now run in the background.

The hook has known false positives, for example the text `sleep 60` inside a commit message. Each one costs a single retry. I accepted that trade.

## 2. No command may stop for approval

Every brief that lets an agent run commands carries the same clause: use the dedicated tools and absolute paths, never run a command that asks for approval, and if a blocked command is truly needed, stop and report it. An agent found waiting on a prompt is stopped and restarted with a better brief. Nobody approves from the agent's screen.

## 3. A usage guard at 90%

Agent accounts have a five-hour usage window. One morning, one account reached its cap, 10 to 12 lanes moved to a second account within 20 minutes, and that account went from 1% to 100% in about two hours. A level check looked healthy until the last half hour, because it did not look at the burn rate.

Now a watcher reads each account's burn rate every 2 minutes. From 90% of the window, a hook holds every new helper agent and workflow. Running steps finish. Lanes on a capped account wait for the reset or move to an account with room.

## 4. Every guard must be tested by breaking it

A guard that passes proves nothing. A guard that fails when you break the thing it protects proves it works.

This rule caught real defects. One detector for stale cloud tasks reported green when its own lookup failed, so it went silent exactly when credentials were degraded. Its fix was a third exit code. The rule now: each check has three results: **found a problem**, **found nothing** and **could not run**. "Found nothing" and "could not run" must never share an exit code.

A scheduled job can also fail with no trace. If the folder for a cron job's log does not exist, the shell cannot open the log file, and the job never starts. It writes no log and no error. After one machine move, two probes died this way, silently.

## 5. Name the environment in every claim

Agents once reported a production problem that was really in staging. The rule now: every finding and every action names its environment. A staging result is never carried over to production, or the reverse. A check that failed or returned nothing is reported as unchecked, never as passed.

## 6. A builder never reviews its own work

Each code change gets an independent reviewer agent, and the reviewer approves one exact version. If the change moves, the approval does not move with it. Every reviewer runs on the strongest model. On changes that touch money, identity checks, sign-in, infrastructure or security, the reviewer checks the server path with extra care and names what it did not verify.

## 7. A privacy check before anything leaves the building

Agents write pull request text, tickets and documents that other people read. Before any of it is posted, a script scans the final text for local paths, machine names and internal setup details. For a while, the checker refused every automated review comment until the review tool stopped citing local file paths. The fix was in the data the comment was built from, not in the rendered text.

## 8. Clean up what you start

Long-running agents start dev servers, tunnels and file watchers, and they forget them. On one machine, about 40 orphaned processes built up, some of them 13 days old, until 23 of 24 GB of memory was in use and swap was almost full. Now each lane runs an orphan check at each job end, at startup and before handover, and stops its own orphans and any orphan older than 24 hours, by exact process ID.

## What the guardrails have in common

- **They run as code**, not as a sentence an agent has to remember.
- **Each one came from an incident**, and the incident is written next to the rule, so the next agent knows why it exists.
- **Detectors fail loud.** A check that cannot run says so. The usage guard fails open on purpose, so an outage of the guard never stops the team.
- **They keep the human gate small.** Each guardrail removes a reason for an agent to stop and ask me, so the questions that reach me are about production and business decisions.

## What I would tell a team starting with agents

1. **Put the rule where the agent cannot skip it:** a hook before the tool call, not a line in a prompt.
2. **Log what agents wait on.** Prompts and sleeps can cost hours of agent time a day.
3. **Watch burn rate, not only usage level.**
4. **Break every guard once** before you trust it.
5. **Give "could not check" its own result.**

More on the system these guardrails protect is in [In the loop, near the loop, out of the loop](/writing/near-the-loop/).

Email [hello@jeffkent.dev](mailto:hello@jeffkent.dev) to talk about running agents safely.
