Election leader completeness: an election in term t builds on every commit of an earlier term
ProvedOpenSearchSafety.inv_elcLet P satisfy P.InitCompatible and let W be a cluster with Inv P W. Suppose ElectionRecord P W L t bt bv x y J: bt < t, the configurations (x, y) realize the base key (bt, bv), J is a quorum of x and of y, and every member of J is an eligible node that sent L a join of term t whose last accepted term and version are Below bt bv. Then every committed key (ct, cv) with ct < t satisfies Descends W ct cv bt bv.
A node that wins term t from an accepted state, and the first publication of term t, whose parent is that state, build on every publication committed in an earlier term. The proof is a strong induction on t: a commit not below the base would have responders sharing a voter with J (through the pivot of the base and the configuration lineage, or P.InitCompatible when nothing is committed on the base's branch), and that voter accepted the commit before voting in term t (join_after_response), which places the commit at or below the base.
import Definitions.Def_OpenSearchSafety open OpenSearchCoordination OpenSearchSafety
theorem OpenSearchSafety.inv_elc {V : Type} (P : Params) (hP : P.InitCompatible) (W : Cluster V) (hinv : Inv P W)
(L : NodeId) (t bt : Nat) (bv : Int) (x y : VotingConfiguration) (J : List NodeId)
(hrec : ElectionRecord P W L t bt bv x y J) (ct : Nat) (cv : Int) (hc : Committed W ct cv) (hlt : ct < t) :
Descends W ct cv bt bv := by sorryRead-back
What the Lean code literally says, in plain math · claude-opus-5-5 (independent sub-agent, blind: Lean code + auditor instructions only)
Read-back: OpenSearchSafety.inv_elc
Notions used
Model and notation. Node ids are natural numbers. The parameters consist of an eligibility function (write for , " is cluster-manager-eligible"), a predicate on voting configurations (the bootstrap configurations; it may be empty or have any number of elements), and an election strategy . is the discovery node with id and cluster-manager flag .
A voting configuration is a strictly increasing list of node ids, so two configurations are equal exactly when they contain the same ids; is the empty one. For a list of node ids, " is a quorum of ", Lean c.hasQuorum q = true, means
i.e. strictly more than half of the members of occur in ; the order of , repetitions in and members of outside are irrelevant, and has no quorum at all.
A cluster state has a term , a version , a metadata version, a last committed configuration , a last accepted configuration , an optional cluster-manager id, two Boolean cluster-UUID flags, and a payload of the arbitrary type . A key is a pair ; the key of is .
A cluster consists of a coordination state for every natural number and a predicate on messages ("has been sent"); for an arbitrary the sent messages form an arbitrary, possibly infinite, set. Messages are of four kinds:
- , where a join consists of a source discovery node and a target discovery node (each an id and a flag), a term , a last accepted term and a last accepted version ;
- (Lean
.publishRequest src s pt pv), a publish request from node carrying the cluster state and the ghost parent key ; - , a publish response from node to node for the key ;
- , an apply-commit request with source discovery node and key .
A publication is a sent message ; its key is the key of and its parent is . In the model's steps, a node publishes , so the ghost parent is the publisher's accepted key at publication time; but the statements below are about arbitrary clusters satisfying the invariant, where only the invariant constrains .
For a node , read off its coordination state : its local discovery node; its current term; , , , the term, version, last committed and last accepted configuration of its last accepted state; its election-won flag; its started-join-since-last-reboot flag; and its last published version and configuration; and the node-id lists of its join votes and publish votes.
Committed keys. (Lean Committed W t v) holds iff some message has been sent, for some source discovery node . The definition alone does not require to be the key of a publication.
Parent and descent. holds iff some publication has been sent with : a publication of key whose ghost parent is . Descent, Lean Descends W t v t' v', written here and read " descends from " — the first key is the ancestor — is the least relation that is reflexive on every key and closed under appending a step: iff there is a chain with and for each . It is reflexive on every key, published or not; a key that is not the key of any publication has no ancestor but itself. "Proper" descent means between two different keys. For a publication write .
Auxiliary relations (over and ):
- : — the lexicographic order on keys.
- : — lexicographic, except that versions are not compared when both terms are .
- , for configurations (in the role of a last committed configuration) and (last accepted): either (i) , and , with unconstrained; or (ii) some publication has key , , and either or ( and ).
- , for a list of node ids: every has and there is a sent with , and .
- : the same, and moreover that join satisfies .
- : every has and has been sent for some node (any destination).
- : , , , is a quorum of and is a quorum of . The key is the base. (Since is a quorum of , and are non-empty; nothing requires to have won or published, nor the base to be published.)
- : , and either ( and ) or some publication from has .
The voter lists may be empty (the voter conditions then hold vacuously) and may contain repetitions.
Compatible bootstrap configurations. holds iff for all configurations with and (possibly ) and all lists of node ids whose members are all eligible: if is a quorum of and is a quorum of , then some node occurs in both and . For this holds automatically, so the condition only constrains pairs of distinct bootstrap configurations; it holds trivially when there is at most one bootstrap configuration.
The invariant is the conjunction of the following 30 fields (node variables range over all of ; "sent" means in ; is descent as above).
Every node :
localNode_eq: .idle_of_not_won: .won_started: .votes_started: .started_term_pos: .won_quorum: is a quorum of and of .not_won_no_quorum: is a quorum of and of .joinVotes_sent: every has , and some sent has , , and .publishVotes_sent: every has , and has been sent.
Every eligible node ():
term_le: .accepted_realizes: or .
Joins and publish responses:
join_wf: every sent has and .join_term_le: every sent with has .join_unique: two sent joins with the same source id, that source eligible, and the same term are equal (all five fields, so in particular the same target).join_after_response: for a sent and a sent with , and : .response_le: for a sent with : and .response_published: for every sent there is a sent publication from with key .
Publications — for every sent :
pub_wf: , , , , and .pub_parent: if , there is a sent with key such that (a) , or ( and ); and (b) .pub_unique: any two sent publications with the same key are the same message (same source, same cluster state in all fields, same parent).pub_rooted: for some .pub_same_term: for every sent with : or .pub_voters: some list with is a quorum of and of .pub_election: if , then for some configuration and list .
Commits:
commit_quorum: for every sent there are a sent with key and a list with , a quorum of , and either a quorum of , or ( and some sent publication of key has last accepted configuration ).
Leaders:
won_unique: .pub_source_term: for every sent : , or and ( or ).leader_pubs: if , every sent with (any source) has , , and a quorum of and of .leader_inflight: if and , then for some state : is sent, , , , and either , or (, and ).leader_settled: if and , then either ( and ), or ( and no sent publication has term ).
1. Declaration
Binders and hypotheses, in order:
- A type (implicit), parameters ,
hP: , a cluster over , andhinv: . - A node id , , , configurations , and a list of node ids.
hrec: , i.e. ; ; every is eligible and has sent a join for term whose last accepted (term, version) is the base ; and is a quorum of and of .- , , and
hc: . hlt: .
Conclusion.
Every committed key of a term below is an ancestor of, or equal to, the base of any election record for term .
Reading aids (consequences of the invariant, not part of the statement):
- With
inv_descends_key(a separate statement), the conclusion forces , and unless : every committed key of a term below has term at most . - If the base is a term-0 key. Under the invariant such a key has no proper ancestor (no publication has term , field 18) while every committed key has term (fields 25 and 18), so the conclusion cannot hold for any committed key; for such a record the statement therefore asserts that no key of a term below is committed.
2. What is not constrained
- The record is any tuple satisfying
ElectionRecord: need not have won, published or kept any votes, and need not contain all of 's voters. - The base need not be published (it may be a term-0 key), and enter only through
Realizesand the quorum conditions. - Committed keys with are not covered.
The hypotheses and . The statement is about every cluster satisfying the 30 fields, for any parameters whose bootstrap configurations are compatible (any eligibility function, any election strategy) and any payload type ; reachability is not assumed. The hypotheses are jointly satisfiable, so the statement is not vacuous on that account: InitCompatible holds whenever has at most one element, and every cluster in which no message has been sent and every node is in the state for some state of term with empty configurations (the model's Initial clusters) satisfies all 30 fields — fields 1, 2, 10 and 11 by direct check, field 7 because has no quorum, the rest vacuously. On such clusters the conclusion is trivial. That clusters with publications and commits satisfy the invariant is the subject of other stubs (reachable_inv, which assumes P.InitCompatible and the default election strategy, and commit_reachable), not of this statement. Neither the statement nor mentions .
3. Plain-language summary
In any cluster satisfying the invariant, with compatible bootstrap configurations: suppose a node has an election record for term , i.e. a quorum (of both configurations realizing the base) of eligible nodes that sent term- joins with last accepted keys at or below the base. Then every committed key of a term earlier than is an ancestor of, or equal to, the base.
Confirmed by the mission captain (proposal self-audit).
Confirmed by the moderator at approval.