Library / SDK
qntx/ovo avatar
qntx/ovo

Ovo: an embeddable multi-agent runtime kernel for Rust, and where its sandbox story breaks down

Agent behavior that compiles

569 stars95 forksRustApache-2.0

At a glance

What is it?
Ovo packages an agent turn loop, a journaled Rhai workflow mode and a set of OS sandbox backends into a Rust library you embed rather than run as a server. The README is unusually honest about the gap between compiling the sandbox features and actually having a working sandbox at runtime.
Who is it for?
Adopt Ovo if you are building a Rust host application that needs to own the approval gate, the jail directory and the process isolation backend itself, and you are prepared to pin a 0.9.x version because the README states breaking changes land without compatibility layers. Do not adopt it if you want a turnkey sandbox or an out-of-the-box agent server; the README states platform_sandbox() can return Failed for a pure library dependency and that there is no NoSandbox fallback.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

What Ovo is for, and who it is not for

Ovo describes itself as an embeddable multi-agent runtime kernel for Rust. The word kernel is doing real work here. This is not a service you start and point a client at. It is a library you link into a host application, and the host application is expected to supply the parts that a framework would normally decide for you: the approval gate, the jail directory, and the OS sandbox backend. The README's production path is explicit about this, naming TurnOptions::for_host(gate) together with sandboxed_host or default_toolkit as the combination intended for real deployments. Everything else in the constructor table is positioned as a test or offline path. TurnOptions::default() is documented as AutoApprove and explicitly labelled not a production default. InProcessHost::new defaults to AlwaysDeny and, per the README, does not install an OS backend. If you are the kind of team that wants an agent runtime to make these decisions for you, Ovo is pointed the other way. It expects you to have already decided what a destructive action is and who approves it. The dual-mode design is the other half of the pitch: a dynamic spawn mode and a journaled Rhai workflow mode, with the workflow path giving you a scripted, replayable shape rather than an open-ended loop. The README does not spell out the journaling format, so treat that as a gap to close by reading the crate source rather than the front page.

The feature flags are the architecture

Most of what you need to know about Ovo's structure is in its feature table, and the table reads like a warning. The default feature set is runtime plus workflow. That compiles the kernel and the workflow engine, and it links ovo-sandbox only for TrustedExecution. It does not compile the toolkit. The README states this directly: runtime is not toolkit, and a default cargo add ovo does not compile toolkit. So the filesystem and shell tools that most people picture when they hear agent runtime are behind a separate flag. Enabling toolkit gives you a cwd-jailed filesystem and shell, but the README is clear that this alone provides no OS sandbox; it needs seatbelt on macOS or landlock on Linux. The sandbox feature on its own only compiles policy types and the SandboxBackend trait. The full feature is described as toolkit plus state plus observability plus openai and ollama integrations plus sandbox types, and the README bolds the fact that full is not an OS sandbox. Passing --all-features gets you full plus the seatbelt and landlock compile-time backends, and even then the README notes Linux still needs the helper binary. This is a deliberate layering, and it is defensible: a library that silently pulled in a platform sandbox would be harder to audit. But it means the distance between a compiling dependency and a confined agent is several deliberate steps, and the crate will not tell you when you have skipped one.

Getting a turn running without fooling yourself

The README gives one embed example. It constructs a host with sandboxed_host(sampler, backend, jail), where backend is an Arc<dyn SandboxBackend>, either SeatbeltBackend on macOS behind the seatbelt feature or LandlockBackend, constructed with new or with_helper, on Linux behind the landlock feature. The turn options come from TurnOptions::for_host(Arc::new(AlwaysDeny)), and the comment in the sample tells you to replace that gate with a UI gate. The README also warns, in the same passage, not to treat platform_sandbox() as turnkey. On Linux the helper has its own installation path: ship ovo-landlock in the same directory as the host binary, set OVO_LANDLOCK_HELPER, or put it on PATH, with cargo install ovo-sandbox --features landlock --bin ovo-landlock given as the install command. The README states plainly that cargo add ovo does not install the helper. For the toolkit path, default_toolkit(jail, backend) canonicalizes the jail directory and gives you a sandboxed shell plus workspace_shell(). There is also trusted_toolkit(jail, TrustedExecution), which the README describes as an explicit opt-out of process isolation. That naming is worth pausing on. It is not a stronger sandbox; it is the absence of one, with a type parameter that forces you to say so in code. The failure mode to watch is platform_sandbox() returning Failed, which the README attributes to a missing seatbelt or landlock or an unresolved helper, and which it says can happen for a pure library dependency. There is no NoSandbox fallback, so a Failed result is something your host code has to handle rather than ignore.

Where Ovo is the wrong tool

The README's own stability note is the first disqualifier for some teams. Ovo 0.9.x is pre-stability, and the README states that the GitHub non-prerelease 0.9.1 is not 1.0 and that breaking changes land without compatibility layers. If your integration cannot absorb a constructor signature change between minor versions, this is not the crate to build on yet. The second disqualifier is the sandbox posture. A team that wants an agent runtime with isolation enabled by default will find that Ovo gives them policy types and a trait, then asks them to supply a backend and, on Linux, a helper binary that the crate does not install. The README's repeated emphasis that full is not an OS sandbox suggests this has been a source of confusion. The third is the approval default. TurnOptions::default() is AutoApprove, which is convenient for tests and offline TurnRuntime work and dangerous anywhere else; a host that wires the default by accident has an agent that approves its own destructive actions. The fourth is documentation depth. The README covers constructors, features and the Linux helper contract well, but the journaled Rhai workflow mode, the state and observability pieces bundled into full, and the relationship between the a2a, mcp, x402 and zk-snarks topics on the repository and the crate itself are not explained in the material available. If your evaluation depends on any of those, the README will not settle it.

How this differs from wiring tools into an existing agent framework

The obvious alternative is to take an existing agent framework, most of which are Python or TypeScript, and register filesystem and shell tools against it. The difference in approach is not the tool list. It is where the trust boundary sits. In a typical framework, the sandbox is either absent, or it is a subprocess wrapper you write yourself, and the approval step is a callback the framework invokes. Ovo inverts that by making the approval policy and the sandbox backend constructor arguments. TurnOptions::for_host takes a gate; sandboxed_host takes a backend and a jail. You cannot construct a production host without deciding both. That is a stronger design for anyone who needs the confinement to be a property of the runtime rather than a convention in application code. It is a worse design for anyone who wants to try an agent out in ten minutes, because the ten-minute path is the one the README marks as not production. The second real difference is the language boundary. A Rust kernel embedded in a Rust host means the tool implementations, the policy types and the host application share a type system; a Python framework calling into a Rust binary does not. The cost is that you are writing Rust, and the README's own examples assume you are comfortable with Arc<dyn SandboxBackend> and feature-gated constructors. There is no managed service, no dashboard, and no configuration file mentioned anywhere in the material.

Version churn, upgrade cost and the license terms

The release history in the supplied material shows v0.8.0 and v0.8.1 both tagged on 2026-02-24, then v0.9.1 on 2026-08-21, with the last repository push dated 2026-09-09. That is roughly six months between the 0.8 line and the 0.9 release, and the README's pre-stability warning applies to the 0.9 line specifically. The practical upgrade cost is therefore not the dependency download; it is re-reading the constructor table on each minor bump, because the README states breaking changes arrive without compatibility layers. The constructor table is short enough to diff by eye, which is some consolation. The crate was formerly published as machi, so any older internal documentation or lockfile referencing that name needs updating. On licensing, the README states the project is dual-licensed under Apache-2.0 and MIT, at your option, with the usual contribution clause that submitted contributions are dual-licensed on the same terms unless stated otherwise. The crates.io badge in the README says MIT/Apache-2.0 while the repository metadata supplied here lists Apache-2.0; the LICENSE-APACHE and LICENSE-MIT files in the repository are the authoritative artifacts, and if the discrepancy matters to your legal review, check those files rather than either badge. Nothing here is legal advice.

What to check before you embed it

Start with the feature flags you actually need, because the default set will not give you a toolkit and the full set will not give you an OS sandbox. Decide whether you need toolkit plus landlock or seatbelt, and if you are on Linux, resolve the helper question first: either install it per the README's cargo install command, set OVO_LANDLOCK_HELPER, or place ovo-landlock beside the host binary. Then confirm your approval gate is not Arc::new(AlwaysDeny) left in from the sample and not TurnOptions::default(), which is AutoApprove. Handle a Failed return from platform_sandbox() explicitly, since the README states there is no NoSandbox fallback and a pure library dependency can trigger it. If your evaluation depends on the journaled Rhai workflow mode or on the state and observability pieces bundled into the full feature, read the crate source, because the README does not describe them. The repository topics list a2a, mcp, x402 and zk-snarks alongside agent and workflow, and the supplied material does not connect those topics to specific modules, so treat any assumption about them as unverified until you find the corresponding code.

Editorial conclusion

Adopt Ovo if you are building a Rust host application that needs to own the approval gate, the jail directory and the process isolation backend itself, and you are prepared to pin a 0.9.x version because the README states breaking changes land without compatibility layers. Do not adopt it if you want a turnkey sandbox or an out-of-the-box agent server; the README states platform_sandbox() can return Failed for a pure library dependency and that there is no NoSandbox fallback. Before committing, verify three things: that ovo-landlock is installed or OVO_LANDLOCK_HELPER is set on your Linux targets, that your approval policy is not left at TurnOptions::default() outside tests, and that the 0.9.x crate version you pin is the one whose constructor table matches what you call.

Official sources

  1. Issues
  2. License: Apache-2.0
  3. qntx/ovo on GitHub
  4. README
  5. Releases
Community notes

Community notes