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
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)
- Quickstart · run the manifest's gate commands locally.
- Failure Modes · what each gate failure looks like in CI output.
- Assumptions and TCB · what is trusted vs verified, and what to do if an assumption breaks in production.
- Constant-Time Tests · timing-leak detection on the verdict hot path.
I'm auditing or certifying chio (security auditor / compliance)
- Theorem Inventory · the per-theorem catalog: ID, statement, tool, file, status.
- P1 Tour · a worked example tracing capability attenuation through its Lean, Rust, and test coverage.
- Assumptions and TCB · the explicit trust boundary and the 15 audited assumptions the proofs are conditioned on.
- Differential Tests · production-vs-spec equivalence on scope subsumption, canonical JSON, anchored roots, receipts.
I'm an academic or formal-methods researcher (Lean / TLA+)
- Lean 4 Proofs · theorem statements and the project layout.
- Aeneas Pipeline · the Rust-to-Lean extraction pipeline (a Lean-targeted adaptation of Aeneas, paired with explicit equivalence theorems).
- TLA+ Specs · the temporal-logic spec for cross-authority revocation propagation.
- Theorem Inventory · the catalog you cite when comparing to your own work.
I'm contributing a proof or harness (chio contributor)
- P1 Tour · how a property is represented in Lean, Aeneas, Kani, and differential tests.
- Lean 4 Proofs · Lean conventions, naming, and the proof-file layout.
- Kani Harnesses · how to write a new bounded-model-checking harness.
- Fuzz Infrastructure · adding a new libFuzzer target, owners table, and corpus.
- 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.
| Layer | Tool | Coverage | Strength |
|---|---|---|---|
| Mechanized proof | Lean 4 | Bounded models of the capability algebra, revocation, evaluation, receipts, protocol | Root-imported and checked without sorry. |
| Refinement extraction | Aeneas (via Charon) | Pure numeric and boolean helpers in formal_aeneas.rs | Lean equivalence theorems link extracted models to handwritten models. |
| Bounded model checking | Kani (CBMC backend) | Public Rust entrypoints: verify_capability, evaluate, sign_receipt, NormalizedScope::is_subset_of, resolve_matching_grants | Symbolic execution exhausts inputs up to configured bounds. |
| Refinement contracts | Creusot | Same five public symbols plus the formal_core helpers | SMT-discharged contracts on production Rust symbols. |
| Temporal model checking | TLA+ (Apalache) | Cross-authority revocation propagation and delegation-depth bounds | Five 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 tests | proptest in chio-formal-diff-tests | Reference spec vs production for scope subsumption, anchored roots, receipt encoding, canonical JSON | Detects drift between two implementations of the same behavior. |
| Coverage-guided fuzz | libFuzzer plus ClusterFuzzLite | All trust-boundary parsers, decoders, and verifiers | Medium. Random and mutation-driven inputs over many CPU-hours. |
| Timing analysis | dudect | Signature byte-equality, scope subset checks | Limited. Statistical detection of data-dependent timing, not a proof. |
| Integration tests | cargo test | End-to-end protocol behavior | Exercises protocol behavior without exhaustive input coverage. |
| Manual review | Humans | Everything outside the proof boundary | Review 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.rsand the production extraction fromcrates/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-nightlylane. Public harnesses are atcrates/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.tlaon the path-scoped PR lane and its liveness property on a nightly lane. The same PR lane coversformal/tla/DelegationDepthBound.tla,formal/tla/DistributedRevocation.tlaunder two configs, and the kernel-state specs underformal/apalache/:MonotoneLogApalache,RevocationCutCompleteness,ReceiptBeforeAllow,KernelTransitionCancelSafe, andPostAdmissionDropGuard. 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 atfuzz/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.
| ID | Property | Evidence lanes | Theorems |
|---|---|---|---|
| P1 | capability attenuation | lean_root_imported, differential_test, rust_projection, aeneas_equivalence, public_kani | 6 |
| P2 | presented revocation coverage | lean_root_imported, audited_storage_assumption, audited_transport_assumption, sqlite_projection, aeneas_equivalence, distributed_apalache, rust_trace_projection | 6 |
| P3 | fail-closed evaluation | lean_root_imported, rust_core, audited_subprocess_assumption, audited_wasm_engine_assumption, public_kani, adapter_no_bypass, aeneas_equivalence | 23 |
| P4 | receipt integrity | lean_root_imported, symbolic_crypto, audited_crypto_assumption, receipt_totality, aeneas_equivalence, public_kani, differential_test | 13 |
| P5 | presented delegation-chain semantic validity | lean_root_imported, sqlite_projection | 6 |
| P6 | local parent-link soundness | lean_root_imported, audited_storage_assumption | 1 |
| P7 | receipt-lineage soundness | lean_root_imported, symbolic_crypto, audited_crypto_assumption | 2 |
| P8 | session continuity soundness | lean_root_imported, audited_transport_assumption, dpop_binding_tests, aeneas_equivalence | 5 |
| P9 | delegation and provenance consistency | lean_root_imported, audited_registry_assumption | 1 |
| P10 | report truthfulness | lean_root_imported, claim_gate | 6 |
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:
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:
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_modulesand contains nosorry. - 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
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
- Theorem Inventory · the full table of theorems by ID, statement, tool, file, and status.
- Assumptions and TCB · what Chio trusts, why, and what would mitigate each assumption breaking.
- Aeneas Pipeline · how the production extraction is wired to the Lean equivalence theorems.
- Lean 4 Proofs · the proof structure, file by file.
- Kani Harnesses · the public harness inventory plus per-harness wall clocks.
- TLA+ Specs · the revocation-propagation spec and the invariants it names.
- Differential Tests · reference spec vs production for the surfaces that proofs do not cover.
- Constant-Time Tests · dudect harnesses and how to read their output.
- Fuzz Infrastructure · the trust-boundary fuzz target inventory.
For the broader trust framing, the Trust Model page explains where formal assurance sits inside Chio's zero-ambient-authority design.