Skip to content

proof(#2080): naming-invariant param-load disjointness contract seam#2117

Merged
Th0rgal merged 3 commits into
paloma/issue-2080-function-exec-withinternalsfrom
paloma/issue-2080-selector-dispatch-withinternals
Jul 7, 2026
Merged

proof(#2080): naming-invariant param-load disjointness contract seam#2117
Th0rgal merged 3 commits into
paloma/issue-2080-function-exec-withinternalsfrom
paloma/issue-2080-selector-dispatch-withinternals

Conversation

@Th0rgal

@Th0rgal Th0rgal commented Jul 7, 2026

Copy link
Copy Markdown
Member

Base / dependency (stacked)

Summary

Threads the L2 param-load prefix-disjointness fact through to the selector-dispatch consumer seam, reducing reliance on conservative-extension / default-empty helper-world wrappers.

  • IRInterpreter.lean: add InternalTableNamesInternalPrefixed (contract invariant: every internal-table entry's name carries the internal_ prefix) and findInternalFunction?_eq_none_of_not_internalPrefixed (a non-prefixed name never resolves in the internal table).
  • Function.lean: prove genParamLoads call-disjointness from the internal table out of per-builtin findInternalFunction? = none facts (genScalarLoad / genParamLoadBodyFrom recursion + minInputSizeCheck), then package it as genParamLoads_callsDisjoint_of_internalNamesPrefixed, which supplies those facts from the naming invariant via by decide on each builtin's non-internal_ prefix.
  • Contract.lean: add compileFunctionSpec_correct_generic_with_helper_proofs_and_helper_ir_of_body_goal_of_internalNamesPrefixed — same premises as its _of_body_goal sibling except it discharges the hparamDisjoint premise from InternalTableNamesInternalPrefixed (param supportedness comes from SupportedSpec via supported_params_of_supportedSpec). Each per-function obligation now feeds straight into execIRFunctionWithInternals without an opaque disjointness witness.

The naming-invariant route (rather than internalFunctions = []) is deliberately forward-compatible with non-empty helper tables — the direction #2080 wants to move.

Validation

All run via lean-slot (host-wide gate, Spark offload), from verity/:

  • lean-slot lake build PrintAxiomsBuild completed successfully. Whole-tree axiom gate (PrintAxioms imports every top-level theorem to #print axioms); Contract.lean's new theorem and all downstream modules compile. Every printed axiom is standard (propext, Classical.choice, Quot.sound) — no sorryAx.
  • Individual green builds this slice: IRInterpreter, Function, Contract.
  • python3 scripts/generate_print_axioms.py --checkOK: PrintAxioms.lean is up to date.
  • python3 scripts/check_proof_length.pypassed (the signature-dominated wrapper is allowlisted with justification; body is a single term application).
  • git diff --check → clean.
  • No new sorry / admit / axiom in any touched proof file.

Next slice (not in this PR — kept narrow)

Whole-contract dispatch integration: establish InternalTableNamesInternalPrefixed for the compiled runtime contract from the compilation pipeline, and supply the per-function body-preservation goal, so the whole-contract theorem consumes this seam across all selector-dispatched functions and fully retires the default-empty helper-world wrapper.

Refs #2080


Note

Low Risk
Lean proof-only changes with no runtime or auth logic; risk is limited to proof maintenance and axiom/theorem registration consistency.

Overview
Adds a forward-compatible proof path so genParamLoads ABI prefix code cannot collide with internal helpers when the runtime table is non-empty, as long as every helper name carries the internal_ prefix.

IRInterpreter: introduces InternalTableNamesInternalPrefixed and findInternalFunction?_eq_none_of_not_internalPrefixed so non-prefixed names (EVM/Yul builtins) never resolve in the internal table.

Function: proves genParamLoads call-disjointness from per-builtin findInternalFunction? = none lemmas, then packages it as genParamLoads_callsDisjoint_of_internalNamesPrefixed using the naming invariant.

Contract: adds compileFunctionSpec_correct_generic_with_helper_proofs_and_helper_ir_of_body_goal_of_internalNamesPrefixed, mirroring the existing _of_body_goal wrapper but replacing opaque hparamDisjoint with InternalTableNamesInternalPrefixed (param support from SupportedSpec).

Tooling: registers new theorems in PrintAxioms.lean and allowlists the long signature-only contract wrapper in check_proof_length.py.

Reviewed by Cursor Bugbot for commit 5759254. Bugbot is set up for automated code reviews on this repo. Configure here.

Th0rgal added 3 commits July 7, 2026 18:04
Introduce InternalTableNamesInternalPrefixed and
findInternalFunction?_eq_none_of_not_internalPrefixed: a name that is not
internal_-prefixed cannot resolve to any helper when the runtime contract's
internal table satisfies the naming invariant. Forward-compatible replacement
for the internalFunctions = [] disjointness route.

Refs #2080
…nvariant

Prove that the ABI parameter-load prologue emitted by genParamLoads (the
min-input-size guard plus the per-param scalar loads) is disjoint from a runtime
contract's internal-function table whenever the table satisfies
InternalTableNamesInternalPrefixed. The six EVM/Yul builtins it emits
(calldataload, calldatasize, lt, revert, and, iszero) are not internal_-prefixed,
so none can resolve to a helper. Replaces the internalFunctions = [] route with a
naming-invariant route that survives non-empty helper tables.

Refs #2080
… seam

Add compileFunctionSpec_correct_generic_with_helper_proofs_and_helper_ir_of_body_goal_of_internalNamesPrefixed,
which discharges the genParamLoads prefix-disjointness premise of its
_of_body_goal sibling from the runtime contract's InternalTableNamesInternalPrefixed
naming invariant instead of taking it as an opaque hypothesis. This is the
selector-dispatch consumer seam that lets each per-function obligation feed
straight into execIRFunctionWithInternals.

Regenerate PrintAxioms.lean and allowlist the signature-dominated wrapper.

Refs #2080
@vercel

vercel Bot commented Jul 7, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
verity Ready Ready Preview, Comment Jul 7, 2026 4:25pm

Request Review

@cursor

cursor Bot commented Jul 7, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_842b1df5-9db6-4d04-8612-c99cb1c86fbf)

@Th0rgal Th0rgal merged commit c91e212 into paloma/issue-2080-function-exec-withinternals Jul 7, 2026
21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant