Once a round has started an election or been closed, it never starts one again
ProvedOpenSearchPreVote.round_starts_onceFor every election strategy es, requester response lr, response resp, sender and round r with r.electionStarted = true ∨ r.isClosed = true: handling the response does not call startElection ((r.handlePreVoteResponse es lr resp sender).2.1 = false), and the resulting round again has electionStarted = true or isClosed = true. Hence, with round_start_quorum (after a call that calls startElection, the round has electionStarted = true) and because close sets isClosed, a round calls startElection at most once along any sequence of steps, and never after it is closed (Java's compareAndSet on electionStarted, PVC:272).
import Definitions.Def_OpenSearchPreVote open OpenSearchCoordination OpenSearchPreVote
theorem OpenSearchPreVote.round_starts_once {V : Type} (es : ElectionStrategy) (lr resp : PreVoteResponse)
(sender : DiscoveryNode) (r : PreVotingRound V) (h : r.electionStarted = true ∨ r.isClosed = true) :
(r.handlePreVoteResponse es lr resp sender).2.1 = false ∧
((r.handlePreVoteResponse es lr resp sender).1.electionStarted = true ∨
(r.handlePreVoteResponse es lr resp sender).1.isClosed = true) := 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: OpenSearchPreVote.round_starts_once
Notions used
Rounds. A pre-voting round has five fields: a cluster state, a local node, a list of (sender, response) pairs, and Booleans and .
The handler. returns a triple (new round, start flag, max-term argument). The cases, in order:
- If : .
- If is fresher than 's cluster state: . "Fresher" means a larger last accepted term, or an equal term and a larger last accepted version than the state's version-or-metadata-version.
- Otherwise let be with the list updated: the new entry in front, and earlier entries from an equal sender removed. has 's flags.
- If the votes of are not an election quorum, or is true: .
- Otherwise: .
1. Declaration
Binders and hypothesis.
- : an implicit type;
- : an election strategy;
- : pre-vote responses;
- : a discovery node;
- : a round over ;
- : .
Conclusion. Write . Then
If the round has already started an election or has been closed, then handling any response does not signal an election start, and the resulting round has still started an election or is still closed.
2. What is not constrained
- No reachability hypothesis. is arbitrary, and , , and are arbitrary.
- A weak form. The conclusion keeps only the disjunction. It does not say which flag holds afterwards. By the definition, each flag is in fact preserved individually: a closed round is returned unchanged, and a started round stays started in every branch. The theorem states only the weaker disjunctive form.
- Other fields. The conclusion says nothing about 's other fields. In particular, the list of a started but open round can still grow. It says nothing about .
- Only the handler. The theorem covers only . is not mentioned (it trivially keeps true). The theorem is a single-step statement; it does not itself assert anything about sequences of steps.
- Vacuity. None. The hypothesis is satisfiable by any closed or started round.
3. Plain-language summary
Once a round has started an election or been closed, handling one more pre-vote response never starts an election again. The round remains started or closed.
Confirmed by the mission captain (proposal self-audit).
Confirmed by the moderator at approval.