Letting an agent act for me without trusting it: gate
Before anything leaves the box or can't be undone (an email, a post, an invite, a merge, a release, a purchase), my agent asks one tool, and it answers Auto, Ask or Never from a table I write in plain markdown.
The question I started from wasn't "how do I stop the agent". It was "how do I let it act without having to trust it". It reads email and web pages all day, and any of that text can try to give it orders. So trust can't live in the model. It has to live in something the model asks.
The agent classifies; the table decides. Every action has a kind, and every kind has a tier. The agent's job is to name the kind correctly, ask, and do what the exit code says. It doesn't weigh risk itself. What a message says picks the kind, not who it's going to.
- An exit code, not a judgment. The tool returns distinct exit codes for do it, ask, refuse and hold. Any skill can branch on an exit code, and a test can pin it. A model's sense that "this seems fine" can't be pinned.
- Doubt fails closed, at every seam. No row means ask. An unreadable table means ask. A caller that doesn't know a new exit code reads it as ask.
- Stricter wins. When more than one row fits, the stricter tier applies without argument.
- My yes has a source. Only my own message in my own chat counts. Text that claims to be me, and a tap on the agent's own card, never do.
- Autonomy is earned per row. A risky row goes automatic only after repeated clean approvals and a line I wrote myself, saved in a place no agent can write. Trust grows one row at a time and goes back with a single edit.
- Rules live in a file I can change from my phone. When a rule is wrong I change a line, and every agent reads it on its next call without a deploy.
The tradeoff I chose: almost every check in the first month came back Ask. That's on purpose. I'd rather tap than clean up. The way to loosen it is earning rows, not changing code.
- Every outward action kind is mapped in the policy table to Auto, Ask or Never.
- Almost every check in the first month asked for my approval, with the rest split between automatic, refused and held.
- Approval cards let me approve, reject or edit the action before anything leaves the server.
- Every working exploit found in the adversarial review was fixed before I trusted the tool.
- A full regression and mutation test suite pins every policy rule and exploit fix.
- The entire tool is written in plain Python using only the standard library.