Bootstrapping with different partial views gives compatible configurations: two configurations of ClusterBootstrapService's form meet the condition of InitCompatible
ProvedOpenSearchSafety.bootstrap_compatibleLet eligible : NodeId → Bool, let k be the number of bootstrap requirements, and let resolve placeholder : Nat → NodeId be such that, for all i, j < k: resolve i = resolve j → i = j (each requirement names its own node); placeholder i = placeholder j → i = j; placeholder i ≠ resolve j; and eligible (placeholder i) = false. Let X, Y be configurations and mX, mY : Nat → Bool with BootstrapConfig k resolve placeholder mX X and BootstrapConfig k resolve placeholder mY Y. Then for all lists q₁, q₂ of node ids with eligible x = true for every x in q₁ and in q₂, X.hasQuorum q₁ = true and Y.hasQuorum q₂ = true, some x is in both q₁ and q₂.
Each bootstrapping node uses the configuration of the requirements it has matched, with placeholders for the others, and needs more than half matched (ClusterBootstrapService, CBS:176-215, 259-273, 306-335). Different nodes may match different requirements and bootstrap with different configurations; the theorem shows that any two such configurations, built from the same requirements with the same resolve and placeholder (every requirement resolves to the same node everywhere), meet the condition of Params.InitCompatible, the hypothesis of the safety theorems. The theorem does not mention Params: P.InitCompatible follows for every P with P.eligible = eligible whose bootstrap configurations are all of this form, but no theorem states this, and the model does not tie P.initConfs to BootstrapConfig.
import Definitions.Def_OpenSearchSafety open OpenSearchCoordination OpenSearchSafety
theorem OpenSearchSafety.bootstrap_compatible (eligible : NodeId → Bool) (k : Nat) (resolve placeholder : Nat → NodeId)
(hres : ∀ i j, i < k → j < k → resolve i = resolve j → i = j)
(hph : ∀ i j, i < k → j < k → placeholder i = placeholder j → i = j)
(hdis : ∀ i j, i < k → j < k → placeholder i ≠ resolve j)
(hphe : ∀ i, i < k → eligible (placeholder i) = false)
(X Y : VotingConfiguration) (mX mY : Nat → Bool)
(hX : BootstrapConfig k resolve placeholder mX X) (hY : BootstrapConfig k resolve placeholder mY Y)
(q₁ q₂ : List NodeId) (hq₁ : ∀ x ∈ q₁, eligible x = true) (hq₂ : ∀ x ∈ q₂, eligible x = true)
(h₁ : X.hasQuorum q₁ = true) (h₂ : Y.hasQuorum q₂ = true) : ∃ x, x ∈ q₁ ∧ x ∈ q₂ := 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.bootstrap_compatible
Notions used
Sources and conventions. Rendered from Definitions/Def_OpenSearchCoordination.lean (configurations, hasQuorum), Definitions/Def_OpenSearchSafety.lean (BootstrapConfig) and the stub Theorems/Thm_OpenSearchSafety_bootstrap_compatible.lean; Java line numbers refer to OpenSearch b2a54ba5c0defba3d1d20423e911d4bf920bab19 (CM = CoordinationMetadata.java, CBS = ClusterBootstrapService.java), checked against the local checkout. The statement uses no cluster, parameter record or coordination state.
Nodes, configurations, quorums. Node ids are natural numbers. A discovery node is a pair of an id and a Boolean (isClusterManagerNode). A voting configuration is a strictly increasing list of node ids, hence duplicate-free; two configurations are equal exactly when they have the same members. denotes the empty configuration EMPTY_CONFIG; " is empty" means its list is empty. For a configuration and any list of ids,
so the empty configuration has no quorum, and ids of outside as well as repetitions in are irrelevant. Transcription check: matches VotingConfiguration.hasQuorum (CM:405-409).
Bootstrap configurations. For , functions , and a configuration , holds when
- for every id : , where if and otherwise; and
- .
(The definition fixes the member set of only; values of the three functions at arguments are irrelevant.) Citation check: in ClusterBootstrapService.java, checkRequirements (CBS:306-335) matches each requirement against the discovered nodes, throwing if a requirement matches several nodes or a node several requirements; onFoundPeersUpdated (CBS:176-215) bootstraps when the matched nodes outnumber half the requirements (CBS:211, the same count as conjunct 2) and the local node is among them (CBS:202-209, not represented); startBootstrap (CBS:259-273) builds the configuration from the matched nodes' ids and "{bootstrap-placeholder}-" + requirement for the unmatched requirements, as in conjunct 1. The best-effort bootstrap without configured requirements (scheduleUnconfiguredBootstrap, CBS:217-250, startBootstrap(discoveredNodes, emptyList())) is not described by this definition.
1. Declaration
Binders and hypotheses, in order:
- a function (a free parameter, not a parameter record);
- and functions ;
hres: for all , ;hph: for all , ;hdis: for all , ;hphe: for all , false;- configurations , and functions ;
hX: andhY: ;- lists , of ids, with
hq₁: every has true, andhq₂: every has true; h₁: andh₂: .
Conclusion. .
Unfolded: the members of are for — if , otherwise — and by hres, hph, hdis these are pairwise distinct, so has exactly members, and likewise . h₁ says that more than members of occur in ; by hq₁ and hphe these are all of the form . The conclusion is that and share an id.
2. What is not constrained
- No parameter record appears. The conclusion has the shape of for the family of configurations with as eligibility, but the statement does not link that family to any , nor to any ; every cluster-level safety theorem keeps as an assumption.
- and share , and : the two bootstrapping nodes have the same requirement list and resolve every matched requirement to the same node; they may differ only in which requirements they matched. In Java a requirement is matched by node name or address at each bootstrapping node (CBS:300-304), so this is an assumption (the module docstring lists "bootstrap requirements name the same node at every node").
- Resolved ids are not required to be eligible; if, for instance, no resolved id is eligible,
h₁cannot hold and the statement is vacuous. For , conjunct 2 of () fails, so the statement is vacuous. - Conjunct 2 of is not needed for the conclusion: given
hq₁,hpheand injectivity,h₁already forces more than indices with and ; two such sets of more than ids among the ids must meet. - Not vacuous: , , , , true, , .
- Only the requirements-based bootstrap path is described; the best-effort bootstrap without configured requirements (CBS:217-250) is outside .
3. Plain-language summary
Two voting configurations built from the same bootstrap requirements resolved to the same nodes — differing only in which requirements were matched, with placeholder ids distinct, distinct from real ids and not eligible — have intersecting quorums when quorums are made of eligible nodes. This is the compatibility property a parameter record needs for such configurations, but the theorem does not itself state for any parameter record.
Confirmed by the mission captain (proposal self-audit).
Confirmed by the moderator at approval.