Chio/Docs

Formal Assurance Overview

Chio takes a layered approach to assurance. A small pure decision core is proven by hand in Lean 4, refined against Aeneas-extracted Rust, and bounded-model-checked with Kani. A TLA+ specification covers the cross-process revocation propagation protocol that the Lean model cannot reach. Everything outside that proof boundary is held to softer bars: differential property tests, libFuzzer coverage-guided harnesses, dudect timing analysis, and ordinary unit and integration tests. This page is the honest map of which guarantees are which.

Read the manifests, not the marketing

Every claim on this page is grounded in a file you can read: formal/proof-manifest.toml, formal/theorem-inventory.json, formal/assumptions.toml, and formal/MAPPING.md. If the docs and the manifests disagree, the manifests are the source of truth.

Reading Paths by Role

The formal-assurance section is sized for four readers. Pick the path that matches your role; each path is a 30-second scan of which pages to open and what each one gives you.

I operate the kernel in production (SRE / platform)

  1. Quickstart · run every gate locally and see green.
  2. Failure Modes · what each gate failure looks like in CI output.
  3. Assumptions and TCB · what is trusted vs verified, and what to do if an assumption breaks in production.
  4. Constant-Time Tests · timing-leak detection on the verdict hot path.

I'm auditing or certifying chio (security auditor / compliance)

  1. Theorem Inventory · the per-theorem catalog: ID, statement, tool, file, status.
  2. P1 Tour · a worked example tracing capability attenuation through every layer.
  3. Assumptions and TCB · the explicit trust boundary and the ten audited assumptions the proofs are conditioned on.
  4. Differential Tests · production-vs-spec equivalence on scope subsumption, canonical JSON, anchored roots, receipts.

I'm an academic or formal-methods researcher (Lean / TLA+)

  1. Lean 4 Proofs · the canonical theorem statements and the project layout.
  2. Aeneas Pipeline · the Rust-to-Lean extraction pipeline (a Lean-targeted adaptation of Aeneas, paired with explicit equivalence theorems).
  3. TLA+ Specs · the temporal-logic spec for cross-authority revocation propagation.
  4. Theorem Inventory · the catalog you cite when comparing to your own work.

I'm contributing a proof or harness (chio contributor)

  1. P1 Tour · how a property flows through Lean, Aeneas, Kani, and the differential lane.
  2. Lean 4 Proofs · Lean conventions, naming, and the proof-file layout.
  3. Kani Harnesses · how to write a new bounded-model-checking harness.
  4. Fuzz Infrastructure · adding a new libFuzzer target, owners table, and corpus.
  5. Failure Modes · debugging a gate that fails on your PR.

The Assurance Pyramid

Chio's assurance is layered. The narrowest, strongest layer at the top is hand-written formal proof; the broadest, weakest layer at the bottom is manual review. Each layer is honest about what it can and cannot say.

chio assurance pyramidFormal proofs: machine-checked theorems for the chio core; smallest surface, strongest guaranteeFormal proofsLean 4 · Aeneas + F*Symbolic execution and model checking: bounded-depth verification of decision logic and protocol invariantsSymbolic executionKani · TLA+Differential tests: cross-check the runtime against an executable spec or reference oracleDifferential testsCoq-style oraclesProperty tests and fuzzing: randomized inputs against invariants; coverage-guided campaignsProperty tests + fuzzlibFuzzer · ClusterFuzzLiteIntegration tests: end-to-end flows across kernel, guards, tool servers, and signing keysIntegration testse2e · multi-processManual review: human eyes on diffs, threat-model walks, and external auditsManual reviewcode review · auditsmachine-checked theoremsbounded state-space searchruntime vs spec / oracle parityrandomized inputs vs invariantscross-component flowsintent and threat-model gapsnarrower surface,higher assurancebroader surface,lower assurancehigher layers verify less code more deeply; lower layers verify more code more shallowly
chio's layered assurance approach. Higher layers cover narrower surfaces with stronger guarantees; lower layers cover broader surfaces with weaker but cheaper guarantees.
LayerToolSurfaceStrength
Mechanized proofLean 4Bounded models of the capability algebra, revocation, evaluation, receipts, protocolStrongest. Sorry-free, root-imported, machine-checked.
Refinement extractionAeneas (via Charon)Pure numeric and boolean helpers in formal_aeneas.rsStrong. Lean equivalence theorems link extracted models to handwritten ones.
Bounded model checkingKani (CBMC backend)Public Rust entrypoints: verify_capability, evaluate, sign_receipt, NormalizedScope::is_subset_of, resolve_matching_grantsStrong within bounds. Symbolic execution exhausts inputs up to a configured size.
Refinement contractsCreusotSame five public symbols plus the formal_core helpersStrong. SMT-discharged contracts on the production Rust.
Temporal model checkingTLA+ (TLC and Apalache)Cross-authority revocation propagationStrong within bounds. Three named safety invariants plus one liveness property.
Differential property testsproptest in chio-formal-diff-testsReference spec vs production for scope subsumption, anchored roots, receipt encoding, canonical JSONMedium. Catches drift between two implementations of the same surface.
Coverage-guided fuzzlibFuzzer plus ClusterFuzzLiteAll trust-boundary parsers, decoders, and verifiersMedium. Random and mutation-driven inputs over many CPU-hours.
Timing analysisdudectSignature byte-equality, scope subset checksLimited. Statistical detection of data-dependent timing, not a proof.
Integration testscargo testEnd-to-end protocol behaviorLower. Sanity, not exhaustive.
Manual reviewHumansEverything outside the proof boundaryLowest. Necessary but fallible.

The general rule: the higher up the table a guarantee lives, the narrower the surface it covers. Mechanized proof reaches the smallest fraction of the codebase but says the strongest things. The bottom layers reach far more code but with weaker guarantees.


The Tools Chio Uses

  • Lean 4 · Proof assistant for the capability algebra, revocation snapshots, evaluation totality, receipt coupling, and protocol-level closure theorems. Source under formal/lean4/Chio/. See Lean 4 Proofs.
  • Aeneas · Extracts a functional model from Rust source for proving in Lean (the original Aeneas pipeline targets F*; chio extracts to Lean instead, paired with explicit equivalence theorems). Two lanes: a pilot at formal/aeneas/verified_core.rs and the production extraction from crates/chio-kernel-core/src/formal_aeneas.rs. See Aeneas Pipeline.
  • Kani · Bounded model checker for Rust via CBMC. Symbolically executes proof harnesses on every PR. Public harnesses are at crates/chio-kernel-core/src/kani_public_harnesses.rs. See Kani Harnesses.
  • Creusot · SMT-backed refinement-type prover that pins contracts to production Rust symbols. Configured in formal/rust-verification/creusot-contracts.toml.
  • TLA+ · Temporal-logic spec language. The model checker TLC and the bounded type checker Apalache run formal/tla/RevocationPropagation.tla on the PR lane and the nightly liveness lane respectively. See TLA+ Specs.
  • proptest · Property-based generator for differential tests in formal/diff-tests/. See Differential Tests.
  • dudect · Statistical detector for data-dependent timing in tight inner loops. Lives in crates/chio-kernel-core/tests/dudect/. See Constant-Time Tests.
  • libFuzzer + ClusterFuzzLite · Coverage-guided fuzzing across every trust-boundary parser. Targets are in fuzz/fuzz_targets/ with corpora at fuzz/corpus/. See Fuzz Infrastructure.

What Is Formally Verified Today

The proof manifest declares ten required property identifiers, P1 through P10. Each is mapped to a list of Lean theorems plus, in most cases, a Kani harness, an Aeneas equivalence proof, or a Creusot contract.

IDPropertyLanes
P1Capability attenuation: a child capability is a subset of its parentLean root, differential test, Rust projection, Aeneas equivalence, public Kani
P2Presented revocation coverage: revoked tokens and revoked ancestors denyLean root, audited storage assumption, SQLite projection, Aeneas equivalence
P3Fail-closed evaluation: deny dominates, allow requires every check to passLean root, Rust core, audited subprocess assumption, public Kani, adapter no-bypass
P4Receipt integrity: sign-then-verify, immutability, field couplingLean root, symbolic crypto, audited crypto assumption, receipt totality, Aeneas equivalence
P5Presented delegation-chain semantic validityLean root, SQLite projection
P6Local parent-link soundness within an authenticated sessionLean root, audited storage assumption
P7Receipt-lineage soundness across two signed receiptsLean root, symbolic crypto, audited crypto assumption
P8Session continuity: anchor and continuation evidence requiredLean root, audited transport assumption, DPoP binding tests
P9Delegation and provenance consistency in call-chain referencesLean root, audited registry assumption
P10Report truthfulness: asserted and observed lineage cannot be relabeled as verifiedLean root, claim gate

For the full per-theorem table, see the Theorem Inventory.


The Proof Boundary

The manifest names the boundary explicitly: implementation_linked_protocol_core. The verification target is security_critical_protocol_semantics. That phrase is doing a lot of work; here is what it means.

The boundary covers the pure security decision surface inside chio-kernel-core plus bounded models of adjacent state transitions (revocation snapshots, budget commits, DPoP nonce admission, guard pipeline composition, receipt coupling). The covered Rust modules listed in the manifest are:

formal/proof-manifest.toml
covered_rust_modules = [
  "crates/chio-kernel-core/src/capability_verify.rs",
  "crates/chio-kernel-core/src/scope.rs",
  "crates/chio-kernel-core/src/evaluate.rs",
  "crates/chio-kernel-core/src/formal_aeneas.rs",
  "crates/chio-kernel-core/src/formal_core.rs",
  "crates/chio-kernel-core/src/normalized.rs",
  "crates/chio-kernel-core/src/receipts.rs",
]

Everything outside that list is excluded from the proof boundary. The manifest also names the excluded surfaces verbatim so a reader does not have to infer them: concrete Ed25519, SHA-256, canonical JSON, TLS, OS clock, SQLite, chain, and hosted-registry implementations beyond their audited assumptions; async scheduling, network delivery, subprocess effects, and tool-server behavior after the verified decision core allows a call; cluster consensus, external settlement rails, and third-party registry availability beyond fail-closed handling; Aeneas extraction from async, IO, SQLite, crypto, and string-heavy production modules outside formal_aeneas.rs; and symlink resolution and OS filesystem root enforcement beyond chio's normalized path-prefix fail-closed checks.

The boundary moves with PRs

When a property graduates from audited assumption to discharged by named theorem, the manifest's discharged_assumptions list grows and required_assumption_ids shrinks. The retired RETIRED-SQLITE-CROSS-ROW entry is a worked example: prior cross-row SQLite atomicity is no longer assumed; the conjunction of the TLA+ MonotoneLog invariant and the per-row budget invariant in crates/chio-kernel/src/budget_store.rs does the work the assumption used to do.

What Is in the Trust Base

Ten audited assumptions remain in formal/assumptions.toml as load-bearing. They are listed by ID; each one names the properties it discharges.

  • ASSUME-ED25519 · Ed25519 unforgeability for trusted public keys.
  • ASSUME-SHA256 · SHA-256 and Merkle hash collision resistance.
  • ASSUME-CANONICAL-JSON · RFC 8785 canonical JSON is deterministic and byte-stable.
  • ASSUME-OS-CLOCK · The injected clock reports operator-accepted Unix time within tolerance.
  • ASSUME-SQLITE-ATOMICITY · SQLite per-row writes are atomic. Cross-row atomicity is not assumed; that prior assumption is retired.
  • ASSUME-TLS · TLS endpoint authentication and channel confidentiality.
  • ASSUME-NETWORK-TRANSPORT · Authenticated messages received by chio are not silently rewritten below TLS or signature checks.
  • ASSUME-EXTERNAL-REGISTRIES · Hosted package, certification, DID, and registry services return durably accepted state or fail closed.
  • ASSUME-SUBPROCESS-ISOLATION · Tool-server subprocess and OS process boundaries hold for effects outside the kernel.
  • ASSUME-CHAIN-FINALITY · External chain or oracle finality after the configured confirmation policy accepts the evidence.

See the Assumptions and TCB page for the rationale and mitigation per assumption.


How to Read a Proof Manifest

The manifest at formal/proof-manifest.toml is the canonical proof inventory. Every release-facing formal claim must cite it, the theorem inventory, and the audited assumptions. Here is the shape of the relevant fields.

formal/proof-manifest.toml
schema = "chio.proof-manifest.v1"
manifest_version = 1
proof_boundary_status = "implementation_linked_protocol_core"
verification_target = "security_critical_protocol_semantics"
assumption_registry = "formal/assumptions.toml"
primary_toolchain = ["lean4", "creusot", "kani", "aeneas"]

# Root Lean modules. Theorems must be reachable from these to count.
root_modules = [
  "formal/lean4/Chio/Chio.lean",
  "formal/lean4/Chio/Chio/Spec/Properties.lean",
  "formal/lean4/Chio/Chio/Proofs/Monotonicity.lean",
  # ... eight more entries
]

# Gate commands. Run all of these to reproduce the assurance posture.
gate_commands = [
  "./scripts/check-formal-proofs.sh",
  "./scripts/check-aeneas-pilot.sh",
  "./scripts/check-aeneas-production.sh",
  "./scripts/check-aeneas-equivalence.sh",
  "./scripts/check-rust-verification-gates.sh",
  "./scripts/check-kani-public-core.sh",
  "./scripts/check-adapter-no-bypass.sh",
  "cargo test -p chio-formal-diff-tests",
  "./scripts/check-portable-kernel.sh",
  "./scripts/check-proof-report.sh",
]

# Property matrix. Each entry has the form:
#   ID|description|lanes|theorem-ids
# A property is "covered" only when every named lane runs and every
# theorem ID exists in theorem-inventory.json.
property_matrix = [
  "P1|capability attenuation|lean_root_imported,differential_test,...|spec.capability_monotonicity,...",
  # ... nine more rows
]

Three rules govern the manifest:

  • A theorem only counts as evidence if it is root-imported from the modules in root_modules and contains no sorry.
  • A property only counts as covered if every lane in its property matrix entry runs green in CI.
  • Excluded surfaces and audited assumptions must be cited explicitly. Silent assumptions are forbidden.

Reproducing the Proofs Locally

Every gate command in the manifest is a shell script that any contributor can run. The full set of commands reproduces the assurance posture:

reproduce assurance posture
# Lean root proofs (sorry-free, root-imported)
./scripts/check-formal-proofs.sh

# Aeneas pilot extraction (formal/aeneas/verified_core.rs)
./scripts/check-aeneas-pilot.sh

# Aeneas production extraction (chio-kernel-core/src/formal_aeneas.rs)
./scripts/check-aeneas-production.sh

# Aeneas-Lean equivalence theorems
./scripts/check-aeneas-equivalence.sh

# Creusot and Kani required-lane verification
./scripts/check-rust-verification-gates.sh

# Public Kani harnesses on chio-kernel-core
./scripts/check-kani-public-core.sh

# Adapter no-bypass: every protocol adapter must call evaluate()
./scripts/check-adapter-no-bypass.sh

# Differential tests: reference spec vs production
cargo test -p chio-formal-diff-tests

# Portable-kernel parity (the same verdict on every target)
./scripts/check-portable-kernel.sh

# Proof report: the final aggregator that all gates fed into
./scripts/check-proof-report.sh

The TLA+ lane is separate, since Apalache is not a Cargo dep. The PR job runs the safety invariants:

apalache PR safety lane
# Install Apalache via the pinned tool installer
./tools/install-apalache.sh

# Safety invariants (NoAllowAfterRevoke, MonotoneLog, AttenuationPreserving)
apalache check \
  --inv=SafetyInv \
  --config=formal/tla/MCRevocationPropagation.cfg \
  formal/tla/RevocationPropagation.tla
apalache stdout (excerpt)
PASS #11: BoundedChecker
Checker reports no error up to computation length 16
It took me 0 days  3 hours 12 min 47 sec
Total time: 11567.881 sec
EXITCODE: OK

The nightly liveness lane is broader: PROCS=6, CAPS=16, with --temporal=RevocationEventuallySeen gated on the WF_vars(PropagateAny) weak-fairness conjunct in the spec.

Lean toolchain pin

The Lean toolchain pin lives at formal/lean4/Chio/lean-toolchain: leanprover/lean4:v4.28.0-rc1. lake build picks it up automatically. Kani, Creusot, and Aeneas pin in their own installer scripts under tools/.

What the Proofs Do Not Say

It is worth being explicit about what the assurance layer does not establish.

  • The Lean theorems are over bounded models. They do not witness the Rust binary running on a real CPU; they witness mathematical functions written in Lean. The Aeneas equivalence theorems and the Kani and Creusot lanes are what tie the bounded models to executable code.
  • Crypto primitives are assumed, not proven. The receipt sign-then-verify theorem is over a symbolic crypto model, not over the Ed25519 implementation in ed25519-dalek.
  • Side channels other than timing are out of scope. dudect detects data-dependent timing variation; it does not address power analysis, electromagnetic emanations, or microarchitectural attacks. See the Constant-Time Tests page for what is and is not covered.
  • Behavior of tool servers after chio allows a call is out of scope. The receipt records the verdict; what the tool server does next is the operator's concern.
  • External chain finality is gated on the configured policy. If your settlement layer reorgs deeper than your finality threshold, the assumption breaks and the receipt evidence does too.

Next Steps

For the broader trust framing, the Trust Model page explains where formal assurance sits inside chio's zero-ambient-authority design.

Formal Assurance Overview · Chio Docs