Skip to content
HV · 07
FIELD NOTE · 04

AI AGENTS · APPROVALS

My agent found the wrong repository, I said no, and it posted the wrong numbers anyway. A no that only stops one call is not enough. Here is what it has to carry.

Rook is a small agent in Garu that checks this project’s repository every Monday and posts a line to Slack when something changed. Early on, I told it to watch “the Garu repo” without giving it the owner’s name. It searched, found somebody else’s project called garu, and asked to log that project’s stars and forks. The review card showed the wrong numbers, so I declined.

Then it tried to post the same wrong numbers to Slack. Of course it did. My no had stopped one tool call and said nothing about why. As far as the model knew, the numbers were fine and the log was the problem.

A decline carries a note

The fix was small and changed how I think about every approval screen. Declining a call in Garu now takes a note, and the note goes back to the model before its next step, as part of the refused call’s result:

DENIED by humberto: a message to the team
The person who declined said: "wrong repo, use humbertovillanueva/garu".
Act on this before doing anything else — correct the mistake if there is one,
and do not repeat it in later calls.

With that sentence in front of it, the model searched again, found the right repository and finished the run. A decline became a correction instead of a wall.

Approvals should write the policy

The complaint people had about the first always-on agents was that approving everything made the person the bottleneck. So a yes has to do more than let one call through.

In Garu, “approve for 24 hours” creates a grant scoped to this agent, this tool and this exact argument, a recipient or a path, until tomorrow. And when the same agent asks for the same tool three times and never hears a no, Garu proposes the narrowest rule that covers what was actually approved and offers to write it into the agent’s file, comments preserved. The policy converges toward what the owner does, instead of staying a document written once.

ENGINEERING RULE

Every answer a person gives an agent should change what the agent does next, not just whether this one call runs.

Silence is a no

An ask nobody answers expires after thirty minutes as a deny. I resisted this at first; most of what my agents ask for is fine. But an agent that gets a yes by default while its owner is away is not being supervised, and the whole design depends on supervision meaning something.

The morning two asks arrived one at a time

This morning showed me a gap in my own rules. Bea, the agent that sorts my inbox, ran at 7:15 and wanted to draft two replies. The kernel ran the calls of that step one after another, so it asked about the first draft and waited. Nobody was up. At 7:45 that ask expired, and only then did the second card appear. When I opened my phone at 8:14, I found one draft waiting and one that had quietly never been made.

Two fixes went out the same morning. Every call in a step now goes out together, so when two things need a yes, both cards are in the inbox at once; a test holds every answer until both asks are up, which the old one-at-a-time kernel could never pass. And Bea now runs at 8, when the phone is actually in my hand. The lesson is the same as the decline: an approval flow has to assume the owner is asleep, busy or wrong, and still leave the agent somewhere sensible.

What I would build first

  1. Let a decline carry a reason, and put the reason in the model’s context before its next step.
  2. Scope every temporary approval to the exact argument it was given for.
  3. Turn repeated approvals into a proposed rule the owner can accept.
  4. Make an unanswered ask a no, with a timeout that fits the owner’s day.
  5. Post every ask from one step at the same time.

The result

My agents ask about one or two things per run, not twenty. When I say no, the next step is better, not just blocked. And when I say yes three times, I stop being asked. That is what trusting an agent to run unattended turned out to mean in practice.

Garu is an independent open-source project under the Apache-2.0 license, unrelated to my employer. The repository names and the numbers in this note are from my own runs.

NextLet’s talk

Have something worth building?