Blog
Govern the whole agent system
When I review an agent I trace what it can read, what it can change and how a person can stop or reverse it, which means looking at the harness and credentials as well as the model.

When I review an agent I trace what it can read, what it can change and how a person can stop or reverse it. The model generates the reasoning, but it doesn't decide which database is connected, which tools are exposed or whether a command runs straight away. Those decisions are spread across prompts, tool definitions, service accounts, job runners, approval screens and ordinary application code, so if you only review the model you miss most of the system.
I start with a named job, in plain terms. "Help with operations" is too broad. "Read a failed import report, identify the affected batch and prepare a retry for approval" gives me something to follow: where the request comes in, what gets loaded, which tools become available and what the agent can return. An agent might be read-only in one tool and have write access through another, a harmless-looking file tool might reach a directory with credentials in it, and a retry might also kick off notifications. I write the scope down before testing so that when a tool gets added, or a read becomes a write, it's obvious the review has to change too.
Then identities. A chat window can look personal while every request behind it runs as the same powerful service account, and the user may assume the agent only sees what they can see. Credentials also outlive prompts, because changing the system instruction doesn't pull a token off a worker or invalidate a queued job. For each connected system I record:
- which identity the tool uses
- how the credential is issued and stored
- which records or actions it permits
- whether access differs by user, role or environment
- where an operator can revoke it
I don't put a confirmation on every tool call, since that mostly teaches people to approve without reading. Checks go where the consequence changes: sending a message, modifying a record, moving money, publishing, deleting data or starting something expensive to unwind. The approval screen should show the target, the intended change, any side effects and whether it can be reversed, which a raw function name and JSON payload don't. Lower-risk work can run inside a narrow boundary, as long as tool code enforces it by restricting paths, validating identifiers and capping batch sizes.
The harness and job runner need their own look. Someone can stop the visible conversation while a background process keeps going, queued tasks can start with old permissions or old instructions, and a retry can repeat a write that succeeded but never reported back. If the system can't tell whether an external write completed, it should stop for reconciliation instead of sending it again. And what does the stop button actually reach? Only the next model request, or running commands, queued work and the retry worker as well?
When I review an agent, I'd test at least a cancelled job, a tool timeout, an expired credential, a duplicated request and a result that reaches one system but not the other, and check whether the operator can see the incomplete state. Most of those failures live in the harness, the credentials and the job runner, which is why looking only at the model misses most of what the agent can read, change or fail to stop. For each approved job I'd keep a short trace (entry point, context sources, identities, tools, consequential actions, stop mechanism and recovery path) close to the implementation, and rerun the review whenever one of those entries changes.
On X
Got a take on this?
Share it on X. I read the replies.