Skip to content

proof-debt: paths-forward proposal for the remaining 268 OWED stubs (post-overly-cautious sweep) #119

@hyperpolymath

Description

@hyperpolymath

Where we stand

After today's proven#107 "overly cautious OWED" sweep (19 PRs, up to ~40 OWEDs discharged), 268 ^0 -erased OWED stubs remain across 40+ Safe* modules. This issue triages the remaining surface by upstream-dependency and recommends concrete next steps.

Distribution by blocker family

Per the tier-a triage + today's hunt, the residual breaks down as:

Blocker family Approx count What would unblock
String FFI opacity (unpack/pack/length/isInfixOf/prim__eq_String) ~120 Upstream Idris2 reflective Data.String bridge OR refactor String parameters to List Char
Char FFI opacity (prim__eq_Char/prim__lte_Char/isAlpha/isDigit/ord/chr) ~35 Upstream Idris2 reflective Data.Char bridge OR refactor to enum types
Nat div/mod opacity (Integral Nat instance) ~20 Upstream Data.Nat.Division reflective tactic OR refactor to Bits32
Bits opacity (xor/shiftL/shiftR/.&./`. .`) ~15
Covering-not-total reduction (covering functions stuck on abstract args) ~12 Refactor specific functions to total (some are inherently covering — e.g. gcd)
External library / KDF / FFI binding (Argon2, bcrypt, OpenSSL, randomBytes) ~12 Stay OWED-AXIOM — permanent. Just need a once-per-version audit.
if/case head substitution + Nat-Bool-Prop bridges ~30 Could be unblocked with a Bool->Dec reflective bridge OR significant manual case-split scaffolding
Double / IEEE-754 equality ~6 Upstream Idris2 Data.Double reflective tactic OR property-test path
List-Prelude lemmas not exposed (mapId/filterAll/etc.) ~12 Add helper lemmas to proven-side lib/ (one-off PRs)
Visibility / structural / other ~6 Various per-site fixes

Three paths forward — owner decision needed

Path A — wait for Idris2 0.9.0

Status: 0.9.0 is not released yet (asdf list-all idris2 ends at 0.8.0). No public ETA found.

Pros: zero work this side. The estate-wide bump would auto-unlock the Char-FFI and (with luck) the case-eta + Nat-< blockers cited in tier-a doc's "DISCHARGE-after-Idris2-upgrade" rows.

Cons: out of our control. Cannot estimate ROI without seeing 0.9.0's release notes.

Path B — write reflective bridges to proven/lib/

Build domain-specific reflective tactics that bypass the FFI opacity:

  • Data.Char.ReflecteqCharRefl : (c : Char) -> c == c = True for LITERAL chars by case-table generation
  • Data.String.ReflectunpackRefl : unpack "abc" = ['a','b','c'] for LITERAL strings
  • Data.Nat.ReflectdivRefl : div 100 1 = 100 via Data.Nat.Division.divNatNZ-driven rewrite

Pros: unblocks the largest fraction (~155 OWEDs) without waiting for upstream. Lives in proven/lib/ so doesn't burden consumers.

Cons:

  • Non-trivial Idris2 metaprogramming work (~5-15 hours per bridge).
  • Easy to accidentally introduce believe_me (banned by llm-warmup-dev.md policy).
  • Reflective code may break with Idris2 0.9.0 upgrade.

Path C — refactor specific modules to enum / bounded types

Replace Char with data SafeChar = SCh0 | ... | SCh9 | SChA | ... | SChF for the SafeHex-class modules. Replace String with List Char (or a parameterised Vect) for narrow APIs. Stays in scope per-module.

Pros: zero believe_me, no waiting on upstream, immediate per-module discharge.

Cons:

  • API-breaking for binding consumers (Rust/Zig/Deno bindings would need to marshal).
  • Estimated 1-2 days per module to refactor + re-prove + re-bind.
  • Doesn't generalise — each module's refactor is bespoke.

Recommendation

  • Defer Path A — track Idris2 0.9.0 release; no action this side until then.
  • Try Path B small — file one prototype tracking issue for Data.Char.Reflect only; if it pans out without believe_me, expand.
  • Skip Path C unless a specific module is critical-path for an external consumer (e.g. SafeUrl Bindings or SafeRegex shipping to opam).

What today's session DID clear

Cross-references

  • This session's discharge campaign: proven#107
  • Phase 3 umbrella: proven#90
  • Tier-a per-site doc: docs/proof-debt-triage-tier-a.md

Refs #90 #107

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions