Skip to main content

state equivalence and validation

This page defines how QuorumKit decides whether two storage states are equivalent enough for bootstrap, dual write, cutover, and rollback.

The key rule is that QuorumKit validates logical durable Raft state, not raw byte identity.

Terms

  • Validation cut -- A named logical point in the durable mutation history used for comparison.
  • Source state -- The backend family currently treated as authoritative at a given validation cut.
  • Destination state -- The backend family being validated against the source state.

Logical equivalence

At a given validation cut, two durable states are logically equivalent if all of the following hold:

  • they expose the same retained log index range
  • for every retained log index, they expose the same logical log entry contents
  • they expose the same persisted term and voted-for information
  • they expose the same latest durable snapshot metadata
  • they expose the same logical snapshot contents through the snapshot reader contract, including the same relative file tree rooted at SnapshotReader::get_path()

Logical equivalence does not require the same bytes on disk, the same file layout, or the same compaction strategy.

Entry equality

Two retained log entries are equal for this contract if they match on all Raft-visible contents needed to replay the log correctly, including:

  • index
  • term
  • logical entry type
  • logical payload

Backend-private framing, checksum placement, compression layout, and segment boundaries are not part of entry equality.

Snapshot equality

Two latest durable snapshots are equal for this contract if they match on:

  • last included index
  • last included term
  • the logical contents exposed through the snapshot reader contract
  • the relative file paths and file bytes made visible under SnapshotReader::get_path()

They do not need to match on backend-private storage structure outside the public snapshot tree. The public relative layout visible from SnapshotReader::get_path() is part of the contract.

Validation stages

QuorumKit uses the same logical equivalence model at several stages:

After bootstrap

After bootstrapping backend family B from backend family A, B MUST be logically equivalent to A at the export cut used to create the bootstrap image.

During dual write

During dual write, the mirror backend family MUST remain logically equivalent to the primary backend family at every completed validation cut after the mirror was bootstrapped.

Before cutover

Before cutover, the destination backend family MUST be shown equivalent to the source backend family at a chosen validation cut that is recent enough for the cutover policy.

After cutover

After cutover, the new primary backend family MUST be restart-safe on its own and MUST still expose the durable state validated at the cutover cut.

Acceptable proof of equivalence

A final cutover decision MUST be based on a strong proof of equivalence.

Examples of acceptable proof include:

  • a full logical comparison of the relevant durable state
  • matching deterministic digests computed over the same canonical representation

Sampling MAY be used as an early warning or monitoring signal, but sampling alone MUST NOT be the only final cutover proof.

Validation outputs

Validation logic SHOULD produce a report that makes mismatches actionable. At minimum, a mismatch report should identify:

  • whether the mismatch is in logs, metadata, or snapshots
  • the earliest mismatching log index, if logs differ
  • whether the mismatch is structural, content-related, or freshness-related

Relationship to other contracts