Capability Is Not Authority

Part two of The Ghost, the Shell, and Earned Autonomy. Start with The Agent Is Not the Work. Next: I Don't Turn Autonomy On. I Earn It..

The coding agent had done its part.

It had changed the application, run the local checks, and reached the point where the only honest next step was to open an authenticated browser and verify the workflow as a user. The authenticated browser profile already existed, but it was not part of the coding session's environment. I did not want to give the coding agent access just because the Task had reached that line in the checklist.

The easy solution was to make the agent bigger: browser tool, credentials, deployment access, review permissions, maybe a few more integrations while I was there.

I have built that agent before. It is convenient right up until I have to explain what it can do.

The better answer was to let the commitment continue in a different bounded environment. I call that environment a Shell.

One commitment, two bounded executions

Capability finds the candidate. Authority permits the action.

Coding Shell
Missing browser capability
Proposal
Continuation packet
Human gate
Single-use authority
Browser Shell
Bounded execution
Capability

“This Shell can reach and operate the surface.”

Authority

“This bounded action is permitted for this commitment.”

The coding Shell reports a specific missing capability. It does not improvise credentials or pretend the browser work is complete.

The giant-agent trap

Tool calling makes capability feel cheap. Add a server, expose a function, put another credential in the environment, and the agent can reach one more surface.

But each addition changes at least three things:

  1. The blast radius of a mistaken action.
  2. The identity under which the action occurs.
  3. The set of results I am prepared to trust without another check.

A single agent with code, cloud, browser, database, and review access is not one neat abstraction. It is several operating contexts hidden behind one chat box.

I wanted those contexts to be visible.

ShellCapabilityCredential boundaryTypical evidence
CodingEdit, test, build, commitDeveloper machine or isolated worktreeDiff, commit, test result
ReviewRead change state and checksSource-control identityReview state, CI result
VerificationExercise a built artifactLocal or isolated runtimeCommand output, artifact
Authenticated browserOperate a signed-in user surfaceBrowser profile outside the Task recordCaptured artifact, observed browser state, structured interaction log

A Shell is not a model. It is not a persona. It is not the Ghost from part one. It is a governed reference to an execution environment: what it can reach, whether it is healthy, which stable identity it represents, and where its credentials live.

The Shell answers where bounded action can occur.

The credentials themselves do not belong in the control plane. The control plane needs a non-secret reference to the identity. The credential stays with the provider of the Shell.

The sentence that fixed the model

While designing this, I caught myself attaching risk classes to Shells. The browser Shell “supported” browser mutations. The review Shell “supported” approval actions.

That was wrong.

Capability is not authority.

Capability answers: can this environment reach and perform this kind of action?

Authority answers: may this actor perform this bounded action, for this purpose, on this commitment, now?

A browser being able to click “Delete” does not authorize deletion. A source-control token being able to merge does not make every merge permitted. Encoding authority as a property of the Shell turns possession of a tool into permission to use it.

So the Shell registry describes declared capability and the access identity behind it. Live readiness belongs to the complete execution path. Authority lives in policy and explicit grants. The two meet only when an execution is authorized.

That separation is one of those small modeling decisions that makes the rest of the safety design possible.

Re-embodiment, not reassignment

I needed a word for the same durable responsibility continuing through another bounded execution. “Retry” was inaccurate: the first execution had not failed. “Delegate” suggested a new owner. “New Task” fragmented the evidence.

I landed on re-embodiment.

The Ghost retains the commitment. A new Shell gives it a different body for one bounded assignment.

The handoff has five parts:

  1. Validate the stop. The source execution must have a real capability gap, not a vague “I can't continue.”
  2. Compile a continuation proposal. It references verified evidence, reported findings, unresolved assumptions, and eligible Shells. It selects nothing.
  3. Check the environment. The destination identity, health, availability, route, and action envelope must be known before authorization.
  4. Authorize once. A human selects one Shell and issues an expiring, single-use authorization bound to the exact source state.
  5. Reconcile the result. The destination returns evidence. A separate decision confirms, rejects, or retries the outcome.

The source Task does not become “done” because another environment was found. The commitment does not fork. And the destination does not inherit a transcript full of assertions it cannot distinguish from evidence.

Registered is not ready

The first production attempt taught me that “check the environment” was still too shallow.

The browser profile can exist. The adapter can be registered. The control-plane gate can authorize the action. The exact operator session can still be unable to invoke the mapped browser tool because its client permissions or classifier policy block that control path.

Shell readiness is therefore a property of the complete route the action will take:

profile resolves
 target is authenticated
 control-plane gate is callable
 mapped Shell action is callable
 the same operator can perform both sides
 authorization may be consumed

On that first attempt, the handoff successfully created the second embodiment and consumed the single-use authorization. The control-plane action gate passed. The mapped browser action failed before it executed, so no browser artifact was captured. Cancellation then closed the destination execution cleanly, returned the Task to a stopped state, and preserved the commitment.

That was valuable evidence, just not the evidence I wanted. It proved the rollback path. It did not prove the successful browser-evidence path.

The fix was a fail-closed preflight over both halves: the Shell itself—stable profile identity, live connection, authenticated target, enforceable action envelope—and the exact operator environment—gate access, mapped tools, classifier permission, and one session able to perform both calls. Any unknown blocks authorization before the single-use grant is spent.

The packet is deliberately incomplete

My first handoff packet tried to be helpful. It copied the summary, the output, the context, and most of the conversation. In other words, it recreated the transcript problem from part one.

The useful packet is stricter. It keeps three lanes separate:

LaneMeaning
Verified evidenceCanonical references the destination can independently retrieve or check
Agent-reported findingsUseful claims from the source execution that remain claims
Unresolved assumptionsThings the destination must not treat as settled

It also states what authority already exists and what authority is still required. Finding an eligible Shell does not select it. Producing a packet does not launch it. A proposal is not an instruction.

The evidence that comes back has its own trust ladder. A browser execution may capture an artifact and report what it appears to show. That interpretation is still agent-reported. Independent verification requires another verifier; human confirmation requires a separate human decision. A screenshot does not promote itself up that ladder.

This can feel fussy until the first time a destination environment is authenticated as a real user. Then every ambiguity becomes a potential action taken under the wrong identity.

Five failures I wanted to make boring

The design became clearer when I stopped asking how the happy path should work and listed the failures I never wanted to debug from an audit trail.

The authorization is replayed. A single-use grant is consumed atomically with creation of the destination execution. A retry requires a new grant.

The source changes after approval. The grant is bound to the exact execution epoch and evidence state. If either moved, consumption fails closed.

Two workers continue at once. The Task has one current execution pointer. Advancing it and consuming the grant happen in one transaction; a stale worker loses the fence.

The claimed capability gap is false. The destination must add the missing capability, the source must genuinely lack it, and the stop must name it consistently. Otherwise there is no re-embodiment path.

The destination exists but cannot actually be operated. Stable profile identity, live connection, target authentication, operator permissions, and the mapped action path must all be preflighted before consuming a single-use authorization. Registered tools are not proof that this operator can call them.

None of this makes the model smarter. It makes concurrent, credentialed product behavior predictable—which is usually the more important job.

Why this is product design, not agent plumbing

The Shell model changed the interface I want humans to see.

Instead of an agent asking for a generic “allow browser” permission, the product can present a concrete decision: this commitment stopped here; this evidence exists; this capability is missing; this signed-in environment is eligible; this is the bounded action; this authorization expires and can be used once.

That is a product surface. The human can reason about it without understanding the agent's internal monologue.

It also gives me a much cleaner route toward autonomy. I do not have to decide whether “the agent” is autonomous. I can ask whether one Ghost may perform one low-risk action class in one Shell when specific evidence exists.

That is a smaller question. Small questions can be measured.

Shells make authority narrow enough to reason about. They do not prove that the system deserves to spend it without asking.


Previous: The Agent Is Not the Work

Next: I Don't Turn Autonomy On. I Earn It.

Related: Architecture from Workload applies the same instinct—derive from explicit constraints instead of hiding judgment inside a suggestion—to infrastructure design.