What's mechanically proven in typed-wasm, what's outstanding, and what's blocked on prerequisites.
This page is for readers asking "where is the theorem?" when faced with typed-wasm's safety claims. The proofs live in src/abi/TypedWasm/ABI/*.idr and are mechanically checked by Idris2 0.8.0. The detailed inventory lives in PROOF-NEEDS.md and LEVEL-STATUS.md; this page summarises and links.
- 0
believe_mein the checked package - 0
assert_totalin the checked package - 0
postulatein the checked package - 0
sorry/ 0Admittedin the checked package - 0
assert_smallerin the checked package %default totaleverywhere
Verified by tests/proof/regression.mjs (107 named-theorem grep assertions) and by idris2 --build src/abi/typed-wasm.ipkg (24/24 modules under Idris2 0.8.0).
24 Idris2 modules. Per-module status is in LEVEL-STATUS.md §"Proof inventory"; the headline:
| Module | Role |
|---|---|
Region.idr |
Schema + FieldIn (L1, L2, L5 structural primitives) |
TypedAccess.idr |
Typed load/store + AccessResult (L3, L6) |
Levels.idr |
Canonical L1-L10 data types |
Pointer.idr |
Pointer kinds + ExclusiveWitness (L4, L7) |
Effects.idr |
Effect-set + subsumption (L8) |
Lifetime.idr |
Outlives preorder + load-safety (L9) |
Linear.idr |
CompletedProtocol + linear discipline (L10) |
MultiModule.idr |
Schema-subtype + no-spoofing theorem (cross-module) |
Tropical.idr |
Cost-bounded paths (L11, draft) |
Epistemic.idr |
Freshness propagation (L12, draft) |
ModuleIsolation.idr |
Per-module memory isolation (L13) |
SessionProtocol.idr |
Session protocols + WellFormedProtocol (L14) |
ResourceCapabilities.idr |
Capability lattice (L15) |
Choreography.idr |
Composition over L13+L14+L15 (L16) |
Layout.idr + Layout/*.idr |
Cross-language layout contracts |
Echo.idr |
Echo composition (research) |
Proofs.idr |
Top-level certificate assembly + witness-indexed attestation API + WitnessCertificate lift |
VerifierSpec.idr |
Spec-of-record for the Rust post-codegen verifier (added 2026-05-27 via PR #79) |
The 2026-05-18 PROOF-NEEDS reconciliation banner deferred several long-tail items. A 2026-05-27 sweep closed three of them:
The post-A10 audit (item 7: Rust verifier ↔ Idris2 spec equivalence; item 8: source-checker ↔ verifier coverage agreement) stated two record obligations:
record VerifierSpecAgreement where
constructor MkVerifierSpecAgreement
verifierIsSound : (m : ModuleSummary) -> VerifierAccepts m -> SpecAccepts m
verifierIsComplete : (m : ModuleSummary) -> SpecAccepts m -> VerifierAccepts m
record SourceVerifierAgreement where
constructor MkSourceVerifierAgreement
sourceImpliesVerifier : (m : ModuleSummary) -> SourceAccepts m -> VerifierAccepts m
verifierImpliesSource : (m : ModuleSummary) -> VerifierAccepts m -> SourceAccepts mPR #74 attempted these with Maybe-returning bridges and a closed-world RegisteredFixture GADT, but the records themselves remained uninhabited — #74 explicitly called this "the multi-week residual".
PR #79 closes the bodies by refactoring the differential constructor to carry the structural witness inline:
data VerifierAccepts : ModuleSummary -> Type where
VAStructural : FunctionsAccepted m.functions -> VerifierAccepts m
VADifferential : (fixture : TrustedFixture m) -> VerifierAccepts m
record TrustedFixture (m : ModuleSummary) where
constructor MkTrustedFixture
trustedFixtureName : String
trustedFixtureId : Nat
trustedWitness : FunctionsAccepted m.functionsThe trust-injection moment moves to MkTrustedFixture construction (single grep point for audit). All four agreement lemmas become total by case analysis. verifierSpecAgreement : VerifierSpecAgreement and sourceVerifierAgreement : SourceVerifierAgreement are concrete inhabitants — the first total no-believe_me agreement values in the codebase.
End-to-end demo on cross_compat row 1 (fixtureCleanLinearConsumerModule). Four discrimination proofs show L10 has teeth and the differential escape hatch cannot smuggle a bad module past the verifier.
The 2026-05-18 banner flagged:
"Stronger 'attestation entails the level's semantic property' (needs
LevelAttestationreindexed by witness) remains tracked future work under standards#130."
The A9 work proved LevelAchievedIn N [attestLN_X w] — i.e. "the certificate provably claims level N". But that's the weaker face: anyone holding the attestation cannot recover the underlying witness (ExclusiveWitness s for L7, etc.) because the legacy attestLN_* family discards it.
PR #80 closes this with a witness-indexed GADT:
data LevelAttestationW : (n : Nat) -> Type where
AttestL7W : {s : Schema} -> (w : ExclusiveWitness s) -> LevelAttestationW 7
-- … 14 more constructors, one per level
attestL7W_EntailsAliasFree :
LevelAttestationW 7
-> (s : Schema ** ExclusiveWitness s)
attestL7W_EntailsAliasFree (AttestL7W {s} w) = (s ** w)A consumer holding LevelAttestationW 7 can now discharge the L7 semantic property (alias-freeness via ExclusiveWitness s) — not just the weak claim-predicate. Purely additive: legacy LevelAttestation, MkAttestation, attestLN_*, attestLN_Sound, LevelAchievedIn, composeCertificates, ProofCertificate are all unchanged. 15 ctors + 15 smart ctors + 15 extractors + legacy bridge + 15 round-trip Refls + uniform attestLW_AchievedIn (subsuming the A9 family).
LevelAttestationW n retains the witness per attestation, but ProofCertificate still uses List LevelAttestation for its levels field, so a heterogeneous certificate can't be built directly. PR #83 (folded into #80) adds an existential wrapper:
data SomeAttestationW : Type where
MkSomeAttW : {n : Nat} -> (att : LevelAttestationW n) -> SomeAttestationW
record WitnessCertificate where
constructor MkWitnessCert
witnessLevels : List SomeAttestationW
witnessHighestProven : Nat
witnessMultiModule : List CompatCertificate
witnessToLegacy : WitnessCertificate -> ProofCertificate
composeWitness : WitnessCertificate -> WitnessCertificate -> WitnessCertificate
WitnessAchieved : (n : Nat) -> WitnessCertificate -> TypeThe composeWitnessLegacyAgree lemma pins down: composing the legacy projections equals projecting the witness composition — the two paths stay consistent.
In rough decreasing priority:
Status: climbing (2026-06-16). This is a second, complementary axis to the
Idris-model proofs above: the assurance that the Rust producer's emitted bytes
are what an independent verifier accepts and a wasm engine executes correctly.
Full per-tier detail (T1…T5) lives in
PROOF-NEEDS.md §"RECONCILIATION 2026-06-16 (codegen climb)". Headline:
- T1 execution gate — ✅ landed (
tests/execute_lowering.rs, wasmi round-trip + no-clobber, non-vacuous by mutation). Empirical stand-in for the byte-equality / WasmCert items below until those land. - T2 verifier self-certification — ✅ landed (
verify_access_typing_from_module+AccessTypingReport): the verifier decodes the code section and checks each pinned access lands on a load/store of the field's exact type/width/offset, in-region. Closes proposal-0002's deferredAccessSiteMisalignment. Tests intests/access_typing.rs(positive + 5 teeth + control, mutation-proven). - T3 parser totality —
⚠️ 3 pre-existing arithmetic panics remain (hardening PR pending). - T4 layout-equivalence lemma — ❌
Layout/ABI.idroffsets vs Rustresolve_field, unproven equal (next bridge). - T5a verifier↔spec — ◐ trusted-base via ADR-0005; T5b WasmCert tie-back — ❌ (same item as below).
Status: in progress on PRs #76 (carrier-section wire-format proposal) + #77 (L2 codec pre-staged behind cfg(feature = "unstable-l2")). DO NOT interfere — actively worked by a parallel session.
The Rust verifier currently covers L7 (aliasing) + L10 (linearity) only. Extending it requires a multi-producer ABI change: a new custom section for L2-L6 region/field schema + nullability + cardinality, and another for the L15 capability lattice. Coordinated across hyperpolymath/{typed-wasm,ephapax,affinescript}.
Status: not started. Tracked in docs/supplementary/proof-inventory.adoc:45, docs/WHITEPAPER.md:602, LEVEL-STATUS.md:66. Requires external Isabelle/HOL artifact + bridge; multi-week. The goal is to connect typed-wasm's Region.idr semantics to the WasmCert mechanised operational semantics so the L1-L6 claims can be discharged against a reference wasm semantics, not just paper-equivalents.
Status: blocked on emitter. PROOF-NEEDS.md:442 explicitly says: "blocked pending a .twasm→.wasm emitter". Once an emitter lands, extend tests/echidna/echidna-harness.mjs Property 5 to run both sides through the emitter and assertBytesEqual.
Status: blocked on parser port. The AffineScript parser is OCaml (lib/ocaml/Parser.affine). The ECHIDNA-side fuzz property is doable today; the Idris2 mechanical proof is blocked on the Track A AffineScript→Idris2 parser port.
| Layer | What it proves | Where |
|---|---|---|
| Idris2 proofs | Type discipline is sound (spec-level): every well-typed program respects L1-L10 / L13-L16 | src/abi/TypedWasm/ABI/*.idr |
| Source checker | Source programs respect the discipline | hyperpolymath/affinescript:lib/codegen.ml (QTT pass), upcoming .twasm parser/checker |
| Post-codegen verifier | Emitted wasm bytes respect the discipline (covers L7 + L10 today) | crates/typed-wasm-verify/ (Rust) + hyperpolymath/affinescript:lib/{tw_verify,tw_interface}.ml (OCaml, reference impl) |
| Spec-of-record (2026-05-27) | Verifier and source-checker agree with the Idris2 spec — bundled as totally-proven records | src/abi/TypedWasm/ABI/VerifierSpec.idr (NEW) |
The agreement records introduced in PR #79 close the loop: a drift between the Rust verifier's accept-verdict on a fixture and the Idris2 spec's SpecAccepts predicate now shows up either as a failing differential-harness fixture or as an absent TrustedFixture registration. Trust is injected once per audited fixture, not at every consumer.
# Build the proof package
IDRIS2_PREFIX=$IDRIS2/0.8.0 idris2 --build src/abi/typed-wasm.ipkg
# expects: 24/24 modules, rc=0
# Run the proof regression
PATH=$IDRIS2/0.8.0/bin:$PATH \
IDRIS2_PREFIX=$IDRIS2/0.8.0 \
node tests/proof/regression.mjs --strict
# expects: 107 passed, 0 failed, 0 skipped
# Verify no banned patterns
grep -rnE "believe_me|assert_total|postulate|sorry|Admitted|assert_smaller" \
src/abi/TypedWasm/ABI/*.idr \
| grep -vE "^[^:]+:[0-9]+:--|^[^:]+:[0-9]+:[[:space:]]*--|^[^:]+:[0-9]+:\|\|\|"
# expects: no output (only banner comments mention banned patterns)PROOF-NEEDS.md— full per-obligation inventory with reconciliation bannersLEVEL-STATUS.md— per-module believe_me / postulate / assert_total status + post-codegen verifier coveragedocs/supplementary/proof-inventory.adoc— paper-facing summaryCHANGELOG.md— dated PR landings- Phase-0-Status — Phase 0 engineering surface (orthogonal to proof debt)
- Production-Path — the 6-phase plan