Let the agent go YOLO: introducing ZTD
There’s a moment, a few hours into pairing with a coding agent, when you realize
you’ve stopped reading the permission prompts. Allow rm? Allow curl | sh?
Allow writing outside the repo? Yes, yes, yes. The dialog that was supposed to
keep you safe has become muscle memory — which means it keeps you safe in exactly
the way a seatbelt you’ve unbuckled does.
You have two bad options. Read every prompt and lose the speed that made the agent worth using. Or click through them and lose the safety. ZTD is a bet that the choice is false — that the right boundary was never a dialog box in the first place.
The boundary should be a machine, not a modal
A permission prompt is a trust mechanism: it asks you, the human, to vouch for each action. That works when there are ten actions. It collapses when there are ten thousand, run unattended, overnight.
The alternative is an isolation mechanism: don’t ask whether an action is safe — make it impossible for an unsafe action to matter. Run the agent somewhere it can do anything it likes, and arrange things so that “anything it likes” can’t reach the stuff you care about.
That somewhere is a VM. ZTD spins one up, drops the agent inside in full
YOLO mode (--dangerously-skip-permissions,
no prompts), and guarantees the blast radius ends at the VM’s edge. The agent goes
fast because nothing it does on the inside can hurt you on the outside.
Zero trust, pointed the right way
“Zero trust” usually means a network that trusts no one. ZTD points it at a single relationship: the host never trusts the guest. The guest is assumed compromised from the first boot. Concretely, that means:
- The host’s Docker socket is never exposed to the guest. The VM runs its own Docker daemon; a runaway agent can’t reach your containers.
- No host filesystem access beyond the one repo path you share in.
- The guest holds only a per-VM SSH key that grants nothing on your forge — no forge credentials at all. All forge git (clone, push) is a host operation.
It is deliberately not trying to protect the guest from the host, or one guest from another. One job, done well: keep the agent’s mess off your machine.
Cattle, not pets
If the VM is disposable, the whole workflow gets simpler. ZTD treats every VM as cattle: created for a task, run autonomously, and destroyed. The valuable output isn’t the VM — it’s a git branch or merge request the agent pushes before the box is torn down. You review that branch on your host, like any other, and the VM goes back to nothing.
“Fixing” a bad run isn’t debugging a sick pet; it’s ./ztd reset for a fresh one
from the same image. No drift, no snowflakes, nothing to lose.
One interface, wherever the VM lives
The same workflow should work whether the VM is on your laptop, a homelab Proxmox
node, or a cloud instance. So ZTD hides the difference behind a single interface
and one TARGET:
./ztd up # local KVM
TARGET=proxmox ./ztd up # same box, on ProxmoxUnderneath, Terraform swaps providers per backend — but you never touch that. And
in keeping with the theme, the orchestration tooling itself runs in a container:
the only thing ZTD asks of your host is Docker, plus a hypervisor when the VM is
local. Run ./ztd check and it tells you exactly what’s missing.
Try it
The quickstart gets you from a clean host to a running, isolated VM in about a minute. Or read the zero-trust model for what “isolated” actually guarantees.
ZTD is pre-v1 — local KVM and Proxmox today, an EC2 backend and a proper ztd CLI
on the roadmap. But the core bet is
already here: stop reading the prompts, and let the machine be the boundary.