Chio/Docs
LOGIN · JOIN

PlatformOrientation

Formal Assurance

Formal Assurance Overview

What each assurance method checks, the models and code it covers, and the assumptions it leaves outside the proof boundary.

Source records for formal claims

This page cites these source records: formal/proof-manifest.toml, formal/theorem-inventory.json, formal/assumptions.toml, and formal/MAPPING.md. If the docs and the manifests disagree, use the manifests.

Reading paths by role

These four paths group the pages by reader role. Each path identifies the pages to open and the information they provide.

I operate the kernel in production (SRE / platform)

  1. Quickstart · run the manifest's gate commands locally.
  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 its Lean, Rust, and test coverage.
  3. Assumptions and TCB · the explicit trust boundary and the 15 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 · 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 is represented in Lean, Aeneas, Kani, and differential tests.
  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.

Methods and what each one claims

These methods differ in target, model, and assurance claim, and the manifest does not rank them against each other. It records each Rust lane as a lane|posture|path row in rust_refinement_lanes. The 5 rows there register Creusot once, Kani once for each of its two harness registries, and Aeneas at both pilot and production. The manifest notes say what those standings mean: Creusot and Kani are required strict-CI lanes for production implementation linkage, while Lean assets count as release evidence only when they are root-imported, free of sorry, and mapped to a property_matrix entry. Read each row below for its own coverage and its own claim.

LayerToolCoverageStrength
Mechanized proofLean 4Bounded models of the capability algebra, revocation, evaluation, receipts, protocolRoot-imported and checked without sorry.
Refinement extractionAeneas (via Charon)Pure numeric and boolean helpers in formal_aeneas.rsLean equivalence theorems link extracted models to handwritten models.
Bounded model checkingKani (CBMC backend)Public Rust entrypoints: verify_capability, evaluate, sign_receipt, NormalizedScope::is_subset_of, resolve_matching_grantsSymbolic execution exhausts inputs up to configured bounds.
Refinement contractsCreusotSame five public symbols plus the formal_core helpersSMT-discharged contracts on production Rust symbols.
Temporal model checkingTLA+ (Apalache)Cross-authority revocation propagation and delegation-depth boundsFive named safety invariants, conjoined with a domain invariant as SafetyInv, plus one liveness property within configured bounds and the Apalache kernel-state invariants.
Differential property testsproptest in chio-formal-diff-testsReference spec vs production for scope subsumption, anchored roots, receipt encoding, canonical JSONDetects drift between two implementations of the same behavior.
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 behaviorExercises protocol behavior without exhaustive input coverage.
Manual reviewHumansEverything outside the proof boundaryReview of behavior outside the formal boundary; reviewers can miss defects.

Mechanized proofs cover smaller models than tests and review. The distinction is stated in each row's coverage and claim.


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/kernel/chio-kernel-core/src/formal_aeneas.rs. See Aeneas Pipeline.
  • Kani · Bounded model checker for Rust via CBMC. Symbolically executes the public proof harnesses in the nightly kani-public-nightly lane. Public harnesses are at crates/kernel/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. Apalache checks the safety invariants of formal/tla/RevocationPropagation.tla on the path-scoped PR lane and its liveness property on a nightly lane. The same PR lane covers formal/tla/DelegationDepthBound.tla, formal/tla/DistributedRevocation.tla under two configs, and the kernel-state specs under formal/apalache/: MonotoneLogApalache, RevocationCutCompleteness, ReceiptBeforeAllow, KernelTransitionCancelSafe, and PostAdmissionDropGuard. 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/kernel/chio-kernel-core/tests/dudect/. See Constant-Time Tests.
  • libFuzzer + ClusterFuzzLite · Coverage-guided fuzzing across the trust-boundary parsers listed in the target directory. Targets are in fuzz/fuzz_targets/ with corpora at fuzz/corpus/. See Fuzz Infrastructure.
  • cargo-mutants · Mutation testing across six trust-boundary crates (chio-policy, chio-credentials, chio-attest-verify, chio-kernel-core, chio-guards, chio-anchor). Runs nightly as an advisory lane, with a co-coverage job that replays the fuzz corpus against surviving mutants. Configured in .github/workflows/mutants.yml.

What the manifest claims today

required_property_ids declares 10 identifiers, P1 through P10, and property_matrix gives each one a description, a list of evidence lanes, and the theorem ids that stand behind it. The lane column here is that list verbatim; a lane named audited_* is an assumption the property rests on rather than a check that runs.

IDPropertyEvidence lanesTheorems
P1capability attenuationlean_root_imported, differential_test, rust_projection, aeneas_equivalence, public_kani6
P2presented revocation coveragelean_root_imported, audited_storage_assumption, audited_transport_assumption, sqlite_projection, aeneas_equivalence, distributed_apalache, rust_trace_projection6
P3fail-closed evaluationlean_root_imported, rust_core, audited_subprocess_assumption, audited_wasm_engine_assumption, public_kani, adapter_no_bypass, aeneas_equivalence23
P4receipt integritylean_root_imported, symbolic_crypto, audited_crypto_assumption, receipt_totality, aeneas_equivalence, public_kani, differential_test13
P5presented delegation-chain semantic validitylean_root_imported, sqlite_projection6
P6local parent-link soundnesslean_root_imported, audited_storage_assumption1
P7receipt-lineage soundnesslean_root_imported, symbolic_crypto, audited_crypto_assumption2
P8session continuity soundnesslean_root_imported, audited_transport_assumption, dpop_binding_tests, aeneas_equivalence5
P9delegation and provenance consistencylean_root_imported, audited_registry_assumption1
P10report truthfulnesslean_root_imported, claim_gate6

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.

The boundary covers the pure security-decision code 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.toml72-86toml
covered_rust_modules = [
  "crates/kernel/chio-kernel-core/src/capability_verify.rs",
  "crates/kernel/chio-kernel-core/src/scope.rs",
  "crates/kernel/chio-kernel-core/src/evaluate.rs",
  "crates/kernel/chio-kernel-core/src/formal_aeneas.rs",
  "crates/kernel/chio-kernel-core/src/formal_core.rs",
  "crates/kernel/chio-kernel-core/src/normalized.rs",
  "crates/kernel/chio-kernel-core/src/receipts.rs",
  "crates/core/chio-core-types/src/merkle.rs",
  "crates/core/chio-core-types/src/merkle_steps.rs",
  "crates/economy/chio-credit/src/formal_economy.rs",
  "crates/economy/chio-web3/src/settlement.rs",
  "crates/trust/chio-federation/src/revocation_gossip.rs",
  "crates/economy/chio-open-market/src/finding_slash_amount.rs",
]

That list is not the whole of what carries verification evidence. The manifest keeps a second list, covered_rust_symbols, and the two disagree: 47 symbols sit in 17 distinct module paths, and 4 of those paths never appear in covered_rust_modules at all (chio_core_types::capability, chio_core_types::delegation_receipt, chio_kernel_core::revocation_view, chio_revocation_oracle::api). Read the module list as the declared file set rather than as a boundary, and check the symbol list before concluding that a module is uncovered.

What is outside the boundary the manifest states directly, in excluded_surfaces: 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 Chio handling; Aeneas extraction from async, IO, SQLite, crypto, and string-heavy production modules outside the registered sources in formal/aeneas/production.toml; reservation-ledger refinement from the pure ledger_apply model to concrete BudgetStore mutations; symlink resolution and OS filesystem root enforcement beyond Chio's normalized path-prefix fail-closed checks; cross-row receipt and budget crash recovery, ordering, and conservation; runtime trace callbacks omitted or rewritten before delivery to the installed observer; Treaty PredicateLang parsing, hashing, signature verification, store lookup, and completeness outside its explicit AdmissionView decision domain; float-valued JSON leaves in compound receipt-ID fields; refinement from the mechanized canonical projection to crates/core/chio-core-types/src/canonical.rs beyond the checked integer-domain fixtures and differential tests; and wasmtime interpreter, compiler, JIT, sandbox, and host-import information-flow behavior beyond Chio's typed verdict dispatch.

Nothing has been discharged

discharged_assumptions in formal/proof-manifest.toml is empty, and so are retired_assumption_ids and retired_assumptions in formal/assumptions.toml. Cross-row SQLite behavior is the case to know, because an abstract invariant comes close to it and the manifest still declines the conclusion. Of ASSUME-SQLITE-ATOMICITY, the registry says cross-row crash recovery, ordering and conservation are not assumed or discharged and remain outside the current formal claim boundary. Of the invariant, the manifest says ReceiptBeforeAllow proves the abstract persist-before-publish ordering and its production replay exercises the native happy path, and that it does not discharge concrete cross-row crash recovery, which remains excluded until implementation trace validation and crash-reopen conservation gates establish refinement. Cross-row receipt and budget crash recovery is also one of the entries in excluded_surfaces.

Scope and gaps

The receipt theorems prove properties over a symbolic cryptography model, under the Ed25519 and SHA-256 assumptions recorded in formal/assumptions.toml, rather than concrete cryptographic implementations. Most catalog entries prove bounded models, not the running binary. Kani and Lean run nightly, not on each pull request. The drop and cancel-unwind path, which runs when a request is torn down mid-flight, is covered by formal/apalache/PostAdmissionDropGuard.tla at the bound the manifest states: two invocations and one buffered child per invocation, with evidence requiring both a positive NoError result and every paired negative mutation producing a registered ITF counterexample. See Formal Assurance for the full honest-scope treatment.


How to read the proof manifest

The manifest at formal/proof-manifest.toml is the proof inventory. Each release-facing formal claim must cite it, the theorem inventory, and the audited assumptions. Its header pins the schema and the boundary: chio.proof-manifest.v1, implementation_linked_protocol_core, security_critical_protocol_semantics, and primary_toolchain = ["lean4", "creusot", "kani", "aeneas"].

Four arrays carry the substance. root_modules names the 37 Lean modules a theorem must be reachable from to count, listed in full on the Lean 4 Proofs page. property_matrix holds one ID|description|lanes|theorem-ids row for each of the 10 required properties. covered_rust_modules and covered_rust_symbols are the two file and symbol lists above. And gate_commands is the set of commands that reproduces every result the manifest records:

formal/proof-manifest.toml53-70toml
gate_commands = [
  "cargo xtask gen proof-coverage --check",
  "./scripts/check-formal-proofs.sh",
  "./scripts/check-aeneas-pilot.sh",
  "./scripts/check-aeneas-production.sh",
  "./scripts/check-aeneas-equivalence.sh",
  "./scripts/tests/aeneas-equivalence.test.sh",
  "./scripts/check-rust-verification-gates.sh",
  "cargo xtask check formal-mirrors",
  "./scripts/check-kani-public-core.sh",
  "./scripts/run-kani-manifest.sh --lane pr --crate chio-open-market",
  "./scripts/check-adapter-no-bypass.sh",
  "cargo test -p chio-formal-diff-tests",
  "./scripts/check-portable-kernel.sh",
  "./scripts/check-receipt-trace.sh",
  "./scripts/check-distributed-revocation-refinement.sh",
  "./scripts/check-proof-report.sh",
]

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

gate_commands above is the list, in the order the manifest keeps it. Each entry is a shell script or a cargo invocation a contributor runs from the repository root, and the lanes they drive are the Lean root proofs, the Aeneas pilot and production extractions and their equivalence theorems, the Creusot and Kani required lanes, the public Kani core lane, the manual-mirror hash check, adapter no-bypass, the differential tests, portable-kernel parity, the receipt-trace and distributed-revocation refinement checks, and the proof-report aggregator that consumes the rest.

Two of them need nothing beyond a Rust toolchain and a shell, so they are the ones to run first against a clone. ./scripts/check-adapter-no-bypass.sh is a four-line wrapper that execs cargo xtask check adapter-no-bypass; on success that command prints adapter-no-bypass: structured mediation contracts passed from xtask/src/adapter_no_bypass.rs. cargo test -p chio-formal-diff-tests compiles the crate library plus the test files in formal/diff-tests/tests/, which cover anchored roots and their tamper cases, canonical JSON in both the native and browser encoders, receipt encoding, scope subsumption, treaty predicates, and one named regression pinned to the ReceiptBeforeAllow lane.

Two of the cases in receipt_encoding_diff.rs carry #[ignore]. They spawn python3 and node subprocesses against the live Python and TypeScript SDKs, and they opt in through CHIO_LIVE_SDK_DIFFERENTIAL=1 cargo test -- --ignored rather than failing when the SDK is absent.

The TLA+ lane is separate, since Apalache is not a Cargo dependency. ./tools/install-apalache.sh installs the pinned checker, and ./scripts/check-apalache-positive.sh drives one spec at one bound, taking --invariant, --length, --timeout-seconds and --config alongside the spec path. The pull-request job in .github/workflows/apalache-safety.yml runs it once per matrix shard, and the shard covering formal/tla/RevocationPropagation.tla passes SafetyInv at length: 6 with timeout_seconds: 10800. The other shards cover the specs under formal/apalache/, formal/tla/DistributedRevocation.tla under two configs and two different invariants, and formal/tla/DelegationDepthBound.tla.

The nightly liveness lane holds the same PROCS=4, CAPS=8 bounds as the PR safety run but drives them to a deeper computation length (--length=24) with --temporal=RevocationEventuallySeen gated on the WF_vars(PropagateAny) weak-fairness conjunct in the spec. It is a scheduled lane, not a required PR gate.

Lean toolchain pin

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

Next steps

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