Skip to content

State TLA+ LogInv and CommittedLogAppendOnlyProp in the Lean ccf-raft model - #8590

Draft
cjen1-msft wants to merge 11 commits into
mainfrom
cjen1-msft-literate-chainsaw
Draft

cjen1-msft wants to merge 11 commits into
mainfrom
cjen1-msft-literate-chainsaw

Conversation

@cjen1-msft

@cjen1-msft cjen1-msft commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Adds lean/ccf-raft/CCFRaft/PropertiesTLA.lean, which states Lean versions of the TLA+ safety properties LogInv and CommittedLogAppendOnlyProp as theorems, each paired with a non-vacuity witness lemma. They are proved in a self-contained CCFRaft/ProofTLA/ closure. The aim is to measure how much Lean proof these TLA+ properties need, separately from the existing Lean safety proof work.

Base. This PR targets main and is based on main at afd42aa7e, which includes the model (#8578), the Lean safety proofs (#8583) and the bundled transition-system types (#8624). No GitHub stack is used. The head is 2c2372466. The diff against main touches only ProofTLA/, PropertiesTLA.lean, Tests/ArchitectureTLA.lean, Tests/PropertiesTLA.lean, the CCFRaft.lean umbrella and the README.

Statements. The presentation follows Properties.lean. Each property is a directly stated theorem with explicit quantifiers, and each witness is a separate lemma with explicit existentials. Both are proved by exact of a ProofTLA theorem, and ProofTLA is imported privately.

  • The properties are invariants of Model.transitionSystem. Each quantifies every initial membership (Finset NodeID) and node list.
  • They are meant to match the TLA+ semantically, not to transliterate its temporal operators. For these safety properties, Spec => []P means P holds in every reachable state, and Spec => [][A]_vars means A holds on every enabled step from a reachable state; stuttering steps satisfy it trivially and fairness plays no part.
  • The committed log is log.take commitIndex over full entries (term and content), which matches TLA+ Committed(i) == SubSeq(log[i], 1, commitIndex[i]).

The theorems and witnesses:

  • log_inv (LogInv, ccfraft.tla ~1400): in every reachable state, the committed logs of any two nodes are prefix-comparable. This is the same-state property, which is weaker than committed_logs_prefix in Properties.lean.
  • committed_log_append_only_prop (ccfraft.tla ~1639): on every enabled step from a reachable state, each node's committed log is a prefix of its committed log afterwards.
  • abs.tla AppendOnlyProp is not stated separately. Under MappingToAbs it is the same property over entry terms only, so committed_log_append_only_prop implies it.
  • log_inv_witness: a reachable state in which two distinct nodes both have nonempty committed logs.
  • committed_log_append_only_prop_witness: an enabled step from a reachable state that strictly extends a nonempty committed log.

Tests/PropertiesTLA.lean checks that both claims cover every state and adjacent step of any valid finite or infinite Stream'.Seq trace.

These are statements about the Lean model. That the Lean model is equivalent to the TLA+ model is not proved; it is a trust boundary.

Proof. The proofs were ported from a snapshot of #8583's safety proof into ProofTLA and pruned to the declarations the theorems depend on. Nothing in ProofTLA or PropertiesTLA.lean imports CCFRaft.Proofs* or CCFRaft.Properties; Tests/ArchitectureTLA.lean enforces this.

  • ProofTLA is 23 files and 7177 lines (6435 non-blank). The witness proofs in ProofTLA/Witnesses.lean account for 267 of those lines.
  • PropertiesTLA.lean is 87 lines (74 non-blank).
  • The README has the commands to reproduce these counts.

CI. CCFRaft.lean publicly imports PropertiesTLA alongside Properties, and privately imports the TLA tests, as main does for its tests. The existing Lean workflow therefore covers the new modules with lake check --inadvisably-no-sandbox, lake exe check-imports, formatting and lake lint. Tests/ArchitectureTLA.lean requires the four theorem roots to be theorems that use only propext, Classical.choice and Quot.sound. This PR does not change the workflow.

Manual testing. These checks passed locally on head 2c2372466:

  • lake build --wfail (3200 jobs), which includes the canonical traces, Tests/Architecture.lean, and the Tests/ArchitectureTLA.lean independence and axiom audit
  • lake exe check-imports
  • lake lint
  • leanfmt on the package
  • scripts/ascii-checks.sh
  • scripts/doc-newline-checks.sh
  • prettier on the README

lake check was not run locally on this head; it runs in CI. An earlier lake check --inadvisably-no-sandbox on head 4873cffab (based on 8fb56b285) accepted the solution with only propext, Quot.sound and Classical.choice. No sandboxed kernel check has been run.

Rebasing onto afd42aa7e needed two follow-up commits. The first ports ProofTLA to the bundled TransitionSystem types from #8624, in the same way #8624 ported Proofs. The second restores the README section after main's rewrite. Intermediate commits do not build against afd42aa7e.

@cjen1-msft cjen1-msft changed the title State TLA+ LogInv and AppendOnlyProp in the Lean ccf-raft model State TLA+ LogInv and CommittedLogAppendOnlyProp in the Lean ccf-raft model Oct 16, 2026
@cjen1-msft
cjen1-msft force-pushed the cjen1-msft-literate-chainsaw branch from 9789f5c to 1b1b4cb Compare October 19, 2026 19:18
@cjen1-msft
cjen1-msft force-pushed the cjen1-msft-literate-chainsaw branch 3 times, most recently from b15bc9b to 9f04123 Compare October 20, 2026 15:53
Base automatically changed from cjen1-msft-vigilant-train to main October 20, 2026 16:16
@cjen1-msft
cjen1-msft force-pushed the cjen1-msft-literate-chainsaw branch from 9f04123 to 6a3f65b Compare October 21, 2026 09:23
cjen1-msft and others added 11 commits October 23, 2026 10:30
Add PropertiesTLA.lean with exact Lean statements of ccfraft.tla
LogInv and CommittedLogAppendOnlyProp, and abs.tla AppendOnlyProp under
MappingToAbs, proved by a self-contained ProofTLA closure. Add exactness
and architecture/axiom tests, a README section, and a sandboxed kernel
check for ccf-raft in CI.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Define LogInv and CommittedLogAppendOnlyProp directly over valid traces,
matching the TLA+ semantically, and add non-vacuity witnesses.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
LogInv holds in every reachable state and CommittedLogAppendOnlyProp on
every enabled step from a reachable state, which is what Spec => []P and
Spec => [][A]_vars mean for these safety properties.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Port PropertiesTLA and the ProofTLA closure to the model at 1041157:
concrete NodeID/ReqID, ModelConfig with a typed primary, the genesis
configuration entry, three-way append-entries role outcomes and the new
conflict index. LogInv's quorum-intersection argument now uses a Genesis
invariant (every nonempty log starts with the genesis entry) to show
each quorum log names a configuration. Statement meanings and the four
theorem roots are unchanged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adapt ProofTLA to the updated model: term-aware step-down, gated
responses from unknown peers, signature-bounded commit quorums, strict
prevIndex-0 matching, renamed vote messages and the active-free lift.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Model #8578 now takes the initial membership as a Finset NodeID, with the
minimum member starting as primary, instead of ModelConfig. The TLA+ claims
and witnesses quantify that membership; proofs carry it in a proof-only
Initial class and derive primary membership from Finset.min.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The model now represents traces as Stream'.Seq. Add regression checks that
the reachable-state LogInv and the step-wise CommittedLogAppendOnlyProp
cover every state and adjacent step of any valid finite or infinite trace.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
nominateSuccessor now owns the primary-role guard and returns the
unchanged node state; port the direct and summary proofs accordingly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Follow the presentation of the proved Properties.lean: each claim is a
directly stated theorem with a separate witness lemma, both delegating
to ProofTLA, which is now imported privately. Semantics are unchanged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Follow #8624: TransitionSystem now bundles its State and Action types.
Generalize the witness run helper over the bundled system, make the
witness systems abbreviations, and name the Reachable recursor explicitly
when inducting over reachability of the Raft transition system.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Main rewrote the README; reapply the TLA+ section after it and refer to
committed_logs_prefix, the current name of the cross-state property.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@cjen1-msft
cjen1-msft force-pushed the cjen1-msft-literate-chainsaw branch from 4873cff to 2c23724 Compare October 23, 2026 10:43

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant