The point became clear to me while working on the GitHub adapter (a more or less simple GitHub gateway for AI agents creating PRs).
At first, creating a pull request looks like one write. A branch is created, commits are pushed, and a PR appears. The API call is concrete, and the result is easy to name.
But after building around it for a while, the word "write" started to feel too imprecise. A pull request is not only a technical object. It changes the state of a repository and creates something that another person may have to review. If it duplicates an existing proposal, it can already be noise before anyone reviews it. If it touches a deployment file instead of a README, the same operation suddenly has a very different weight.
The operation name did not change.
The effect did.
In the previous parts, I argued that the agent should not hold the write credentials, that tool access is not the same as impact permission, and that blocked requests should return boundary feedback instead of generic tool failures.
This leads to the next point (or let's call it problem).
Even if write authority is moved behind a boundary, the word "write" is still too coarse.
A permission table can say that an action may write. That is useful, because it separates reading from changing. However, it does not say where the change lands, who sees it, which systems react to it, or whether another decision is still possible before the effect becomes larger.
A draft and a sent email are both writes. A pull request and a merge are both writes. Updating test data and changing production data are both writes. Technically, all of them change state. Operationally, they are not the same event.
This is the weakness of flat write access. A system can enforce the permission correctly and still allow the wrong kind of effect.
Reach is the missing property
The useful distinction is not only whether an action changes state.
The useful distinction is reach.
By reach, I mean how far the effect travels before another decision is required. A change that stays inside an isolated workspace has low reach. A change that creates work for another person, becomes visible to users, changes production, or sends something outside the system has higher reach.
This is why the same technical write may need different treatment. A draft email still stays inside a controlled workflow, while a sent email leaves it. A pull request is not a merge, but it already changes the repository workflow. A staging change can be acceptable with little friction, while the same change against production should pass a stronger gate.
The boundary should therefore not only ask whether the verb is allowed. It should ask how far the requested effect is allowed to go.
This is the point where "write" stops being a sufficient impact class.
Reversibility is not enough
A tempting classification is reversible vs. irreversible.
This helps, but it is not stable enough as the main boundary.
Real systems are rarely cleanly reversible. A draft may allocate an ID. A temporary object may leave logs, cache entries, metrics, notifications, or review noise. A staging change may start automatic work. A pull request may consume reviewer attention even if it is later closed.
The primary object may be deleted, but the system has already changed.
Therefore, reversibility should only be a secondary signal. A reversible action can still cross an important boundary. An action that cannot be fully undone can still be isolated and low impact. What matters for admission is not only whether the object can be removed, but what became visible, costly, dependent, or relevant while it existed.
Reach captures that better than reversibility.
The boundary needs structure, not guesswork
A boundary cannot reliably control reach if the agent only submits plain language.
A request such as "update the customer record" is not enough. It may mean a harmless internal note, a billing change, a correction in production data, or a change that notifies someone. These are different effects, even if the sentence looks similar.
A second model may help as an additional signal, but it should not be the main boundary. If the control layer has to read a paragraph and guess the effect, the hard part has only moved into another interpretation step.
The cleaner design is that the agent submits a structured intent before an external effect is possible. The request should make the relevant parts explicit: the kind of action, the target, the expected state, the environment, and the intended result.
This does not mean that the agent gets to declare its own safety.
The agent can propose what it wants to do. But the system around the boundary has to make the relevant effect visible. A path, repository, branch, account, environment, URL, or table is not only a string in the request. It has to be resolved by the system that owns the boundary.
This is important because a tool name does not tell us enough.
A generic tool may be able to do harmless and risky work. Treating the whole tool as high impact creates review noise. Treating it as low impact misses dangerous use. The useful classification is therefore not "this tool is safe" or "this tool is dangerous". The useful classification depends on the resolved target and on the effect that the interface exposes.
A write to an agent-private scratch folder is different from a write to a deployment file. A request to a status endpoint is different from a request that changes billing. A test data update is different from a production data update.
This only works when the interface exposes enough detail. If the target cannot be resolved, the request should be treated as broad. If a tool hides what it may change, the boundary cannot magically recover that information from the tool name. In that case, the safer answer is to wrap the tool with a narrower interface, require review, or block the request.
Narrow admission only works when narrow effects are visible.
The tool is not the boundary.
The resolved effect is.
Small actions can add up
Per-request admission does not mean memoryless admission.
A single small write may be acceptable, while many small writes can become a larger operational effect. This is especially relevant for agents because retries are not always simple technical retries. The agent may rephrase the same goal, split it into smaller steps, or move toward the same blocked outcome through another route.
The boundary should be able to notice that pattern.
However, this memory must not depend on an identifier the agent can freely choose. If the agent can reset a trace ID, rename the task, or create a new parent label to escape accumulated context, the control is not real.
Cross-request signals have to be tied to something the agent cannot invent on its own, such as a workflow record created by the boundary, the underlying user or service identity, a signed work order, or another trusted identity.
With that constraint, workflow memory does not contradict per-request admission. Each requested effect is still evaluated separately. There is no broad write window. But the decision is not blind to recent denials, repeated similar intents, unusual volume, duplicate effects, or ignored boundary feedback.
At some point, the next safe action is no longer another small admission.
It is review.
The boundary is not the whole target system
There is also a limit to what the boundary can claim.
The boundary sees the request at the interface. It does not automatically know every automatic effect that happens inside the target system afterward. A narrow-looking write may start internal rules, background work, notifications, audit records, or other follow-up actions.
The agent requested one write.
The system may produce many effects.
This does not make the boundary useless. It defines its responsibility. The boundary controls the handoff from agent request to admitted effect. The target system still has to own what happens internally through clear behavior, access control, data rules, and production safeguards.
If an endpoint can create a stronger effect behind the scenes, that effect should be part of what the endpoint exposes to the boundary. If the boundary cannot know it, the request should be treated as broader or sent to a stronger gate inside the target system.
The boundary is not a proof that everything behind the interface is harmless.
The boundary is a controlled handoff point.
The narrower claim
This does not make the agent correct.
It does not prove that generated code is good, that an email is wise, that a data update is meaningful, or that a deployment is safe. Tests, review, domain knowledge, and normal engineering judgement remain necessary.
The claim is narrower.
A boundary should control how far an agent request is allowed to reach before another decision is required.
That reach is not defined by the verb alone. It depends on the resolved target, the surrounding workflow, and the effects exposed by the target system.
Write access only says that state may change. It leaves open where the change lands, who sees it, and what other systems start doing because of it.
That is why write access is too flat for agent work.
A draft, a pull request, a staging update, a production write, an external message, and a payment may all be writes.
They do not reach the same world.
The verb is not the boundary.
The effect is.
Project: Impact Boundary Labs
Top comments (0)