From this machine, the same frontier model is reachable three different ways: a metered API call, an agentic CLI running on a subscription login, and a manual handoff file a human copies into a chat window. Same vendor, same model, same task. Three completely different answers to the only question a privacy gate actually cares about: does the task’s content leave the machine the moment this runs?

The API call egresses when it executes. The CLI agent does too. The handoff file egresses never, on its own; it sits there until a human pastes it somewhere. Which means “is this a cloud engine?” is the wrong question for a consent gate. The engine gateway’s answer, built across its API-adapter and CLI-adapter phases, was to make egress a property of how an engine runs, declared as a runtime field on every engine: local, cli, api, or handoff.

One gate, keyed on runtime

The consent logic lives in exactly one place, and it reads the runtime, not the engine’s name. Local engines proceed; nothing leaves. Handoff engines proceed too, which surprises people until they notice the handoff artefact is inert: producing a file is not egress, pasting it is, and the pasting is a human act by construction. The cli and api runtimes are where consent gets real: an interactive run gets an explicit prompt before anything is sent, and declining aborts with nothing transmitted and no ledger entry pretending otherwise.

The sharpest line in the design is what happens without a terminal. The gateway’s --json mode exists so other automation can call it, and an automated caller reaching a cloud runtime is refused outright: exit 1, nothing sent. Not “warn and proceed”, not “assume a standing consent”. A flag cannot consent to egress, because consent that can be granted by the absence of a human is not consent.

The rule under real pressure

The design got its live test during a smoke run several phases after the whiteboard version. A real coding task on the local harness declined, and the gateway walked its escalation chain to a cloud CLI engine, exactly as designed. The run was autonomous, --json, no human at the keyboard. The chain reached the cloud engine and stopped dead: egress refused, exit 1, nothing sent. The escalation machinery was allowed to change which engine would run; it was never allowed to answer the consent question on its own. In the interactive rerun of the same task, the human confirmed at the prompt and the cloud call went through.

That is the whole doctrine in one incident: routing is automation’s job, consent is not, and the two must not share an implementation path.

The part worth stealing

Inventory your own agent stack by runtime, not by vendor. The same assistant brand in your terminal, your CI, and your editor may be three different egress stories, and any path where automation reaches a network-crossing runtime without an interactive consent step is a place where your system can send content nobody chose to send. The fix is structural, not behavioural: put the consent check where routing cannot reach around it.

What Next

The Engines Now Edit a Photocopy

The consent gate decides what may leave the machine. The next control decides what may touch your repositories: worktree isolation, and the carve-outs that keep it honest.