Lean clarity record¶
As a reader of current permanent contract, I can register a fresh key and terminate it permanently.
The active model and compiled state support exactly tags 1 (insertActive) and
3 (updateTerminal); tags 0, 2, 4, 5 and 6 are explicitly refused, including
caller-constructed and mixed requests. Application payload maintenance is separate.
Current sources and receipts must be bound to the revised candidate.
The detailed walkthrough and measurements below are archived broader model evidence,
retained to explain the earlier contract; their broader success claims do not apply
to permanent contract. Historical sources are retained on preserve/m2/pre-m1-source-removal.
The active theorem manifest and
the exact scope-retirement record
explain the changed law and denominator. Unmet consumer requirements stay uncovered.
Archived broader model evidence¶
A proof is only worth what its statement says. This page reads the registry-mode model back in English — what each promise actually quantifies over, what it assumes, and where the reader should not take it further than it goes — so that "proved" can be checked against "promised" without reading Lean.
The statements themselves, with their digests, are in the theorem manifest. This page is about their meaning.
Who this is for¶
A reviewer deciding whether the model is the right model. The build already answers are these proved — every one is, from the standard axioms and nothing else. It cannot answer do these say what the interface promised, and that is the question this page exists to make answerable.
What is bound¶
| Artifact | SHA-256 |
|---|---|
Model.lean |
538b204c10ad8ac96bc90d88af83fd90195418dd2499e53bd4dde22bed672d9d |
Lemmas.lean |
7ac8c9b77c8b894a119595a79a51494de57c323f36a3705c3a949ef08d8b9948 |
Statements.lean |
6db05532db8e26f9102106f5a05540b1bb0b5dec4624b0d49e57f8f16b69ce00 |
Audit.lean |
2ef1e8f78746b0c91267729b20633b1deab774ded5c12538a1295f5aa1597e6b |
Main.lean (corpus generator) |
1b5b4526acd54eb8ab6d233dad20a44e178272d60d9f30776155c787d4d6717b |
corpus.json |
c07e5fdade5a52868ee0f94200b4589af30ea66807d54622a2e1dbdff172ceff |
Every one of these ships beside the page under simulator/formal/, and
node simulator/mirror-check.mjs fails if the shipped copy and the built copy
differ, in either direction. Changing any bound input invalidates this record.
The readback below covers the eleven promises, the seven inversions, the deposit, the read and the fold. The registry module bound above also carries fifteen later statements — about when a pending request may be retracted and what a refused retraction is told, what every exit pays and to whom, and which datum a delivered or spent witness carries, and how a batch of one folds — that are listed in the theorem manifest and not yet read back here.
The shape the promises are made over¶
flowchart TD
G["genesis"] -->|"accepted fold"| S["Reachable state"]
S -->|"accepted fold"| S
S --> INV["Consistent:<br/>root commits the map ·<br/>supply laws ·<br/>custody soundness"]
INV --> A["what the promises are proved about"]
ARB["an arbitrary RegistryState value"] -.->|"not reachable"| X["supply laws are simply false here"]
Almost every promise is stated over reachable states — genesis, closed under accepted folds — and not over arbitrary values of the state type. This is not a weakening dressed up as a hypothesis: over an arbitrary state value the supply laws are false, because nothing stops you writing down a state with three active tokens for one key. Reachability is what makes them true, and it is exactly the property a chain enforces by only ever arriving at a state through a fold.
Where a promise does not need reachability, it does not assume it. The seven
inversions, the empty-batch refusal, the fold-cons equation and
read_changes_nothing are proved over any state at all, because they are
statements about what an accepted edge did, not about what the ledger holds.
Reading the promises back¶
No tree change without approval (no_tree_change_without_approval). If a
request is accepted and it is not the read, then an approval was present, it was
minted under the registry's own pinned policy, its asset name is the hash of the
edge, the key, the owner and the destination of this request, and the
registry's own pins — its policy, its owner, its recovery commitment — are
unchanged by the fold. The part worth dwelling on: a correct policy is necessary
and not sufficient. An approval minted for a different key, or a different
destination, under the very same policy, does not admit the request. A model
that checked only the policy would be wrong in a way no amount of proving would
reveal, which is why the tuple appears in the statement rather than in a comment.
Booked at most once (booked_at_most_once). A batch is a fold, and the fold
spends each request once, in order. The statement is about the step function,
so a request cannot be applied twice within one batch, and a batch that fails
anywhere produces no state at all rather than a partial one.
Soundness of attestation (terminal_attestation_sound). In a reachable
state, a terminal attestation exists for a key only if that key's leaf really is
terminal. Its companion (terminal_mint_only_by_read) supplies the provenance
half: the only edge that can bring a terminal token into existence is the read.
Together they say the witness cannot be forged and cannot be minted by a state
change.
Permanence (terminal_attestation_permanent). What a terminal attestation
says stays true through any later sequence of accepted folds. A terminal leaf
has no outgoing edge, so nothing downstream can make an already-issued
attestation false. This is the promise that lets a holder keep the witness
rather than re-reading the chain.
The supply law (biconditional_supply_sync). For every key in a reachable
state, the count of outstanding active tokens is one exactly when the leaf is
active and zero otherwise — a biconditional, both directions, over all keys, not
only the key in hand. The same shape holds for the absent witness. This is the
statement that ties the token supply to the map and makes "the token is the
name" more than a slogan.
Occupancy and its converse (occupancy, occupancy_free_key_succeeds). A
booking edge succeeds only on a key that is not already taken; and on a key that
is free, with a matching approval, it does succeed. The converse matters as
much as the rule: a registry that refused everything would satisfy the first
half perfectly.
Termination (termination). On a terminal key every leaf-moving edge is
refused. Not "should be", not "by convention" — the refusal is the complement of
the edge table, so there is no unlisted case that quietly moves a retired name.
The four witness laws (active_witness_unique, absent_witness_unique,
terminal_witness_plural, witness_kinds_exclude). At most one active token
per key, and exactly one when the leaf is active. The same for the absent
witness. Terminal attestations, by contrast, are plural: any number may
exist, each is true, and minting another changes nothing — which is the
consequence of the attestation being a read. And the kinds exclude one another:
a key cannot have an outstanding active token and an outstanding absent witness
at the same time.
The seven inversions. For each edge, a single statement saying what an accepted application of it did: the leaf before, the leaf after, the new root, the token deltas, the custody movement, the deposit destination. These are the statements the simulator is really transcribing, and they are the ones to read first when asking whether the model matches the interface, because they contain no reachability hypothesis to hide behind.
The deposit (inside update_active_inversion and
delete_absent_inversion). The two edges that consume an absent witness pay the
deposit back to the refund address the original request named, not to the
output of the consuming request and not to whoever folded it. Those two rejected
destinations are the reason the statement pins the address rather than merely
asserting that some payment occurred.
The read (read_changes_nothing, witness_terminal_inversion). An accepted
read leaves the leaf, the root and custody exactly as they were and adds one
terminal token. It needs no approval at all — and, symmetrically, a stray
approval does not make it refuse.
The fold (empty_fold_error, fold_batch_cons). An empty batch is refused
rather than accepted as a no-op. A non-empty batch succeeds exactly when its
head applies and the rest applies to the result, which is what makes a batch
mean the same thing as the sequence of its requests.
What the model does not say¶
These are limits of the model, not gaps in the proofs. Each is a place where a reader could reasonably expect more than is there.
| Point | What the model does | What it does not claim |
|---|---|---|
| Keys and owners | integers, compared for equality | no string encoding, no address codec, no key derivation |
| Approvals | a value carrying a policy and a tuple | no signature is checked; minting authority is assumed, not verified |
| The deposit | a number that must arrive at a named address | not lovelace, no fee model, no minimum-UTxO arithmetic |
| The root | a fold over the map, recomputed | not the MPFS trie's own hashing; collision resistance is assumed |
| Retirement authority | the recovery commitment or a distinct-member quorum | the current control key alone never certifies it, and the model says so, but no signature scheme is modelled |
| Reachability | genesis closed under accepted folds | a chain that arrives at a state by any other route is outside every promise above |
| Validators | nothing | no compiled script, no ledger rule, no transaction is executed here |
The last row is the important one. Everything on this page is about a model. Whether the deployed validator implements it is a different question with a different kind of evidence behind it, and this page is not that evidence.
How much independence this record has¶
Stated plainly, because a reader cannot see it from the outside: the model, the corpus generator, the simulator transcription and this readback all have the same author.
That has a concrete consequence. A misunderstanding of the interface made while writing the model will be made again while transcribing it and again while reading it back, and none of the three will catch it — they are not independent measurements, they are one measurement repeated. What the internal machinery does catch is real but narrower: transcription slips (the corpus replay), statements that do not constrain what they appear to (the mutation record), unproved obligations (the compiled axiom check), and drift between the shipped Lean and the built Lean (the mirror check).
The check this record cannot perform on itself is the one that matters most — whether the statements say what the interface promised. That requires someone who did not write them. Treat this page as the author's best account, written to be falsifiable, and not as an audit.