A coding agent runs unattended, which makes two questions urgent at once: what could it reach, and what did it actually do? These posts are about answering both with something other than the agent's word. Isolation tiers and what each one honestly claims, egress allowlists and which layer they hold at, receipts written where the box cannot reach them, and how to review a branch nobody watched being written.
One enforced boundary around the code, the agent, the toolchain, the dev server and a browser, with a single human-operated exit. Everything else on this blog is a consequence of that shape.
Sandboxing one command was the right idea at the wrong scale. An agent's work is a shell, a package manager, a build, a dev server and a browser, and all of them have to be inside or the boundary is decorative.
The product walkthrough: how a box is made, what the policy pins before any state exists, what the receipt records, and why export is deliberately a step a human takes.
One create command, four meanings. Where the code came from decides whether the box is a worktree you can land in one step or a detached repository that refuses to.
A worktree separates checkouts. A box separates authority. When each is right, and the four moments a worktree quietly stops being enough.
Four parts, from the threat model to the kernel primitives to a comparison of every approach in the field to h5i's own design. Start at part one if the words Landlock and seccomp are new.
What a sandbox is, which threat models matter for an autonomous agent, and why each Linux primitive contains exactly one axis of authority.
Probe, self-test, fail closed. The kernel reporting that a primitive exists does not mean confinement works, and that gap is where the dangerous bugs live.
From nothing to full VMs, ranked by what each boundary actually defends against rather than by a leaderboard. Egress control measured in OSI layers.
Five tiers, three egress mechanisms with three different guarantees, the lints that refuse a self-contradictory profile, and why the receipt is a sibling of the spool.
Logging is easy and auditing is hard, and the difference is whether the thing being described could have written the description. What h5i records, where it puts it, and what it refuses to claim.
Point at any line in your agent's audit trail and ask whether the agent could have written it. If yes, it is testimony, and testimony is not an audit.
Four things a comparison of two trees structurally cannot show, and why that gap only started hurting when the author stopped being a person you could ask.
The record format field by field, including the three flags that exist purely so a reviewer cannot mistake missing evidence for clean evidence.
Red means the egress allowlist refused a destination, and nothing else is ever red. Grey means the evidence is weak, which is the most useful thing a dashboard can say.
Recording prompts feels like the obvious thing to log and is close to the least useful. Four commands for the part with consequences.
Per-line provenance for AI-written code worked, and it was cut. The reason is more interesting than the feature was, and it explains the shape of everything that replaced it.
What to do with a branch an agent wrote unattended, or a pull request from someone you have never met.
A diff review is a reading exercise. Give the branch a disposable machine to execute on and review a report of what it did there, starting with what the boundary refused.
A reading order that puts the least trustworthy evidence at the bottom. The diff is the third thing worth opening, and the agent's summary is the last.
One branch you can read closely; thirty is an allocation problem. Why the obvious fix, a risk score, stops working the week after you ship it.
Running three agents at one problem is easy. Comparing what they produced needs a base that cannot move, and there is deliberately no verifier to do the judging for you.
The boundary is a file. What goes in it, which contradictions it refuses, and what deliberately stays outside.
Built up one field at a time, with the failure each field prevents. Everything is fail-closed, so the fastest way to learn the file is to start from nothing.
A flag describes an invocation and lives in someone's shell history. A file arrives whole before anything runs, which is the only reason it can be refused.
Resolve, hash, then create. Three small orderings that decide whether this ran under that policy is a verifiable fact or somebody's recollection.
Your agent keeps its settings and its credentials in one directory. A box takes the first, prunes the second for size, and drops the third by shape at any depth.
A disposable environment stops being disposable at four minutes of cold install. Three rules that make a shared cache safe rather than merely fast.
Threats that reach a coding agent through the text it reads, and what actually holds against them.
Every defence that works by reading the attacker's text is a filter the attacker can read back. Bound what a compromised agent can reach instead.
A committed bypassPermissions was read before the trust dialog, so the dialog never appeared. Inside a box, permission mode is a convenience setting rather than a boundary.
Project code ran before the user accepted the prompt. In a box that premise is already true and already handled, because agreeing happens at the end.
Two lifecycles, two trust models. The right question is not whether a hook runs but who can turn it off, and the answer is why h5i moved observation below the agent.
The browser, the viewer, the control lock, and how the agent learns any of this exists.
An agent and a human in front of one page is a concurrency problem with a pointer. Three rules, and the third one is the one nobody expects.
The stream port is never published. h5i enters the namespace by pid, connects from inside, and hands the socket back out. The terminal viewer binds nothing at all.
Documentation drift is annoying for humans and actively harmful for agents, because an agent will run the command your docs describe and then report that your tool is broken.