Architecture
Build agentic operating systems on a shared kernel for delegated authority, durable work, and cooperation across independent operators.
On this page
Chio is a Rust kernel for agentic operating systems: systems in which agents organize work, use shared resources, and cooperate under rules their operators control. The architecture places authority and execution beneath the agents. Applications can change their models and orchestration while the kernel continues to enforce the rules for each governed operation.
That separation supports systems that grow beyond a single agent loop. A research application can delegate investigations to specialists. An engineering system can carry a candidate through implementation and review. Independently operated systems can exchange work through explicit trust and signed evidence, with each operator retaining control of its resources.
The kernel checks authority and retains its decisions. A configured runtime and process host give work an identity and recovery path that survive an individual worker. Applications own their goals and coordination; hosts supply storage, credentials, and isolation. These responsibilities let you build an operating environment whose rules and retained work outlast any one model or run.
The kernel connects callers to governed resources
The kernel has three human roles: operator, approver, and verifier. An operator configures it before any call arrives: the policy, the trusted issuer keys, the signing keys, and the stores for receipts, revocations, budgets, and approvals. An approver signs a decision for a held call that needs one. A verifier checks exported receipts and checkpoints against signer keys it selects itself, with no access to the running kernel.
The systems around it each exchange one kind of thing. An agent reaches tools only through the kernel, over MCP, A2A, a provider’s tool-call API, or HTTP, and presents the capability token that authorizes each call. A capability issuer signs those tokens, and the kernel accepts a token only from an issuer the operator configured as trusted. Tool servers receive admitted operations and nothing else. A payment rail settles charges for governed transactions, and a peer operator’s kernel exchanges treaty-scoped authority and evidence.
The kernel admits, dispatches, and signs
The kernel checks the presented capability, policy, approval, and budget requirements before admitting a call. It dispatches admitted calls through an execution adapter and signs a receipt for each decision. The mediated call.
The system has several architectural views, each showing a different responsibility:
| Level | What it draws | Where |
|---|---|---|
| System context | The kernel and the people and systems around it | This section |
| Containers | The processes and stores of one deployment | Connect an application |
| Kernel components | The phases of one call and the decision core inside them | Below, inside the kernel |
| Deployments | Which process holds the kernel, its key, and its stores | Below, deployment shapes |
| Ports and adapters | The kernel’s traits and the crates that implement them | Portable kernel |
| Crate layers | The workspace’s crates and the direction of their dependencies | Portable kernel |
| Control and data planes | Where shared revocation, budget, and receipt state is served | The state a verdict depends on |
| Storage | The retained state as tables | What survives a crash |
The application assigns work; the kernel admits calls
The review of pull request #421 makes that separation concrete. The reviewer from Capabilities can read and search /workspace. It delegates a smaller grant to the tester: read the tests the assignment needs. The tester can produce findings without gaining the reviewer’s entire authority.
read_file · searchread_fileParent delegates read authority to child.
repository/- Application
- Combines the worker’s findings into a review.
- Kernel store
- Retains signed decision records.
- Process host
- Retains identity, checkpoints, and named calls.
The application owns the meaning of the work. It selects a model, prepares the review instructions, divides the assignment, and decides whether the findings are useful. Chio does not need to understand what makes a good code review to enforce the tester’s read authority.
The kernel owns the admission decision on the configured execution path. Both agents reach the same workspace server, but each request is evaluated under its own authority. A shared implementation does not imply a shared permission. The tester’s knowledge of write_file would not grant the right to invoke it.
The adapter gives an admitted operation its concrete behavior: open a file, contact a service, or invoke a connected tool. Protocols sit at this edge. An MCP connection can expose an adapter; an application can also embed the Rust kernel or use a service interface. The authority model is the architectural center those integrations share.
Follow one read all the way to its effect
Suppose the review worker wants tests.rs. Its request names an operation and supplies arguments. The host binds the worker’s connection to its process identity and persisted capability. The kernel evaluates that authority and the configured admission requirements before the repository adapter receives the operation.
read_file(
"tests.rs"
)The grant covers read_file.
- 01Identify the caller✓
Bind this request to the subject.
- 02Check its authority✓
The read falls within its grant.
- 03Resolve admission✓
Apply the configured policy and limits.
- 04Invoke the adapter→
Read the file and return its contents.
Change the request to write_file. The worker is still the same worker and the repository still exists. What changes is whether its grant covers the requested operation. The refusal occurs before dispatch, so this path never asks the adapter to modify the repository.
A request within scope must still pass admission. Policy, approvals, and configured budgets may still prevent admission. After dispatch, execution itself may fail. These are distinct outcomes: an authority refusal, an admission requirement, and an attempted operation that did not complete call for different application behavior.
A name for the operation
The process client gives the read a stable logical-call key. The host supplies connection; the example assumes a configured repo/read_file adapter.
Check both the admission verdict and completion state before interpreting the adapter’s result.
from chio_process import ProcessClient
client = ProcessClient(
connection["socket_path"],
connection["credential"],
)
result = client.invoke(
"read-tests-42", "repo", "read_file",
{"path": "tests.rs"},
)
if result["verdict"] != "allow":
raise RuntimeError("Read was not admitted")
if result["terminal_state"]["state"] != "completed":
raise RuntimeError("Resolve read-tests-42 before continuing")The logical-call key identifies this piece of work across attempts. It is not permission and it is not a receipt identifier. Reusing it with the same operation lets the process host resolve retained work; changing its arguments conflicts with that existing call. A new identifier would describe new work, which is the wrong response to uncertainty about the old work.
The mediated call explains admission in detail. Calls and recovery describes the process contract for named operations and uncertain outcomes.
Work retains its identity when a worker stops
An application can assign ongoing responsibility to an actor whose identity outlives any one worker run. A review worker may read the tests, record progress, and exit before returning its findings. Its replacement needs the original authority and the records of unfinished work.
An agent process is the durable actor in the configured process host. The OS worker is the program currently executing for that actor. A replacement worker can resume the same process identity, checkpoint, and named calls. It does not need to become a new actor to continue the assignment.
The host retains these records outside the executing worker, under the configured durability contract.
Three kinds of state answer three different questions. The capability establishes the actor’s authority. The checkpoint records the application’s progress. The logical call records the identity and known state of an operation. Keeping them distinct prevents a restarted worker from treating an unfinished effect as permission to start it again.
For a read, resolving a retained result may be straightforward. For an external write, an interruption can leave the outcome uncertain. A checkpoint saying “about to publish” cannot establish whether publication happened. The replacement must follow the call’s recovery contract, including reconciliation when required.
This continuity belongs to a correctly configured durable runtime. It is not a property of an arbitrary loop that sends requests to Chio. The first-process walkthrough runs real workers through a retained handoff and an interruption; checkpoints and state explains where application progress belongs.
The host makes the authority boundary effective
The kernel can refuse the worker’s write request. That refusal protects the repository only if the worker cannot reach it through another path. A writable mount or an inherited unrestricted credential would give the worker a second source of authority, regardless of how narrow its Chio grant was.
The host therefore controls the execution environment: which processes run, which credentials and handles they receive, and which adapters can access protected resources. It also supplies trusted issuers, policy, keys, and stores. These choices determine the boundary within which the kernel’s decision has force.
Repository ← adapter ← admitted operation ← worker’s grant
Then account for every other route the worker could use to reach that repository.
Workers sharing a mission need a consistent view of its revocations, approvals, spending, and retained work. That view depends on the stores used by the deployment. Two workers using Chio do not automatically share a revocation view. Durable storage, restore behavior, and state freshness must match the application’s operating assumptions.
Separate the decision core from the runtime around it
Inside this architecture is a smaller boundary. Chio’s portable decision core is a no_std + alloc Rust library. It evaluates supplied authority and context with explicit clock and entropy interfaces. The native runtime surrounds that core with the live state and I/O needed to admit and execute operations.
The runtime follows four phases in evaluate_tool_call. Authorize verifies the capability, checks the token and each delegation link for revocation, and matches the request to a grant. Admit opens a durable record and checks approval, guards, and budget before charging. Execute sends the admitted call to its tool server and inspects the result. Record signs the outcome, including refusals, and commits receipts to checkpoints.
Every governed call takes the same four phases
An edge or host (MCP, HTTP, or an SDK) hands the kernel a tool call request: the operation, its arguments, the caller’s agent id, and the capability token that authorizes it. The native runtime takes the call through four phases in order and calls the decision core three times: to verify the capability, to admit a delegated child’s budget share, and to sign the receipt. Architecture.
- 1native evaluation
kernel::evaluationevaluate_tool_callis the authoritative path. It runs each step in order and answers every outcome, a refusal included, with a signed receipt.
evaluate.rs:13//! What it does NOT do (fenced into `chio-kernel` proper):
//!
//! - Revocation membership lookup (stateful `RevocationStore`).
//! - Budget mutation (stateful `BudgetStore`).
//! - Delegation-chain ancestor inspection against the receipt store.
//! - DPoP proof verification with nonce replay (LRU-backed).
//! - Governed-transaction policy evaluation (pulls in chio-governance).
//! - Payment authorisation (async adapter trait).
//! - Tool dispatch to wrapped servers (async transport).
//! - Receipt persistence / Merkle checkpointing (SQL / IO).
evaluate_tool_call runs its steps, with the stores and tool servers it reaches outside the process. Execution nonces, purchase gates, payment, and trace observers are left out or folded into the phase they belong to.Portable kernelThe runtime calls the decision core three times: to verify the capability, to admit a delegated child’s share of its parent’s budget, and to sign the receipt. Everything that touches a store, a tool, or the network stays outside the core: the revocation, admission, approval, and budget stores, the tool servers, and the receipt store. Around both, the process host binds workers to durable actors and manages checkpoints, named calls, and replacement attempts.
This separation makes the decision logic portable and gives formal claims a defined subject. A proof about a core function does not establish that a database retained every receipt or that an external write completed. Those claims need evidence from the runtime and deployment that performed the work.
See the portable kernel for the host interfaces and verified core boundary for the proof manifest and its supported claims.
Choose where the application meets the kernel
The integration shape follows the trust boundary. Embedding brings the kernel into a host you control. A service puts an authenticated interface between the caller and the runtime. A bridge admits operations for a connected tool server. Each still needs explicit authority, configured state, and a host that protects the admitted path.
What changes between the shapes is which process holds the kernel, its signing key, and its stores, and so where the trust boundary lies. Embedded, it is the whole host process, and host code must be trusted. As a shared service, it is the sidecar container: the signing seed is mounted only there, and the application container holds no key. As a bridge, it is the chio process; the MCP server it launches as a child over stdio is not an operating-system sandbox. In every shape, a route around the outlined process is outside both the control and the record.
The process that holds the kernel is the trust boundary
In each shape, the process that holds the kernel also holds the signing key and the stores and runs admission. Its dashed outline marks the trust boundary, and its extent is what changes from shape to shape. Architecture.
- admitted route
- The caller reaches the resource through the kernel and adapter. The host closes any other route, including credentials or handles that bypass admission.
- signing key
- Anything that can read the process holding the seed can sign receipts that verify.
- stores
- Two kernels share a revocation view only through a shared store or the trust control plane.
- trust boundary
- Routes around the outlined process are outside both the control and the record.
In Rust · types.rs:11811 lines
/// Optional SQLite database path for durable receipt persistence.
#[arg(long, global = true)]
pub(crate) receipt_db: Option<PathBuf>,
// …
/// Optional file path for a persistent capability-authority seed.
#[arg(long, global = true)]
pub(crate) authority_seed_file: Option<PathBuf>,
// …
/// Optional SQLite database path for durable admission, trust authority, and remote MCP session state.
#[arg(long, global = true)]
pub(crate) session_db: Option<PathBuf>,
Each shape has its guide. In-process integration owns the kernel’s lifecycle and stores inside your application, which shares memory and key custody with it. HTTP service deployment serves remote callers through an authenticated interface and configures the listener, the tenant boundary, and durable state. MCP bridge integration puts an existing MCP server behind admission, where its served operations define the scope of the integration.
An application can use these boundaries to add specialists, retain work across worker changes, or connect to another operator. Its models and workflow remain application choices. The kernel supplies the authority contract, and the configured process host supplies continuity for the work.