formal(dlv): binding value continuity — the temporal property the binding register does not enforce - #899
Merged
Conversation
…ister does not enforce A raw-transport probe showed a chosen binding value can be REPLACED: an honest client drove A to Committed, then a second client bypassed QuorumBind, read the records, and raw-CAS'd a different value at a higher round to every member; honest Class K then reported BoundFinal on the attacker's value. This module states the property that failure violates, and proves the failure: Chosen(K, A, t1) and Chosen(K, B, t2) with t1 < t2 => A = B It models the shipped member-side rule (byte-identical replay; else exact expectation plus a strictly greater round; then ANY value) and machine-checks the counterexample over a concrete run. It also re-proves the snapshot property in the same model, so this cannot be read as contradicting DSMLineageQuarantine's one_read_cannot_show_two_chosen_values — that theorem is about ONE read and remains correct. The gap is temporal, not arithmetic. ValueContinuity is a definition, not a theorem: no mechanism enforces it yet, and an unproved target is an obligation, never a stubbed proof. No sorry, no axiom, no opaque; the three concrete runs depend on no axioms at all. Mutation control: restricting the higher-round branch to require prior.value = replacement.value makes the kernel prove BOTH counterexample theorems FALSE. Reverted from a byte copy. Lean gate 23 -> 24.
cryptskii
added a commit
that referenced
this pull request
Sep 17, 2026
main added DSMBindingValueContinuity.lean (#899) and set the lean job count to 24; with DSMSofiSuccessorCells and DSMSofiAtomicity the tree has 26. The CI count and the README count are set to 26. The two SoFi modules are unchanged.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
One new Lean module,
lean4/DSMBindingValueContinuity.lean, plus the Lean gate count. No Rust changes.A raw-transport probe on 2026-09-15 showed that a chosen binding value can be replaced. An honest client drove
AtoCommitted; a second registered client then bypassedQuorumBindentirely — no prepare, no adoption of the accepted value — read the records, built a different value at a strictly higher round under its own proposer id, and issued rawCompareExchangeManyto every member. Applied 3/3. Honest Class K then reportedBoundFinalon the attacker's value.This module states the property that violates, and proves the violation:
Why it is a new theorem and not a broken one
DSMLineageQuarantine.one_read_cannot_show_two_chosen_valuesis a snapshot property — two strict-majority sets cannot be disjoint within one read — and it remains correct. The attack establishesA, then establishesBat a later time. The gap is temporal. To keep the two from ever being confused, this module re-proves the snapshot property in its own model alongside the counterexample.What it contains
applyCas— the shipped member-side rule: byte-identical replay is idempotent; otherwise the caller must still hold exactly what it expected and supersede it with a strictly greater round; then any value is written. That last omission is the defect.a_higher_round_raw_cas_can_choose_a_different_value— the counterexample, by computation.one_read_cannot_show_two_chosen_values— the snapshot property, preserved.ValueContinuity— a definition, not a theorem. No mechanism enforces it yet, and an unproved target is an obligation, never a stubbed proof.Faithfulness to the shipped code:
roundLtis lexicographic counter-then-proposer, matching the derivedOrdwhose own comment calls that field order load-bearing;chosenmirrors the documented rule thatqmembers hold ACCEPTED at one exact round.Verification
lean -DwarningAsError=true lean4/DSMBindingValueContinuity.lean— exit 0.propext/Quot.sound. NosorryAx.prior.value = replacement.valuemakes the kernel prove both counterexample theorems FALSE — the strongest grade, not merely a broken proof. Reverted from a byte copy,cmpclean, recompiled.expected=23->24, matchingls lean4/*.lean | wc -l.Scope
No repair is proposed here. The mechanism is deliberately kept out so a partial fix cannot narrow the defect, and the storage node stays application-blind either way.