IO Harness
An embeddable agent runtime for Rust. Any task, any provider, in your process — with a permission boundary, a sandbox, and a durable trace you own.
You hand it a contract: the task, the workspace it may touch, and what it may read, write, run and dial. It runs the loop — observe, reason, act, check, stop — and hands back an outcome, with every step, refusal and budget draw in a SQLite trace you can read afterwards. The agent can run the project's own toolchain, so the language the project is written in is not the harness's business.
Quickstart
[]
= "0.17"
= { = "1", = ["rt-multi-thread", "macros"] }
use ;
async
Requires Rust 1.88 or later. The floor comes from rmcp, which publishes no
rust-version of its own, so cargo cannot catch it at resolve time — on 1.87 the
build fails inside that dependency rather than here.
What it does
The loop. A [TaskContract] names the goal, the subject, and — optionally —
the criterion. Workspace mode gives the agent grep, find, read_file,
write_file and edit_file across a repository root. Single-file mode edits one
file.
Commands, under the same boundary as everything else. The agent runs the
project's own build, tests, linter or package manager through an exec tool
taking a fixed argv and never a shell string. Every call is checked against the
policy on the program and on the whole argv, so allow_exec("cargo test*")
beside deny_exec("cargo publish*") means what it reads. A command runs with
your process's privileges and is not sandboxed — that bound is stated in full
in the command execution guide, because it is
the widest thing the crate grants.
Verification in any language, or none. A criterion can be the project's own test command in whatever language it is written, or nothing at all when the task has no checkable criterion — "work out why the deploy fails" is a run, not a gate. What a passing gate does and does not prove is stated exactly in the verification guide; it is narrower than it reads. The harness also ships a table of what each ecosystem's commands conventionally are, so the agent does not spend turns discovering that this is a pnpm workspace — see language support.
A permission boundary. Layered, deny-first rules decide what the agent may read, write, execute, and connect to. Anything marked ask goes to an approver that can approve, deny, or defer past the end of the process and resume on a human decision later. Every refusal and decision is in the trace, attributed to the rule and the layer that produced it.
Budgets and stop conditions. Steps, wall-clock time, and token spend are capped. A tree of agents draws from one shared ledger no spawned contract can raise.
Agent composition. A root run can spawn contained sub-agents over a shared workspace, nested, many at once. A child inherits its parent's policy and can only narrow it — never grant itself what the parent lacks.
An execution sandbox. Model-produced code runs in an ephemeral sandbox with an isolated workdir, resource caps that kill rather than throttle, and network denied by default. Native backends on macOS and Linux over a portable floor that runs everywhere.
Durable, unattended runs. After every completed step the trace, the budget draw, and a checkpoint commit in one transaction. A crash resumes the whole tree where it stopped: completed steps are not re-run, the budget is not double-charged, and an irreversible action already taken is not taken twice.
Providers, with fallback. OpenRouter, Anthropic, and OpenAI behind one trait, over the crate's own HTTP+SSE client. A provider that is down or rate-limited falls back to the next configured one; failures are classified so a caller can tell a retryable transport error from a terminal one.
Extensibility, in-process and out. Implement the Tool trait for something
your program already does, or point the harness at MCP servers over stdio or
streamable HTTP. Skills are markdown instruction files that shape how the agent
approaches a class of task, with no Rust at all.
Context that stays relevant. Each turn is assembled to fit a stated share of the token budget: superseded observations are compacted, and an observation a later write invalidated is re-read rather than trusted. Durable memory keyed to the workspace survives between runs.
Observation and replay. Register an observer and be called as the run happens — steps, tool calls, approvals, refusals, spend draws, retries, fallbacks, outcomes — instead of polling the store. A recorded provider replays a case so it runs identically twice.
Documents and images, behind opt-in features: spreadsheets, Word, PowerPoint text, PDF, and barcode decoding, each gated on the real path the model named; and image passthrough to any provider whose model accepts one.
Git, as fixed-argv built-ins: status, diff, log, add, and commit, so a run ends as a reviewable commit rather than a working tree someone has to reconstruct. The model supplies paths and a message, never a subcommand or a flag, so push, fetch, reset and rebase are unreachable by construction.
Guides
| Guide | What it covers |
|---|---|
| Permissions and approval | Layered rules, what asks and what is refused, deferring past process exit |
| Command execution | Running a project's own toolchain, checked on the whole argv — and the bound that is not there |
| Language support | Toolchain detection, a criterion in any language, migrating off the Rust-specific gates |
| Verification | The criteria, execution-based gates, and exactly what a pass proves |
| Agent composition | Sub-agents, inherit-and-narrow containment, the shared ledger |
| Execution sandbox | Backends per platform, resource caps, the portable floor |
| Durable runs | Checkpoints, resume, approvals that survive a restart |
| MCP and network egress | Stdio and HTTP servers, Act::Net, what the policy does not govern |
| Tools and skills | The Tool trait, the toolbox, skill discovery and its boundary |
| Context and memory | Per-turn assembly, compaction, invalidation, durable memory |
| Resilience | Failure classification, retry, provider fallback, stall detection |
| Observability and replay | Observers, events, outcome records, deterministic replay |
| Documents | Spreadsheets, Word, PowerPoint, PDF, barcodes — and what was cut |
| Images and git | Image passthrough and the fixed-argv git built-ins |
docs/CAPABILITIES.md indexes them. docs/CONTRACT.md is the public contract: what is stable, what may change, and the limits that hold today.
Feature flags
Everything below is off by default. The default build compiles no optional dependency at all.
| Feature | What it adds |
|---|---|
media |
Image passthrough to providers that accept images |
documents |
Umbrella over the five below |
xlsx |
Spreadsheet read, generate, and preserving single-cell edit |
docx |
Word read and generate (no in-place edit, deliberately) |
pptx |
PowerPoint text extraction (read-only, no writer) |
pdf |
PDF generate, extract text, watermark, fill AcroForm fields |
barcode |
Barcode and QR decoding from an image |
Platform support
| Platform | Sandbox containment |
|---|---|
| macOS | Native, sandbox-exec |
| Linux | Native, namespaces and rlimits |
| Windows | Portable floor only — the Job Object backend is designed, not implemented, and only the wall clock is enforced |
The full suite runs on all three in CI.
Stability
The crate is pre-1.0 and stays pre-1.0 until its owner says otherwise. A minor release may break the public contract — SemVer permits it below 1.0, and this project uses it. What you can rely on is not that a break will not happen, but that when it does it is marked in CHANGELOG.md with a migration note saying what to write instead, and that a renamed or removed item goes through a deprecation cycle rather than vanishing between two releases.
docs/CONTRACT.md states the whole of it.
Part of initorigin
IO Harness is one of the initorigin products:
| Product | What it is | Status |
|---|---|---|
| io-harness | The Rust agent harness (the center product) | Released |
| io-cli | Terminal app on io-harness | In development |
| io-studio | Desktop coding studio on io-harness | In development |
io-harness is the only public repository today, which is why it is the only one linked. io-cli and io-studio open when they release.
Contributing
Read CONTRIBUTING.md. Work branches from develop, lands via
PR, and every user-facing change updates CHANGELOG.md. Releases
follow docs/RELEASE_PROCESS.md.
Security
Report vulnerabilities per SECURITY.md.
License
Apache-2.0. Copyright 2026 Aakash Pawar (InitOrigin). See LICENSE and NOTICE.