Skip to content
Pere Villega
Go back

Letting Go Without Losing Control

8 min read

A permission prompt feels like control because it makes the agent stop. We see the proposed command, press a key, and work continues. Repeat that often enough, though, and approval becomes a reflex rather than a decision.

Removing the prompt does not solve this problem. It merely removes the pause.

This distinction matters when people describe running a coding agent in “YOLO mode”. There is a technical setting involved, but there is also a much larger engineering decision: which actions may happen without us, inside which boundaries, with what evidence afterwards? Confusing the two is how we replace tedious supervision with unjustified trust.

Part I of this series dealt with working alongside agents. Part II begins when the agent can continue while we do something else. The transition is not from control to no control. It is from controlling individual actions to designing the conditions under which action is safe enough.

A Flag Is Not an Operating Model

Claude Code provides the admirably direct --dangerously-skip-permissions flag. Its documentation says that the corresponding bypassPermissions mode skips most permission prompts, including writes to protected paths, and recommends using it only in isolated environments where the tool cannot cause damage. The same documentation makes a second, useful point: permission rules are enforced by Claude Code, not by the model.

An enforced deny rule can block a matching tool call even when the model ignores an instruction. Its scope still matters: Claude Code’s Read and Edit rules do not cover arbitrary subprocesses which open files indirectly. Keeping a secret out of every subprocess’s reach requires operating-system isolation or removing access to it altogether.

At this point we have bounded the agent’s reach: which tools it may call, which files a process can access and which networks it can contact. We have not established that the requested change is the right one.

An agent can remain entirely inside its allowed directory yet delete the wrong file or implement the wrong business rule without exposing a secret. Even approved commands can produce a migration which is impossible to roll back. Sandboxing limits what a command can touch; it does not turn an ambiguous requirement into a good one. Claude Code’s sandbox documentation describes this narrower job well: filesystem and network isolation allow commands to run without repeated approval inside an operating-system-enforced boundary.

Permissions answer what may this process do? Autonomy also requires answers to several other questions:

Skipping permission checks without those answers is not autonomy. It is unattended execution.

Why Letting Go Feels Wrong

There is a practical reason for our reluctance. When I write a change, I acquire understanding while producing it. I see the awkward interface, the failing test and the assumption that no longer fits. When an agent produces the change, those small moments of learning happen somewhere else. The code may arrive before my mental model does.

There is a psychological reason too. Many of us learnt that professional care looks like attention to each step: type the command, inspect the output, make the next edit. Moving away from that rhythm can feel negligent, even when the repeated approvals add little safety.

Neither concern is irrational. The mistake is to answer them with a binary choice between watching everything and trusting everything.

Trust in a person is often broad and social. Trust in an automated process should be narrower. I do not need to believe that an agent has good judgement in general. I need evidence that, for this class of task, it stays inside a boundary and exposes mistakes quickly enough to recover.

That evidence comes from the system around it: repository isolation, tests, type checks, policy rules, resource limits, audit trails, deployment gates and rollback. This is the same principle discussed in the earlier chapter on AI-generated code security, applied to everyday development. The model proposes actions. Independent mechanisms constrain and judge them.

Grant Authority in Layers

Autonomy is not a switch. It is a collection of authorities which can be granted separately.

LevelThe agent mayThe agent must notEvidence before we widen it
InspectRead the repository and run known read-only checksEdit files or contact new servicesIts plan names the relevant boundaries and uncertainties
EditChange files in a disposable branch or worktreeTouch secrets, repository history or external systemsA focused diff and the required local checks
VerifyRun allowlisted builds, tests and local servicesWeaken tests or silently change the success criteriaCommands, exit codes and meaningful failure output
PackageCreate commits or review artefacts in an isolated workspacePush, merge, release or deployReviewable commits, provenance and residual-risk notes
OperatePerform a specific remote action inside a bounded environmentCross an irreversible or high-impact boundaryAudit logs, health signals, rollback and an explicit stop policy

This is an example, not a maturity model. A documentation repository may safely allow edits and commits while denying network access. A production investigation may allow broad reading but no writes at all. The useful boundary follows the blast radius, not the apparent sophistication of the task.

There are also actions I would keep behind a human decision by default: destructive data changes, credential and permission changes, deployment to a sensitive environment, acceptance of legal or financial terms, and communication sent in somebody’s name. Automation can prepare those actions and gather evidence. Authority to execute them is a different grant.

The table exposes why constant approval is a poor long-term control. A prompt appears at the level of a command, while risk often lives at the level of an outcome. git push may be harmless to a private scratch repository and consequential on a protected release branch. npm test looks benign, but a compromised script can use network and credentials if the environment permits it. Command names are useful signals; they are not a complete policy.

Make Failure Cheap Before Making Work Autonomous

The safest first autonomous task is not the task an agent is most likely to complete. It is the task we can most easily recover from when it does not.

Start with a disposable workspace and a narrow outcome. Remove production credentials. Deny network access unless the work genuinely needs it. State which files, tests and interfaces are out of bounds. Provide exact verification commands, including the expected result. Require the agent to stop when a constraint conflicts with the task rather than improvising around it.

Then preserve the evidence. A useful unattended run leaves more than a final diff:

This costs time and storage. Isolation takes setup. A comprehensive test suite is expensive. Logs need sanitising. Rollback mechanisms themselves fail. Strong constraints can also reject a valid approach or make a five-minute edit take an hour.

The answer is proportionality, not maximum ceremony. If deleting the workspace undoes the entire mistake, the evidence can be light. If a task can affect customer data, money or access, cheap generation does not make recovery cheap. The controls should become stronger before the authority does.

Watch the Boundary, Not the Cursor

Once the inner loop is trustworthy, human attention can move outwards.

The specification and acceptance tests deserve attention before the event stream. Review the constraints on the edits and protect the tests which define success, then use exceptions, changed boundaries and the final evidence to decide where to look more closely. This is not less supervision. It is supervision at a level where judgement matters.

There is a failure mode on either side. Too little authority leaves the human feeding commands to a very fast intern, adding latency without applying much thought. Too much authority hides bad assumptions until they have accumulated into a large, confident result. The workable position moves by task and by system.

I would widen autonomy only after observing repeated, recoverable runs under the narrower policy. When a failure reveals a missing boundary, add the boundary before trying again. When an approval repeatedly carries no information, replace it with an enforceable rule or remove it. Trust should grow from evidence, not boredom.

This changes the engineer’s job. We still decide what matters, what may be risked and what counts as proof. We stop pretending that clicking “allow” is the same as making those decisions.

The next question is therefore not which flag to enable. It is what to put on the other side of the interface. Specifications Are the Interface looks at how much specification is useful, which forms actually constrain an agent, and when another Markdown document merely gives us the appearance of control.


Share this post on:

Previous Post
Specifications Are the Interface
Next Post
Beyond Coding: Where Agents Are Useful