Skip to content

EPIC S2 standing: Provable Contracts (PVL-001) #2870

Open
19 of 19 issues completed
Open

Description

@noahgift

Spec: APR-EPIC-001 §2 · Epic: S2 · Train: standing · Successor at cut: —
Owner: aprender-w5382 (re-owned 2026-10-19 by aprender-triage-worker at the cop's word: previous owner session absent; picks up children only as batch constituents after its current timed task)

Theme

Provable Contracts (PVL-001)

done_when

Lean/Kani run in required contexts; bindings resolve; L4/L5 have one definition.

Budget

At most 3 open children (docs/roadmaps/epics.yaml). Repo-wide cap 100 open issues; andon at 95.

Absorbs

#2556, #4080, #4081, #4082, #4083, #4084, #4122, #4139, #4166, #4168, #4197, #4198, #4199, #4200, #4201, #4202, #4238, #4239, #4240, #4241, #4244, #4347, #4351

Prior body

Audit of the provable-contracts system in this tree together with its archived upstream
(paiml/provable-contracts). Full plan drafted as
docs/specifications/improve-provable-contracts.md (PV-IMPROVE-001, PR to follow); this
issue is the tracking ticket for it.

Reference HEAD: origin/main @ b1a6324b8 (v0.65.2, 2026-09-05). Every number below was
measured on a detached worktree of that commit with a pv 0.65.2 built from it by cargo
(scripts/pv_bin.sh doctrine) — not the pv on PATH.

The finding in one line

The measurement half (pv lint, pv score, pv proof-status, the README count) reports
PASS, a grade and a proof level for 1,807 YAML files. The enforcement half (build.rs →
#[contract], pv codegen → call sites, Kani, Lean) enforces almost nothing, and every
layer of it reports success while doing so.
Most pieces are already filed (#2699, #2797,
#2557, #2648, #2704, #2630, #2530); what is missing is the ordering and the honest baseline.

Measured ledger

Claim surface Declared Discharged / real
pv lint contracts/ 0 errors, 1082 warnings, PASS score gate threshold is 0.00; warnings cannot fail it
pv score (with aprender binding) — mean 0.48 Grade D; A 62 · B 57 · C 516 · D 362 · F 761
pv proof-status levels (1,800) — L1 1,073 · L2 295 · L3 400 · L4 28 · L5 4
Lean-proved obligations 181 8 of 639 lean_theorem refs resolve to a theorem in aprender-contracts-staging/lean/ (417 theorems, 4 sorry). The rest come from hand-typed verification_summary.l4_lean_proved integers, which proof_status.rs::is_lean_proved trusts over the scan whenever > 0 (36 contracts self-report 159)
Kani harnesses 1,257 entries (1,162 distinct harness: names) 84 #[kani::proof] fns exist in source; 47 overlap; actually_verified (#1595) set on 0; cargo kani in no workflow
Lean build — no lake build anywhere in CI/Makefile; .lake/build dated 2026-03-21; lakefile.lean requires mathlib from git master
#[contract("…")] sites (non-doc) 10 10 / 10 name a contract YAML that does not exist (forward-pass-v1, sampling-v1, gemm-v1, softmax-v1, color-wcag-v1, rect-geometry-v1, constraints-layout-v1, facade-compat-v1) → option_env! is None → nothing injected. macros/src/lib.rs:26 still says env!() / "compile error" (#2699 open)
generated_contracts.rs 25 files, 379,866 lines (6 byte-identical) aprender-core: 1,007 pre + 326 post macros, 1,991 empty () => {{}} arms, 696 debug_assert!; assertion vocabulary ≈ 95 % len() > 0 / is_finite()
Enforcement call sites (non-generated) 478 pre + 210 post = 688 329 (48 %) are contract_pre_x!() with no argument, which expands to {{}} — produced by pv kaizen --fix's first-identifier heuristic
PV-ENF-001 auto-fix text — proposes !input.is_empty() (107×) and result.len() > 0 (808×) — the placeholders the upstream spec §30 diagnosed as "catches nothing"
falsification_tests[].test 2,704 fields 210 are cargo test invocations (190 resolve); 2,474 are prose; Gate 4 counts 26
Binding registries for aprender — two (contracts/binding.yaml 99, contracts/aprender/binding.yaml 172) + a third upstream (125); 227 / 3,086 bound (7.4 %); one-directional (#2797)
verification_summary 355 contracts carry it 17 have total_obligations ≠ len(proof_obligations) (#2648)
Provability denominator "1,807 provable contracts" pv holds 343 (kind: kernel) to the chain; 481 root kernel-kind files self-exempt via registry: true (#2557); 306 are zero-obligation contracts/work/ tickets; 429 apr-page-* manifests; 52 in v1-legacy-skip/
Proof ladder — three numberings: upstream verification-ladder.md (L4 Kani, L5 Lean), aprender-spec.md §2 (same), proof_status.rs:20-40 (L3 Kani, L4 Lean, L5 Lean+bound)
Doc drift — CLAUDE.md:23 says 1,768 (README 1,807); crates/aprender-contracts/README.md says 0.29 / "968 files" / "405 contracts across 70 crates"; staging pv-spec.md §1 cites crates/provable-contracts/, 40 repos, "Grade B"

The upstream is archived and still being edited

  • paiml/provable-contracts is archived on GitHub (last push 2026-04-06).
  • The local clone at ../provable-contracts is on main @ 31791c3 with two commits dated after the archive (68a317d L5 binding fix, 31791c3 bashrs SEC002) plus an uncommitted 28-line edit to contracts/manzana/binding.yaml. None can be pushed. contracts/bashrs/safety-classifier-v1.yaml differs from our copy; contracts/manzana/ does not exist here.
  • 47 of the 144 shared kernel contracts differ byte-wise; 58 library src/ files differ; ContractKind has 5 variants upstream vs 13 here.
  • crates/aprender-contracts-staging/ is not a crate — it is a vendored snapshot (book/, mermaid.min.js 2.6 MB, generated/, proof-status.json) that also happens to hold the only Lean tree. proof_status.rs still falls back to ../provable-contracts/lean.
  • 10 generated .pv/ cache files are tracked in git (Epic: pv / provable-contracts hardening — the tool that decides release soundness #2556 housekeeping).

Root cause (five whys, condensed)

The system was built to maximize a score (PMAT-082 mass generation, kaizen penetration, the
README count gate) and the score was allowed to be declared rather than derived. Every
row above follows: hand-typed proof counts are trusted, every silent path (option_env!,
COUNT missing ≡ 0, unparseable predicate ≡ skip, empty macro arm) was written to be
"graceful" for a crates.io stranger and is silent for us, and a count that a gate defends
gets inflated.

Proposed sequencing (detail in the spec)

Phase 0 — tell the truth (no shipped-code change). One ladder; pv validate errors on
summary-count drift; proof_status credits only resolving harnesses/theorems (expect
181 → 8 Lean, L4/L5 to single digits — this is the honest baseline); README headline
becomes three derived figures behind a floor (closes #2630); port the stranded upstream
edits, remove the ../provable-contracts fallback, untrack .pv/; pv lint becomes its own
CI step with a shrink-only warning baseline (1,082) and --min-score 0.48.

Phase 1 — enforcement that can fail. Close #2699 in full (exported contract_env_key,
generated registry include! instead of env vars, compile_error! on missing/unparseable,
explicit optional); repoint the 10 dangling #[contract] sites; codegen drops the
() => {{}} arm so the 329 empty call sites become compile errors; PV-ENF-003 vacuous-predicate
lint and no more !input.is_empty() auto-fix text; one scoped generated_contracts.rs per
crate (< 30 k lines total); one aprender registry, pv verify-bindings --both-ways in CI
(#2797), superseded + D5 "not measured" (#2704).

Phase 2 — proof credit only from receipts. PV-KANI-001 (every harness: must exist;
shrink-only baseline for the 1,115 dangling) + KaniStrategy::symbolic_float (#2530);
kani-nightly.yml writes receipts and D3 credits only receipts; pin mathlib, lean-nightly.yml
writes receipts, PV-LEAN-001 (delete the 631 inert refs in one PR); remove the registry: true
exemption (#2557) and add kind: descriptor for data-only YAML; test: must be executable
(prose → prediction:), so Gate 4 counts all refs instead of 26; then ratchet --min-score.

Phase 3 — corpus scope. contracts/work/ → .pmat-work/; delete/migrate
v1-legacy-skip/; fleet dirs → contracts/fleet/ (decision D-3); resolve the 48 baselined
duplicate stems; collapse the staging dir to lean/ and rewrite the spec copy for the
monorepo.

Phase 4. Course repo design-by-provable-contracts (installs aprender-contracts-cli
from crates.io) added to the release dogfood lane; fail-closed fixture suite for every gate.

Each item ships with a committed mutant that must be seen RED (FALSIFY-PVI-001..018 in the
spec), per the existing "guard's own case table must pass before it judges" convention.

Decisions needed

ID Decision Recommendation
D-1 Which ladder numbering survives upstream / aprender-spec (L4 Kani, L5 Lean); change proof_status.rs, not the docs
D-2 Descriptive YAML: kind: descriptor in place, or a manifests/ tree in place for one release, then move
D-3 Fleet contracts/<repo>/ dirs stay here or move to each repo stay, under contracts/fleet/; four siblings already went in-repo, pv kaizen should accept both
D-4 Nightly lake build with pinned mathlib on clean-room runners, or drop L5 credit pin and run; without a receipt D4 credit is theater (phase 0 already zeroes it)
D-5 Delete vs keep 631 dangling lean_theorem refs / 1,115 dangling harness: names delete in one PR each; re-add only with evidence

Ticket map

Issue Phase item Disposition
#2556 all this is the sequenced plan for the epic
#2699 1.1 closes
#2797 1.6 closes
#2557 2.4 closes
#2648 0.2 closes (option b), option a next minor
#2704 1.6 closes
#2630 0.4 closes (floor now, derived headline after)
#2530 2.1 closes
#2512 — already wired at ci.yml:957; close with a pointer
#1595 2.2 superseded by receipts; field removed
#673 0.3 re-measure under discharged credit

Repro

git worktree add --detach /tmp/apr-main origin/main && cd /tmp/apr-main
CARGO_TARGET_DIR=/tmp/apr-target cargo build --release -p aprender-contracts-cli --bin pv
PV=/tmp/apr-target/release/pv
$PV lint contracts/ | tail -4                                   # 0 errors, 1082 warnings, PASS
$PV score contracts/ --binding contracts/aprender/binding.yaml | grep Mean
$PV proof-status contracts/ --binding contracts/aprender/binding.yaml | grep -E '^Totals|^By kind'
grep -rhoE '^\s*#\[contract\("[^"]+"' crates --include='*.rs' --exclude-dir=target | sort | uniq -c
grep -c '() => {{}};' crates/aprender-core/src/generated_contracts.rs   # 1991
gh repo view paiml/provable-contracts --json isArchived                   # true

Refs #2556. Related: #2699 #2797 #2557 #2648 #2704 #2630 #2530 #2512 #1595 #673.

Parked

Closed over budget (APR-EPIC-001 rule 5). Reopen = pull (rule 7).

Superseded epics

Children tracked here (REDUCE-1022)

Activity

  1. 26 remaining items

  2. modified the milestones: 0.72.0, 0.73.0 on Oct 14, 2026
  3. noahgift commented on Oct 19, 2026

    @noahgift
    MemberAuthor

    Triage evidence 2026-10-19 17:15Z: all children named for this epic are closed: #4122 #4080 #4348. The epic body lists no open child issue. Owner label is owner:aprender-df. Closing is left to the owner.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High priorityautomationBot-maintained dashboard, not a defect — skip in triageepicEpic — multi-story umbrellaowner:aprender-dfOwned by session aprender-df

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions