Governance as a Feature
Approvals, audit, and the orchestrator-as-trust-layer are not bolted on. They are the thing that makes autonomy comfortable enough to give an agent the keys.
Most products treat governance as compliance overhead. We treat it as the product.
Every other AI coding tool we've looked at presents the same tradeoff to the user: more autonomy means less oversight, less autonomy means less leverage. Toggle a slider; pick one. The assumption is that approvals, audit trails, and review workflows are taxes you pay on the way to the “real” feature, which is the agent shipping code.
We disagree. The way an agent gets the keys is not by demanding fewer gates — it's by giving the operator gates that are cheap to walk through. A one-tap approval on a diff that's already been read by the orchestrator is not friction. It's confidence. The system that lets you ship more code isn't the one with no gates. It's the one with the right gates, ordered the right way, with the cognitive load bounded at every step.
The reason humans don't trust autonomous agents isn't the agents. It's the absence of governance shaped for them.
So we built the governance shaped for them. Five blocking gates between a worker and main, an audit spine that persists every operator decision into the next dispatch's context, and a single load-bearing human checkpoint that you can answer from your phone in three seconds. That's the feature.
Worker output never reaches main without passing through these in order.
Each gate is blocking. Each one is ordered. Skipping any of them is not a configuration option.
- G1 — Packet contract.Before a worker ever runs, the orchestrator writes the packet: what the change is, which runtime executes it, what branch it lives on, what the success criteria are. The packet is a contract. The worker either fulfills it or doesn't.
- G2 — Worktree isolation.The worker runs inside a freshly-checked-out git worktree. It can't touch main. It can't see other workers' in-flight changes. Concurrency is bounded by physical isolation, not by convention.
- G3 — Orchestrator review.When the worker emits a diff, the orchestrator reads it first — with the original packet, the directives that constrain the change, the recent outcomes that touched adjacent code, and the symbol graph for the files involved. If anything is wrong, the orchestrator reprompts the worker. The operator never sees a bad diff.
- G4 — Operator approval.The single place a human is required. By the time the diff lands in your inbox — on desktop or on your phone — it has already been reviewed by an LLM that understood the packet. One tap. Ship or send back.
- G5 — Audit trace. Approval logs an event. The merge logs a session outcome. The Brain ingests both as facts. The next dispatch on this codebase will retrieve them. Nothing happens off the record.
The only one that interrupts you is G4. The other four happen while you're doing something else.
The orchestrator reading the diff before the human does is the load-bearing claim.
A pull request from a human is an artifact you can roughly trust. The author had context, made tradeoffs, knew what they were doing. A pull request from an autonomous worker is an artifact you can't. Even if the diff is technically correct, the worker may have misunderstood the scope, missed a directive, regressed something the original packet didn't mention. Human reviewers catch some of that. They miss most of it because human reviewers were built for human authors.
o8's answer is that the orchestrator is the first reviewer, not the operator. Claude reads the worker's diff with the full original packet in front of it, with the Brain's relevant facts loaded into context, and with the worktree's file changes traversable. It judges whether the worker satisfied the contract. If not, it reprompts — often inside the same packet, often with a sharper instruction that fixes the issue without operator involvement.
By the time you see the diff at G4, you're not reviewing the worker. You're ratifying the orchestrator's judgment. That's a different cognitive task. It's smaller. It scales.
The trust layer isn't the operator. The operator is the ratification step. The trust layer is the model reading the diff before the human ever sees it.
This is also why we don't ship a “skip review” mode for advanced users. The orchestrator review isn't slow enough to be worth skipping — it runs in the seconds between the worker finishing and the diff landing in your inbox — and it's the only thing standing between unreviewed agent output and a merge. Removing it would be removing the feature.
One tap, three seconds, designed for the place you actually are.
The operator surface has one job: present a diff that has already been reviewed, in a frame that lets you say yes or no without thinking about anything else. We built it for the phone first.
- The inbox is the home screen. Not a chat, not a file tree, not a project picker. The inbox shows you the small handful of things that need your attention, ranked by recency. Everything else is hidden until you ask for it.
- Each card shows one decision.The packet summary, the diff stat, the orchestrator's one-line verdict, and three buttons: approve, reject, ask. No scrolling required for the binary case.
- Asking re-engages the orchestrator.If you need more context before deciding, hit ask — the orchestrator answers in line, pulling from the Brain and the directives. You stay on the same card. No context switch into a chat surface.
- Push notifications respect the boundary. We page you when an operator decision is genuinely needed, not when an agent prints a status update. If the orchestrator is handling something itself, the phone stays quiet.
The desktop surface is the same shape with more density — the inbox in a sidebar, the diff in the workspace, the same three buttons. The point of having both is that you should be able to ratify a fleet decision from the bus, the bathroom, or the back of a meeting. Approval that requires you to be at your desk is approval that becomes a bottleneck.
Every operator decision becomes context for the next one.
When you tap approve, five things persist. An event row in the approvals table records that you (specifically) approved (specifically) this diff at this time. A row in the session outcomes ledger records the dispatch that produced the diff, how long it took, which runtime ran it, what got changed. The merge itself lands as a structured artifact. The Brain ingests the outcome as a fact tagged with the packet's intent. And the next dispatch on this codebase, when it asks the Brain for relevant prior decisions, gets your approval back as cited context.
That last step is the one that matters. The audit trail isn't for compliance theater. It's for reuse. Every approval you give is information about what you consider acceptable in this codebase. The system learns from your decisions whether you intended it to or not. Over a few weeks, the orchestrator's pre-review at G3 gets sharper because it has retrieved your prior approvals on adjacent changes. The whole loop tightens.
Audit logs are usually evidence for things that already happened. Ours are training data for things that haven't.
The same spine catches rejections. When you say no to a diff, the rejection is logged, the outcome is recorded as a regression signal, and the Brain extracts a fact about why— either explicitly (you typed a reason) or implicitly (the orchestrator infers from the diff and the rejection). That fact will surface the next time a worker tries to ship something similar. The system doesn't forget the “no.”
Loopback only, ws-token bearer, hard middleware. The blast radius stays small.
The other half of governance is keeping the fleet from doing things you didn't authorize at all. Every API route that touches agent or repo state in o8 is gated by a single middleware. It runs in Node runtime, not edge, so it has the same access to the local environment that the rest of the app does — and it enforces two rules.
- Loopback only. Requests must come from
127.0.0.1,localhost, or the Tauri webview's own origin. Cross-origin requests are rejected before the route handler runs. This is the difference between a desktop app and a hosted service: the attack surface is your machine, not the public internet. - Bearer token for cross-origin.When a cross-origin request needs to reach the API — for example from the mobile shell talking back to the desktop — it must present an
Authorization: Bearerheader matching the ws-token written to~/.o8/ws-token. The token never leaves your devices. - A small read-only allowlist. First-run setup endpoints and OAuth handshakes get GET-only access without the bearer. Everything that mutates state is gated.
The middleware is documented in src/middleware.tsand the rule is enforced everywhere: never add a new route prefix that touches state without going through the gate. If a route needs public access, it goes under the read-only allowlist or it doesn't ship.
The point: governance includes “what the user approved” and“what could ever be asked to be approved in the first place.” The middleware handles the second one. The five gates handle the first.
The gates are cheap. The cost is in not having them.
| Gate | Latency added | Where it runs |
|---|---|---|
| G1 packet contract | 0 | Pre-dispatch, written by the orchestrator before a worker spawns |
| G2 worktree isolation | ~50ms | git worktree add, one-time per packet |
| G3 orchestrator review | 5–15s | Sonnet reads diff + packet + Brain context |
| G4 operator approval | human time | One tap; the only blocking-on-you step |
| G5 audit trace | <10ms | SQLite write + indexer enqueue |
The full cost of the orchestrator review (G3) is paid once per packet, not once per file. A 12-file diff costs about the same to review as a 2-file diff because the review prompt is shaped around the packet's intent, not the file count. That makes governance scale with the operator's decision load instead of the worker's output volume.
The cost of nothaving governance is harder to quantify cleanly but easier to feel. Every minute spent re-reviewing a worker's output you've already accepted three times. Every regression that ships because nobody noticed the directive existed. Every conversation where you have to re-explain a constraint that's been written down twice already. The fleet either remembers or it doesn't. Ours does.
The pattern most other tools picked. The pattern we picked instead.
| Pattern | Their bet | Where it leaves o8 |
|---|---|---|
| Editor with optional review | Make the agent fast inside an IDE; review is a code-review tool layer. | We don't ship an editor. The review is the product surface, not a tab in someone else's tool. |
| Cloud autonomous agent | Agent runs on a remote VM, opens PRs against your repo, GitHub review handles the rest. | GitHub review wasn't designed for agent authors. We add the orchestrator pre-review and a phone-first approval surface above the diff. |
| Slack-bot dispatch | Mention an agent in a thread; it runs and reports back. | Threads aren't a governance surface. We ship a real inbox with structured cards and an audit spine. |
| Manual policy engines | Write rules in YAML. The system blocks what doesn't match. | Rules in YAML are a different shape from organizational memory. Our rules are facts in a substrate that an LLM reads alongside the diff. |
None of these are wrong for their audience. The pattern we picked is the one that fits a single operator running a fleet of agents in their own repos, on their own machine, with their own subscriptions, who needs the governance to be local-first and phone-friendly. That's the wedge. The other patterns scale to bigger orgs with different requirements. We'll get there. Today, we're built for the operator who is also the founder.
The gates are stable. The next bets are about transparency, learnability, and reach.
- Recall Card — ambient governance. Today the directives that constrain a packet are loaded into the orchestrator review at G3. They aren't shown to the operator at G4. Recall Card surfaces them in the sidebar so you see why the orchestrator approved a diff before you do. Issue #966.
- Brain UI — ask the substrate directly. A
/askchat-input quick action that lets you interrogate the substrate from inside the approval flow, without leaving the diff. Issue #965. - Quality regression dashboard. The smoke gate is a 6-case substring rubric. The full eval is 30 cases with Sonnet-as-judge. We need historical tracking so governance regressions surface visibly, not just in commit logs. Issue #969.
- Better contradiction surfacing.The compactor reports candidate contradictions today via a heuristic. Refining it with IDF-weighted overlap and an LLM judge moves it from “noisy report” to “trusted signal.” Issue #968.
Each of those is a refinement, not a redirect. The shape of governance in o8 is the shape we want. We're sharpening the edges.
Without governance, autonomy is a demo. With it, autonomy is shippable.
The largest unsolved problem in AI engineering tools right now isn't making agents better — the models are improving on a curve nobody at any company can move faster than. The unsolved problem is making agent output shippable to productionby a small team that can't afford to babysit them.
That problem is governance-shaped. It's about how a human stays in the loop without becoming the bottleneck. It's about how a fleet of agents inherits its operator's taste without being told the same thing every conversation. It's about how a rejection today shapes the next dispatch's prompt automatically, not via documentation a new agent will never read.
We built the gates, the orchestrator pre-review, the audit spine, and the inbox-as-home-screen because that's the wedge. Not the editor. Not the model. The thing that turns autonomous agents from a demo you watch into a fleet you ship with.
Governance is what makes “the agents shipped 14 PRs while you slept” a sentence you say with relief instead of dread.