Auditor: Independent Formal Verification & Fuzzing Specialist
Date: 2026-02-25 (re-audit superseding prior 10/10 report)
Updated: 2026-02-25 (remediation pass β 6 of 8 gaps closed)
Branch: main (post-commit 5087a44 + remediation commits)
Scope: Formal verification, fuzzing, property-based testing, coverage, reachability, CI enforcement
The prior audit report claiming 10/10 contained factual inaccuracies β most critically, it stated Verus was "FIXED" with "30+ real verus!{} proofs" when the CI Dockerfile still performs grep-based structural analysis only and never invokes the Verus/Z3 toolchain. This re-audit is based on direct file reads of every formal specification, CI workflow, fuzz harness, test file, and coverage configuration in the repository.
Remediation (6 of 8 original gaps closed):
Verus CI fabricates Z3 resultsβ FIXED: Dockerfile and CI job honestly relabeled as "Structural Regression Tracker (NOT Z3)".SECURITY_INVARIANTS.mdVerus rows downgraded from β toβ οΈ STRUCTURAL.Rust coverage has no thresholdβ FIXED: 70% minimum enforcement added torust-test-coverage.yml.Security coverage gate targets only 7 modulesβ FIXED: Expanded to 14 secret-handling modules.crypto_core has zero proptestβ FIXED: 15 property tests added (crypto_core/tests/property_tests.rs).Several modules lack fuzz harnessesβ FIXED: 3 new fuzz harnesses created (fuzz_x25519_fs.py,fuzz_timelock_expiry.py,fuzz_forensic_cleanup.py), added tofuzz.yml.Python coverage thresholds 70%/80%β FIXED: Raised to 80%/85%.- AEAD-005β012 vacuous lemmas β OPEN (acknowledged RL-1, research-level).
- Lean 1 sorry + 2 axioms β OPEN (API incompatibility, textbook axioms).
- Five-tool formal verification stack: TLA+ (7 specs), ProVerif (6 models), Tamarin (16 models), Lean 4 (4 files), Verus (4 files) β 13,000+ lines of specifications across 44 artifacts. All except Verus are genuinely CI-executed and blocking.
- 31 fuzz targets (21 Python Atheris + 1 AFL++ + 9 Rust cargo-fuzz), all CI-gated on push/PR, exercising real production code (verified via import statements).
- 2,953+ test functions (2,412 Python + 541 Rust) plus 29 Rust proptest blocks and 20+ Python Hypothesis property tests.
- 348 dedicated security tests in
tests/security/across 18 test files. - Meta-tests that verify production boundaries, fuzz target coverage, fail-closed enforcement, and absence of Python key bytes β unusual and commendable discipline.
- Mutation testing (mutmut + cargo-mutants) running on push + weekly.
- Negative formal tests in both ProVerif (replay vulnerability documented) and Tamarin (NoKEMBinding, LeaksFailureReason correctly fail).
| Priority | Gap | Status |
|---|---|---|
| β FIXED β Honestly relabeled; SECURITY_INVARIANTS.md downgraded | ||
| High | AEAD-005β012 Verus lemmas are vacuous | OPEN (acknowledged RL-1) |
| β FIXED β 70% minimum via tarpaulin output parsing | ||
| β FIXED β Raised to 80%/85% | ||
crypto_core has zero proptest despite declaring the dep |
β
FIXED β 15 property tests in property_tests.rs |
|
| Medium | Lean has 1 approved sorry + 2 axioms | OPEN (API gap + textbook axioms) |
| Low | Constant-time is statistical only (dudect, exit-0) | OPEN (no formal CT proof) |
| β FIXED β 3 new harnesses, 4 modules covered |
| Tool | Artifacts | Total LOC | CI Job | CI-Gated? |
|---|---|---|---|---|
| TLA+ (TLC) | 7 specs + 7 configs | ~2,180 | formal-verification.yml β tlaplus |
β Blocking |
| ProVerif 2.05 | 6 models | ~3,093 | formal-verification.yml β proverif |
β Blocking |
| Tamarin 1.10.0 | 16 .spthy files | ~3,504 | formal-verification.yml β tamarin |
β Blocking (10) + non-blocking (5) |
| Lean 4 (Mathlib) | 4 .lean files | ~966 | formal-verification.yml β lean |
β Blocking + sorry gate |
| Verus | 4 .rs files | ~3,426 | formal-verification.yml β verus |
Total formal LOC: ~13,169 lines across 44 specification files.
TLA+ (7 specs β all TLC-verified in CI):
| Spec | Lines | Key Properties |
|---|---|---|
MeowEncode.tla |
626 | Auth-then-output state machine, manifest integrity |
MeowFountain.tla |
268 | Fountain decode guarantee (1.5Γ k suffices) |
MeowStreaming.tla |
283 | Streaming protocol liveness, frame ordering |
MeowRatchet.tla |
227 | Ratchet DoS bound, chain monotonicity, key uniqueness |
MasterRatchet.tla |
210 | Cross-session forward secrecy |
TimingEqualizer.tla |
166 | Constant-time equalization |
ExpiryProtocol.tla |
β | Message expiry fail-closed invariant |
ProVerif (6 models β all verified in CI):
| Model | Lines | Key Queries |
|---|---|---|
meow_encode.pv |
1,099 | Dolev-Yao secrecy, authentication, duress safety (3 critical queries gated) |
meow_aad_8field_binding.pv |
β | 8-field AAD binding under active network attacker |
pq_beacon_pcs.pv |
β | Post-quantum beacon post-compromise security |
manifest_signing.pv |
β | Ed25519/ML-DSA manifest signature unforgeability |
deadmans_switch_duress.pv |
β | Dead-man's switch duress protocol |
meow_encode_NEGATIVE_ReplayNoCounterCheck.pv |
1,095 | Negative test: confirms replay attack succeeds without counter (correctly fails) |
Tamarin (16 models β 10 blocking, 5 non-blocking, 1 negative):
| Model | Lemmas | Status | Key Properties |
|---|---|---|---|
MeowSchrodingerDeniability_Core.spthy |
~8 | β Blocking | Deniability, indistinguishability |
MeowSchrodingerDeniability_Ratchet.spthy |
~7 | β Blocking | Ratcheted deniability |
MeowKeyCommitment.spthy |
4 | β Blocking | Invisible salamanders prevention |
MeowRatchetFS.spthy |
5 | β Blocking | Per-frame forward secrecy, PCS |
MeowAEADBinding.spthy |
5 | β Blocking | 4-ary AEAD AAD binding, nonce uniqueness, executability |
meow_deadmans_switch.spthy |
4 | β Blocking | Dead-man's switch protocol |
MeowDuressEquiv.spthy |
β | β Blocking | MEOW3 duress equivalence |
MeowDuressEquivPQ.spthy |
β | β Blocking | MEOW4/5 PQ duress equivalence |
MeowDuressEquivPQ_NEGATIVE_NoKEMBinding.spthy |
β | β Negative | Correctly falsified |
MeowDuressEquivPQ_NEGATIVE_LeaksFailureReason.spthy |
β | β Negative | Correctly falsified |
SchrodingerDeniabilityTiming.spthy |
β | Timing analysis (may timeout) | |
secure_alloc_guard_pages.spthy |
β | Memory allocation model | |
RatchetHeaderOE.spthy |
β | Header observational equivalence | |
SchrodingerOE.spthy |
β | SchrΓΆdinger OE | |
meow_encode_equiv.spthy |
β | Encoding equivalence |
Lean 4 (4 files):
| File | Lines | Theorems | Open Items |
|---|---|---|---|
DomainSeparation.lean |
225 | 10+ theorems via native_decide (distinctness, prefix-free, versioning, min length β₯14) |
None β fully proved β |
ShamirSecretSharing.lean |
175 | GF(2^8) field axioms via native_decide |
1 approved axiom: shamir_threshold_security (Lagrange interpolation, textbook) |
FountainCodes.lean |
412 | XOR algebra, droplet recovery, type-level k-block indexing | 1 approved sorry at L254 (Lean 4.5.0 List.find? API incompatibility) |
Assumptions.lean |
131 | None (registry) | Axiom A1: lt_decode_completeness_prob (Luby FOCS 2002); Axiom A2: belief_propagation_progress (proof sketch only) |
Original Evidence: formal/Dockerfile.verus counted proof fn / spec fn strings with grep and synthesized fake "verification results:: verified: N, errors: 0" output.
Remediation Applied:
formal/Dockerfile.verusrewritten: Now titled "Verus Structural Regression Tracker (NOT Z3 Verification)", emits "structural inventory:: proof_spec_fn_count: N" instead of fake verification results.formal-verification.ymlVerus job renamed from "Verus Implementation Proofs (Docker)" to "Verus Structural Regression Check (NOT Z3)". Parsing updated to match new honest output format.docs/SECURITY_INVARIANTS.mdv1.3: All 6 Verus rows downgraded from β toβ οΈ STRUCTURAL with explanatory note: "The CI job performs grep-based regression tracking... does NOT invoke the Verus/Z3 SMT solver."
Compounding factors:
verus_proofs.rslines 1-8: file header explicitly states "β IMPORTANT β noverus!{}blocks exist in this file... They are NOT machine-checked proofs."- AEAD-005β012 are documented as "abstract only (preconditions subsume postconditions)" in both
verus_proofs.rs:L22andformal-10x-audit.md(RL-1). - The prior audit report claimed this was "FIXED" with "30+ real
verus!{}proofs" β this is factually incorrect.
Impact: 26 claimed properties (AEAD-001β012, GB-001β008, KDF-001β004, WG-001β007) are NOT machine-checked by Z3/SMT in CI. SECURITY_INVARIANTS.md overclaims Verus verification status.
| Tool | Linkage Type | Quality |
|---|---|---|
| TLA+ | Abstract state machines referencing protocol concepts | Partial β comments name modules but no line-level traceability |
| ProVerif | Dolev-Yao symbolic model | Partial β maps to encode/decode/crypto flows informally |
| Tamarin | Symbolic key exchange and AEAD rules | Partial β same as ProVerif |
| Lean 4 | Domain separation lists 7 specific HKDF constants from ratchet.py |
Good β strongest linkage |
| Verus | verus!{} blocks inline in production Rust (aead_wrapper.rs) |
Excellent linkage IF verified β but CI doesn't run Verus |
- AEAD INT-CTXT (AEAD-005): Requires GF(2^128) GHASH model, open research
- Assembly-level constant-time: dudect is statistical, warning-only (exit 0)
- All 26 Verus properties: Syntactically present but NOT Z3-checked in CI
- Shamir threshold security: Lean axiom (not proved)
- Belief propagation progress: Lean approved sorry (API gap)
Impressive breadth across 5 tools with 40+ artifacts. TLA+, ProVerif, Tamarin, and Lean are genuinely CI-executed and blocking. The Verus CI gap (grep-only, not Z3) remains, BUT is now honestly documented β SECURITY_INVARIANTS.md v1.3 downgraded all Verus rows to
Python Atheris (21 harnesses, CI-gated on push/PR):
| Harness | LOC | Production Code Exercised |
|---|---|---|
fuzz_manifest.py |
94 | crypto.unpack_manifest, verify_manifest_hmac |
fuzz_fountain.py |
114 | fountain.FountainDecoder, unpack_droplet |
fuzz_crypto.py |
183 | crypto.derive_key, decrypt_to_raw, unpack_manifest |
fuzz_windows_guard.py |
505 | memory_guard.GuardedBuffer |
fuzz_mouse_gesture.py |
450 | Mouse gesture auth module |
fuzz_tamper_detection.py |
530 | tamper_detection.* |
fuzz_adversarial_stego.py |
626 | Stego adversarial rotation |
fuzz_ratchet.py |
273 | ratchet.init_ratchet, encrypt_frame, decrypt_frame |
fuzz_manifest_signing.py |
345 | manifest_signing.* |
fuzz_pq_ratchet_beacon.py |
306 | pq_ratchet_beacon.* |
fuzz_master_ratchet.py |
253 | master_ratchet.* |
fuzz_schrodinger.py |
298 | schrodinger_encode.*, quantum_mixer.* |
fuzz_crypto_backend.py |
262 | crypto_backend.* (Rust FFI) |
fuzz_shamir.py |
330 | shamir_split.* |
fuzz_memory_guard.py |
214 | memory_guard.GuardedBuffer |
fuzz_dual_stream.py |
210 | dual_stream.* |
fuzz_stego_multilayer.py |
291 | stego_multilayer.* |
fuzz_pq_hybrid.py |
359 | pq_hybrid.hybrid_encapsulate/decapsulate |
fuzz_x25519_fs.py |
~160 | NEW x25519_forward_secrecy.derive_shared_secret, keypair gen, serialize/deserialize |
fuzz_timelock_expiry.py |
~160 | NEW timelock_duress.TimeLockPuzzle, expiry.ExpiryManager |
fuzz_forensic_cleanup.py |
~130 | NEW forensic_cleanup._scrub_file_lines, ForensicCleaner init |
afl_fuzz_manifest.py |
53 | crypto.unpack_manifest (AFL++) |
Import verification: All Python harnesses import real production modules (confirmed via grep '^from meow_decoder\|^import meow_decoder' across all fuzz files).
Rust cargo-fuzz (9 targets, CI-gated on push/PR):
| Target | Crate |
|---|---|
fuzz_decrypt_frame |
rust_crypto |
fuzz_header_parse |
rust_crypto |
fuzz_hybrid_decapsulate |
rust_crypto |
fuzz_ratchet_step |
rust_crypto |
fuzz_full_decode_pipeline |
rust_crypto |
fuzz_aead |
crypto_core |
fuzz_nonce |
crypto_core |
fuzz_secure_alloc |
crypto_core |
fuzz_pure_crypto |
crypto_core |
Long-fuzz (weekly, long-fuzz.yml): 5 targets Γ 3600s each: fuzz_tamper_detection.py, fuzz_crypto_backend.py, fuzz_schrodinger.py, fuzz_ratchet.py, fuzz_adversarial_stego.py.
fuzz.yml: Triggers on push + PR + weekly + manual. Crash gate checksfuzz/crashes/directory and fails if non-empty.rust-security-suite.yml: 5rust_crypto+ 4crypto_coretargets each run 60s with crash detection and artifact upload.long-fuzz.yml: Weekly 1-hour per target, crash artifacts uploaded.- All fuzz jobs have
continue-on-error: false(verified β prior fix from commita2b26cf).
Python (Hypothesis):
test_property_based.pyβ 20 tests: encrypt/decrypt roundtrip, fountain encode/decode, nonce uniqueness, key derivation determinism, manifest packing, frame MAC integritytest_property_ratchet_pq.pyβ Ratchet chain one-wayness, key commitment binding, master ratchet monotonicity, PQ beacon roundtrip, manifest signing, Shamir thresholdtest_property_shamir_dualstream.pyβ Shamir field arithmetic, dual-stream identity, size normalizer roundtrip, decorrelation bounds
Rust (proptest):
rust_crypto/tests/property_tests.rsβ 14proptest!blocks (496 lines): decrypt roundtrip, nonce exhaustion, Argon2 determinism, HMAC integrity, frame header parsingrust_crypto/tests/proptest_crypto.rsβ 414 lines additional property testscrypto_core/tests/property_tests.rsβ 15 proptest blocks (NEW): AEAD roundtrip, ciphertext length invariant, tamper detection, wrong AAD/key rejection, invalid key size, truncated ciphertext, nonce uniqueness, HMAC roundtrip, HMAC wrong-key rejection, SHA-256 determinism + collision resistance, HKDF determinism, constant_time_eq reflexivity + rejection
| Module | Has Fuzz? | Has Property Test? | Has Unit Tests? |
|---|---|---|---|
x25519_forward_secrecy.py |
β
NEW fuzz_x25519_fs.py |
β | β |
timelock_duress.py |
β
NEW fuzz_timelock_expiry.py |
β | β |
expiry.py |
β
NEW fuzz_timelock_expiry.py |
β | β |
forensic_cleanup.py |
β
NEW fuzz_forensic_cleanup.py |
β | β |
secure_temp.py |
β | β | β |
decorrelation.py |
β | β (via test_property_shamir_dualstream.py) | β |
env_safety.py |
β | β | β |
Exceptional fuzz breadth β 21 Python Atheris harnesses (18 original + 3 new) + 9 Rust cargo-fuzz, all CI-gated and exercising real production code. Property-based testing with Hypothesis and proptest covers core crypto invariants, including 15 new proptest blocks for crypto_core. Long-fuzz and mutation testing add depth. Remaining gaps: secure_temp.py and env_safety.py still lack fuzz harnesses; coverage thresholds could be higher.
| Scope | Metric | Threshold | CI-Enforced? | Evidence |
|---|---|---|---|---|
| Python (batch 1) | Line + Branch | 80% | β
--cov-fail-under=80 |
ci.yml:L155 (raised from 70%) |
| Python (batch 2) | Line + Branch | β | β Blocking gate (no threshold) | ci.yml:L193 |
| Security modules (14 files) | Line + Branch | 85% | β
--cov-fail-under=85 |
ci.yml:L522 (raised from 80%, expanded from 7 files) |
.coveragerc-security (local) |
Line + Branch | 85% | β Local only | .coveragerc-security:L48 |
General .coveragerc |
Line + Branch | 0% | β No enforcement | .coveragerc:L52 |
| Rust (all crates) | Line | 70% | β NEW β tarpaulin output parsing | rust-test-coverage.yml (was 0%) |
Note: Rust coverage enforcement was added by parsing tarpaulin output percentages for both crypto_core and rust_crypto crates, failing CI if either drops below 70%.
Targets 14 modules (expanded from 7): constant_time, frame_mac, crypto_backend, crypto, metadata_obfuscation, ratchet, pq_hybrid, x25519_forward_secrecy, memory_guard, secure_temp, schrodinger_encode, quantum_mixer, master_ratchet, manifest_signing β with --cov-fail-under=85 (raised from 80%).
Modules still excluded from security coverage that handle secrets:
meow_decoder/pq_ratchet_beacon.py
Per .coveragerc, the following are omitted from all coverage measurement:
meow_decoder/pq_ratchet_beacon.py,deadmans_switch_cli.py,mobile_bridge.py,logo_eyes.py,hardware_integration.py, 20+ additional modules.
- Python (mutmut): CI workflow
mutation-testing.ymlruns on push (path-filtered) + weekly.mutmut_config.pydefines paths and patterns. - Rust (cargo-mutants): Same workflow, runs
cargo-mutantsoncrypto_core/andrust_crypto/. - Status: Both jobs exist and are CI-gated. Quality of mutation score tracking not assessed (no historical data visible).
ci.yml "All CI Gates" summary job requires:
- Preflight (lint) β β Blocking
- Test Batch 1 (coverage β₯70%) β β Blocking
- Test Batch 2 β β Blocking
- Security Coverage (β₯80%) β β Blocking
- Slow Tests (Monte Carlo) β β Blocking
- Cat Mode Tests (Gates 2-4) β
β οΈ Non-blocking (warnings)
Additional blocking workflows:
fuzz.ymlβ on push/PRrust-security-suite.ymlβ on push/PRformal-verification.ymlβ on push/PR (path-filtered) + weekly
Coverage thresholds substantially improved: Python batch 1 raised to 80%, security gate raised to 85% and expanded from 7 to 14 modules, Rust enforcement added at 70%. Only pq_ratchet_beacon.py remains excluded from the security gate among secret-handling modules. General .coveragerc still has 0% threshold. For a crypto project aspiring to 95%+, further raises are recommended but the current levels are defensible.
- 55 Python modules in
meow_decoder/ - 10 Rust modules in
crypto_core/src/(excluding Verus files and wasm/hsm stubs)
| Module | Formal | Fuzz | Property | Unit | Coverage Gate |
|---|---|---|---|---|---|
crypto.py |
β ProVerif, TLA+ | β
fuzz_crypto |
β Hypothesis | β | β 80% |
crypto_backend.py |
β | β
fuzz_crypto_backend |
β | β | β 80% |
ratchet.py |
β TLA+, Tamarin | β
fuzz_ratchet |
β Hypothesis | β (145) | β 80% |
pq_hybrid.py |
β ProVerif, Tamarin | β
fuzz_pq_hybrid |
β Hypothesis | β | β 80% |
fountain.py |
β TLA+, Lean | β
fuzz_fountain |
β Hypothesis | β | β 70% |
frame_mac.py |
β | β | β Hypothesis | β | β 80% |
constant_time.py |
β | β | β | β (46) | β 80% |
schrodinger_encode.py |
β Tamarin | β
fuzz_schrodinger |
β | β | β 85% (NEW) |
memory_guard.py |
β | β
fuzz_memory_guard Γ 2 |
β | β | β 85% (NEW) |
manifest_signing.py |
β ProVerif | β
fuzz_manifest_signing |
β Hypothesis | β | β 85% (NEW) |
x25519_forward_secrecy.py |
β Tamarin | β
NEW fuzz_x25519_fs |
β | β | β 85% (NEW) |
master_ratchet.py |
β TLA+ | β
fuzz_master_ratchet |
β | β | β 85% (NEW) |
encode.py / decode_gif.py |
β TLA+, ProVerif | β | β | β | β 70% |
aead_wrapper.rs |
β
fuzz_aead |
β NEW proptest | β | β 70% (NEW) | |
secure_alloc.rs |
β
fuzz_secure_alloc |
β | β | β 70% (NEW) | |
pure_crypto.rs |
β | β
fuzz_pure_crypto |
β proptest | β | β 70% (NEW) |
nonce.rs |
β | β
fuzz_nonce |
β NEW proptest | β | β 70% (NEW) |
MEOW_TEST_MODE=1is set in all CI environments.- Argon2 test preset: 32 MiB, 1 iteration, 1 thread.
- Production "paranoid" preset: 512 MiB, 20 iterations, 4 threads.
- Production guard in
crypto.py:if _PRODUCTION_MODE and not _TEST_MODE: raise RuntimeErrorβ prevents accidental production execution without Rust backend. - Consequence: Production-strength Argon2 (512 MiB, 20 iter) is never exercised in CI. Only the test preset runs.
- Assessment: Acceptable for CI speed. The KDF is a well-tested primitive; the risk is configuration, not algorithm. The preset selection mechanism itself is tested in
test_fail_closed_enforcement.py.
meow_decoder/_archive/β excluded from coverage, no imports from production code.meow_decoder/*_DEBUG.pyβ verbose debug variants, excluded from coverage.crypto_core/src/hsm.rs,tpm.rs,yubikey_piv.rsβ hardware integration stubs, excluded from tarpaulin.crypto_core/src/wasm.rsβ WASM bindings, excluded from tarpaulin.
| Category | Score | Weight | Notes |
|---|---|---|---|
| Formal Verification | 7.5/10 | 30% | Excellent breadth; Verus now honestly labeled |
| Fuzzing | 9/10 | 25% | 22 Python + 9 Rust targets, CI-gated; 3 new harnesses |
| Property-Based Testing | 9/10 | 15% | Hypothesis + proptest; crypto_core gap closed (15 tests) |
| Coverage Enforcement | 8/10 | 15% | Python 80%/85%, Rust 70% β all enforced |
| Test Quality & Meta | 8/10 | 15% | Meta-tests, negative tests, mutation testing |
No, but the primary blockers are significantly reduced. Remaining items:
- Verus Z3 not running β Still grep-only, but now honestly documented. The CI job and documentation no longer overclaim. Installing the full Verus toolchain in CI would raise this to 10/10 for formal verification honesty.
- AEAD-005β012 vacuous lemmas β Research-level gap (acknowledged RL-1). These abstract lemmas have preconditions that subsume postconditions.
- Lean open items β 1 approved sorry (API incompatibility) + 2 textbook axioms. Acceptable for a crypto project.
- Coverage could be higher β 80%/85%/70% is defensible but below the 95%+ ideal for high-assurance crypto.
The 6 most actionable gaps have been closed: Verus claims are accurate, coverage is enforced across Python and Rust, crypto_core has property tests, and 4 previously-unfuzzed security modules are now fuzzed. The remaining gaps (Verus Z3, Lean axioms, statistical CT) are either research-level or honestly documented.
The prior test-formal-fuzz-audit-results.md (dated 2025-07-15, claiming 10/10) contained the following factual errors:
- Row 4 ("Verus AEAD/KDF proofs are stubs β FIXED"): The Verus CI Dockerfile still performs grep-based structural analysis only. No Z3 invocation was added. Remediation: Dockerfile and CI job now honestly labeled as structural regression tracking;
SECURITY_INVARIANTS.mdVerus rows downgraded toβ οΈ STRUCTURAL. - Row 11 ("Rust coverage not gated β FIXED"):
fail_ci_if_error: truewas added, but this gates the Codecov upload, not a coverage percentage threshold. Remediation: Explicit 70% threshold enforcement added via tarpaulin output parsing. - "30+ real
verus!{}proofs":verus_proofs.rsheader explicitly states "noverus!{}blocks exist in this file." Theaead_wrapper.rsfile contains approximately 1verus!block, not 30+. Remediation: Claims now match reality.
| Fix | Files Modified |
|---|---|
| Verus CI honesty | formal/Dockerfile.verus, .github/workflows/formal-verification.yml, docs/SECURITY_INVARIANTS.md |
| Rust coverage threshold | .github/workflows/rust-test-coverage.yml |
| Security coverage gate expansion | .coveragerc-security (7 β 14 modules) |
| crypto_core proptest | crypto_core/tests/property_tests.rs (15 tests, all passing) |
| Missing fuzz harnesses | fuzz/fuzz_x25519_fs.py, fuzz/fuzz_timelock_expiry.py, fuzz/fuzz_forensic_cleanup.py, .github/workflows/fuzz.yml |
| Python coverage thresholds | .github/workflows/ci.yml (70β80%, 80β85%) |
End of audit report (post-remediation).