Ablation

Switch one of the rules below off, then run it again. A rule that looks redundant makes its case the moment it is gone.

Every non-obvious rule in Raft defends a specific safety property. Turn the rule off and watch the property break — the fastest route to understanding why the rule is there.

Each guard lives in lib/raft/rules.ts and is consulted in exactly one place. That is what makes these switches honest rather than cosmetic: there is no second site quietly still enforcing the rule. Every switch also has a test proving the violation actually occurs.

Unmodified Raft — every rule enforced.

  • Election restriction

    Switch this rule off and the following promise can fail: A record that has been settled never goes missing from any later leader.

    A voter refuses a candidate whose log is less up-to-date than its own — comparing last term first, then index. This is what makes Leader Completeness hold.

    Protects:
    Leader Completeness
    Paper section:
    §5.4.1
    In Figure 2:
    RequestVote RPC, receiver rule 2
    Single call site:
    lib/raft/election.ts — handleRequestVote
    Scenario that proves it:
    election-restriction-overwrite
  • Current-term commit rule

    Switch this rule off and the following promise can fail: No two computers ever act on different contents at the same row.

    A leader may only mark an entry committed by counting replicas if that entry is from its own term. Older entries commit indirectly. Removing this reproduces Figure 8.

    Protects:
    State Machine Safety
    Paper section:
    §5.4.2
    In Figure 2:
    Rules for Servers, Leaders, final rule
    Single call site:
    lib/raft/commit.ts — advanceCommitIndex
    Scenario that proves it:
    figure-8
  • AppendEntries consistency check

    Switch this rule off and the following promise can fail: If two computers hold the same record at a row, everything above that row is identical too.

    AppendEntries carries prevLogIndex and prevLogTerm; the follower rejects on mismatch and the leader walks nextIndex back until the logs agree. Only the term half is ablated here — accepting past the end of a log would punch a hole in it rather than diverge it.

    Protects:
    Log Matching
    Paper section:
    §5.3
    In Figure 2:
    AppendEntries RPC, receiver rule 2
    Single call site:
    lib/raft/replication.ts — handleAppendEntries
    Scenario that proves it:
    log-matching-break
  • Term increment on candidacy

    Switch this rule off and the following promise can fail: There are never two leaders at once in the same round.

    Incrementing the term is what makes a campaign a new ballot. Without it, a server that has already voted for someone else campaigns inside the same term and overwrites its own vote.

    Protects:
    Election Safety
    Paper section:
    §5.2
    In Figure 2:
    Rules for Servers, Candidates, rule 1
    Single call site:
    lib/raft/election.ts — startElection
    Scenario that proves it:
    double-candidacy
  • Step down on higher term

    Switch this rule off and the following promise can fail: There are never two leaders at once in the same round.

    Any server seeing a higher term adopts it and reverts to follower. Only the role change is ablated, not the term adoption — suppressing both deadlocks elections rather than breaking safety.

    Protects:
    Election Safety
    Paper section:
    §5.1
    In Figure 2:
    Rules for Servers, All Servers, rule 2
    Single call site:
    lib/raft/node.ts — observeTerm
    Scenario that proves it:
    partition-stranded-leader
  • Persistent votedFor

    Switch this rule off and the following promise can fail: There are never two leaders at once in the same round.

    votedFor is persistent state and survives a restart. Lose it and one server can vote twice in a term, electing two leaders in it.

    Protects:
    Election Safety
    Paper section:
    §5.2
    In Figure 2:
    State, Persistent state on all servers
    Single call site:
    lib/raft/node.ts — restart
    Scenario that proves it:
    double-vote-restart
  • Joint consensus

    Switch this rule off and the following promise can fail: There are never two leaders at once in the same round.

    A membership change passes through a transitional configuration C-old,new, in which agreement requires a majority of the old set *and* of the new one. Without it the cluster switches straight from C-old to C-new — and since there is no instant at which every server switches together, two disjoint majorities can elect two leaders in the same term. That is Figure 10.

    Protects:
    Election Safety
    Paper section:
    §6
    In Figure 2:
    Not in Figure 2 — Figure 10, and §6
    Single call site:
    lib/raft/replication.ts — beginConfigurationChange
    Scenario that proves it:
    membership-change