PlatformDecision Contract
Kernel
The Kernel
The Kernel is Chio's trusted core: where an agent's intent becomes a governed, receipted action, or a signed denial.
Where to start
Mental Model
An agent issues a tool call. The kernel intercepts that call, walks a verified capability through a pipeline of guards, and produces a verdict. If every guard agrees, the kernel forwards the call to the tool server. The tool runs and returns a response. The kernel writes a signed receipt. Nothing reaches the tool unless the pipeline allowed it; nothing reaches the agent without a receipt.
crates/kernel/chio-kernel/src/kernel/dispatch.rs:384-435crates/kernel/chio-kernel/src/kernel/responses/finalization.rs:19-107crates/kernel/chio-kernel/src/kernel/responses/allow_responses.rs:58-112at fe56570Three properties hold for every call through the kernel:
- Synchronous evaluation. The guard pipeline runs to completion before the tool is invoked. There is no probabilistic admission and no asynchronous deferral on the critical path.
- Fail-closed. Any guard that returns
Verdict::Denyor anErrstops the call. See Fail-Closed Semantics. - Receipts always. Allowed calls, denied calls, and human-pending calls all produce a signed receipt. The receipt is the audit boundary.
Glossary
These terms recur throughout the Kernel docs. The definitions here are the ones the source code uses.
| Term | Meaning |
|---|---|
Guard | A type that implements the sync Guard trait. One name() and one evaluate() method. evaluate() returns Ok(GuardDecision), a Verdict plus the evidence the guard recorded, or an Err the kernel treats as a deny. |
Pipeline | An ordered collection of guards, itself wrapped as a single Guard. Evaluates in registration order. Three flavors: GuardPipeline, AdvisoryPipeline, PostInvocationPipeline. |
Verdict | The three-valued outcome of guard evaluation: Allow, Deny, or PendingApproval. Copy + Clone, no payload. The full kernel can also produce PendingApproval; the portable core never does. |
Evidence | Structured findings a guard records on the receipt. Examples: redaction summaries from the sanitizer, provider decision identifiers from external guards, advisory signals. |
Capability | A signed token that names what an agent can invoke. The kernel verifies the signature, expiry, and subject binding before guards run. See Capabilities. |
Receipt | The signed record of one evaluation. Carries the verdict, the guard evidence, advisory signals, and the policy hash used. See Receipts. |
Advisory | A non-blocking signal. Recorded as evidence, never a denial, unless promoted by a PromotionPolicy. |
The Platform Scale Ladder
Platform has six sections. The first four are a ladder of scale: one call, one process, one authority's fleet, then authority that descends past the operator. Each rung adds exactly one thing the rung below cannot express. The last two are not scale. Federation & Compliance is the standing relationship between authorities and the outside regimes it is mapped to; Formal Assurance is what is proved rather than what runs.
Two questions come before the six. Is the subject priced, settled, or metered? Then it is Economy and off the ladder. Is it one vendor's recipe for one runtime? Then it is Build. Platform documents the obligation; another area can own the crate and the walkthrough.
A Platform page then files at exactly one of the six. The filing tests below are the first cut: read the test for the section you think a page belongs to, and if it does not fire, climb. Three rules override a test that fires, and each is worked under the table. Lowest rung wins when two fire. A guard implementing the Guard trait is Kernel whatever state it reads, so rate limit files at Kernel even though its token buckets are per process. Emission semantics file at Node even though the receipt that records the same call is Kernel.
| Section | What it governs | Filing test |
|---|---|---|
| Kernel (here) | One function decides one governed action and signs the receipt that attests it. | Does this change if you run two of them? If no, it is Kernel. |
| Node | The kernel decides whether an action is permitted; the node decides whether this process is still fit to decide. | Can one process answer this by reading its own disk? Then Node. |
| Cluster | Many nodes, one key. State no single process can hold, and the published ceiling on how consistent it gets. | Does answering it require another node's disk under the same key? Then Cluster. |
| Swarm | Authority descends by signature to actors you do not run, and every hop must prove it narrowed. | Is the actor's authority derived from another party's rather than issued to it, or does the action require signatures from parties under different keys? Either clause fires. |
| Federation & Compliance | The standing relationship between two authorities, and the external regimes it is mapped to. | Does answering it require a party whose keys you do not control, or an external framework you must map to? |
| Formal Assurance | What is proved about the kernel, and what is assumed instead. | Is the subject a theorem, a harness, an assumption, or a verification gate? |
Two clauses do most of the work. Cluster and Federation both involve more than one node; under the same key is what separates them, because a cluster shares one authority keypair, one admin service token, one shared-secret peer credential, one trust domain, and a federation shares none of those. And a Chio node hosts a kernel: a deployed process that hosts no kernel is not a node, however much it looks like infrastructure.
The Kernel-to-Node boundary is already written down in the code. crates/kernel/chio-kernel-core/src/evaluate.rs names what pure evaluation excludes: revocation lookup, budget mutation, delegation-chain joins against the receipt store, DPoP nonce replay, payment authorization, tool dispatch, and receipt persistence. What that list moves off Kernel is the implementation, not the contract. Receipt persistence is a Node subject; the receipt format, the canonical JSON it hashes, and the signing backend are Kernel, and Receipts & Audit carries them on one page, contract first and the SQLite store last. Where each implementation lands is then the per-subject test's job rather than this list's. Most file at Node. Governed-transaction evaluation climbs to Swarm with chio-governance, whose escalation ladder can require a co-signature under a key the operator does not hold. Budget mutation leaves the ladder for Economy, which owns pricing, credit, metering, and settlement.
Lowest rung wins
When two tests fire, the page files at the lowest rung where its subject is fully determined. Secrets & Signing Keys is the worked case. A cluster shares one authority keypair, so key custody reads like Cluster. But the question a reader actually arrives with, where this process loads its signing key from and how that key is protected at rest, is answered by one process reading its own disk. It files at Node. Only the part that no single process can answer, which verifier bundle and revocation checkpoint the fleet agrees on, climbs to Cluster.
The guard corollary
A guard that implements the kernel Guard trait is Kernel content even when its verdict depends on state a node holds. The guard is Kernel, the store it reads is Node, and both pages open by naming the other. That settles rate limit, session-aware, memory, and approval: all four file at Kernel while the journal, the counters, and the pending-approval record are node concerns. The standing evidence is spec/GUARDS.md section 9, where the guard logic ships in chio-guards and the SessionJournal ships in chio-http-session and is operator-wired.
The corollary reaches state a node holds. It does not reach a call to another party's service. External Guard Adapters files at Node because its subject is the out-of-process call and the per-process cache, retry budget, and circuit breaker wrapped around it. Two nodes do not share a breaker, so the Kernel test fails on the first clause.
Emission semantics are documented at Node
The tracing macros, the guard join key, and the guard metric names are documented at Node Observability. There is no Kernel observability page, by design. One call's evidence is its receipt, which is Kernel. What a process emits about itself while it runs is Node, and two nodes emit two streams.
The href prefix carries no rung
The URL prefix says nothing about which section a page files under. This page is /docs/guard-platform/overview and files at Kernel; chio.yaml Configuration is /docs/guard-platform/config and files at Node. /docs/deployment/ pages file at Node, at Cluster, and in Build under Cloud Platforms. Authors file by the filing test, never by the URL.
The same six tests applied to source directories, plus seven placements the directory path gets wrong, are on Crate Map.
Guard Categories
Every guard falls into one of five categories, distinguished by the state it reads and the phase it runs in. This is the vocabulary the rest of the Kernel docs use. The protection-area tour below groups the same catalog differently.
| Category | State | Phase | Blocking |
|---|---|---|---|
| Stateless deterministic | None | Pre-invocation | Yes |
| Session-aware deterministic | Session journal | Pre-invocation | Yes |
| Post-invocation hooks | Tool response | Post-invocation | Yes |
| Advisory signals | Session journal (optional) | Pre-invocation | No, unless promoted |
| WASM custom guards | Sandboxed runtime | Pre-invocation | Configurable |
Capability Tour
The table groups guards by the area they protect. State read is what the guard consults beyond the request, finer-grained than the State column above. Rung is where the page files on the ladder. Every row but one is Kernel, because a guard implementing the Guard trait is Kernel content whatever state it reads.
| Surface | What it protects | State read | Rung | Page |
|---|---|---|---|---|
| Filesystem | Path allowlists, forbidden patterns, normalization, session-scoped roots. | None. Session roots arrive on the context. | Kernel | Filesystem |
| Network | Egress allowlists, internal-network checks, URL validation. | None. | Kernel | Network |
| Shell & Code | Forbidden shell patterns, code-execution gates, patch integrity. | None. | Kernel | Shell & Code |
| Rate & Velocity | Per-window invocation and spend caps: per-grant and cross-capability token buckets. | In-process token buckets. | Kernel | Rate Limit |
| Session-aware | Guards that read the session journal: data flow and behavioral sequence. | Session journal. | Kernel | Session-aware Guards |
| Jailbreak & Prompt Injection | Pattern and ML detection of jailbreak prompts and indirect injection. | None. The detector scores request text. | Kernel | Jailbreak Detection |
| Sanitization | Output sanitizer hook redacting secrets, PII, high-entropy tokens. | Tool response. | Kernel | Sanitization |
| Computer Use (CUA) | Browser automation, remote desktop, computer-use mediation. | In-process screenshot bucket. | Kernel | Computer Use |
| Approval (HITL) | Human-in-the-loop checkpoints producing PendingApproval. | The pending-approval record the node holds. | Kernel | Approval |
| Memory Governance | Reads and writes to agent memory stores. | Grant constraints, plus an in-process per-session write counter. | Kernel | Memory |
| Data Layer | DB query review, structured-data redaction. | Query text and result rows. | Kernel | Data Layer |
| External Adapters | Cloud guardrails (Bedrock, Azure, Vertex) and threat-intel (Safe Browsing, VirusTotal, Snyk). | A remote provider, behind a per-process cache, retry budget, and circuit breaker. | Node | External Adapters |
| Advisory | Non-blocking signals with severity, optional promotion to denial. | Session journal, optional. | Kernel | Advisory Signals |
| WASM Custom | Custom guards loaded as sandboxed WASM modules. | Sandboxed runtime. | Kernel | WASM Guards |
The three guard groups in the sidebar, System Access, Session & Approval, and Content & Data, are a coarsening of this tour for navigation, not a fourth taxonomy.
How Policy Fits In
A guard implementation performs enforcement. A policy supplies its configuration. Operators write a HushSpec YAML file, the policy compiler converts it into a configured pipeline, and the kernel runs that pipeline against every request. The same guard binary serves every deployment; the policy file is what differs.
- HushSpec authoring lives in HushSpec and Write a Policy.
- Runtime configuration knobs (caches, breakers, rate limits) live in Configuration.
Trust Boundary
The kernel is the trusted component and the agent is untrusted. The tool server is neither. The threat model draws one boundary, the agent-kernel-tool trust boundary, and counts tool_execution_confinement among the 7 assets that boundary protects, so a tool server is an effect surface the kernel confines rather than a party the kernel relies on. The confinement itself is registered as an assumption, ASSUME-SUBPROCESS-ISOLATION: Tool-server subprocess isolation and OS process boundaries are assumed for effects outside the pure kernel decision core.
A native guard runs inside the kernel process, so the agent cannot reach its evaluation. A WASM guard runs in that same process, but the code it runs is the guest's, and Wasmtime is what holds the guest inside its sandbox. That containment is registered as ASSUME-WASM-ENGINE: Wasmtime is assumed to enforce its documented i32 return, trap, fuel-metering, memory-limiter, and in-process sandbox semantics for untrusted guest code. A WASM guard therefore inherits the engine's confinement, not the process trust a native guard has.
The receipt signature binds the verdict to the kernel's signing key, which is verifiable offline.
Errors are denials
Err from evaluate is treated as if it returned Deny. This is the fail-closed invariant. When in doubt, the pipeline blocks.Where to Go Next
- Crate Map · which rung owns which crate, and where the directory path lies
- The Guard Trait · the contract every guard implements
- Pipelines & Composition · how guards combine into a pipeline
- Fail-Closed Semantics · what happens when something goes wrong
- Default Pipeline · what runs out of the box
- In-Process Library · the first page of Node, the next rung up