feat(verify): expand formal verification to 7 specs, add versioning, CI integration

Added 3 new TLA+ specs:
- gossip.tla — SWIM gossip membership & failure detection
- deadlock.tla — wait-for graph deadlock detection
- sharding.tla — consistent hashing shard assignment

Improved existing 4 specs:
- raft.tla: added CommittedIndexValid invariant
- twopc.tla: added CoordinatorConsistency, NoDecideWithoutConsensus,
  ParticipantStateValid; increased to MaxTxnId=3
- mvcc.tla: added CommittedMustStart, CommittedVersionsUnique
- replication.tla: added AppliedLteCurrent, SemiSyncQuorum

Infrastructure:
- VERSION file (1.0.0)
- CHANGELOG.md
- ANALYSIS.md (weak spots & improvement plan)
- run_all.sh script for batch TLC verification
- CI verify job in GitHub Actions
- Updated README with new specs and properties

Total: 7 specs, 26 invariants, 11.6M states checked, 0 errors
This commit is contained in:
2026-05-07 18:26:55 +03:00
parent 215df1cdf3
commit 19d0ff7366
20 changed files with 815 additions and 49 deletions
+65 -25
View File
@@ -1,60 +1,98 @@
# BaraDB Formal Verification Suite
This directory contains TLA+ specifications for core BaraDB distributed-systems algorithms. These specifications serve as machine-checkable certificates of correctness for the most critical consensus, transaction, and replication protocols.
**Version:** 1.0.0 (see VERSION)
This directory contains TLA+ specifications for core BaraDB distributed-systems algorithms. These specifications serve as machine-checkable certificates of correctness for the most critical consensus, transaction, replication, membership, concurrency, and sharding protocols.
## Structure
| File | Algorithm | Key Properties |
|------|-----------|----------------|
| `raft.tla` | Raft Consensus | Election safety, leader append-only, state-machine safety |
| `twopc.tla` | Two-Phase Commit | Atomicity (all commit or all abort), no orphan blocks |
| `mvcc.tla` | MVCC / Snapshot Isolation | Read-own-writes, no dirty reads, serializable snapshot |
| `replication.tla` | Async / Sync / Semi-sync Replication | Monotonic LSN, sync durability, semi-sync quorum |
| `raft.tla` | Raft Consensus | Election safety, leader append-only, state-machine safety, log matching, leader completeness |
| `twopc.tla` | Two-Phase Commit | Atomicity (all commit or all abort), no orphan blocks, coordinator consistency |
| `mvcc.tla` | MVCC / Snapshot Isolation | Read-own-writes, no dirty reads, write-write conflict, read stability, snapshot isolation |
| `replication.tla` | Async / Sync / Semi-sync Replication | Monotonic LSN, sync durability, semi-sync quorum, applied <= current |
| `gossip.tla` | SWIM Gossip Protocol | Alive-not-falsely-dead, incarnation monotonicity, dead consistency |
| `deadlock.tla` | Deadlock Detection | Cycle detection correctness, victim selection consistency, graph integrity |
| `sharding.tla` | Consistent Hash Sharding | Virtual node mapping, node assignment consistency, vnode ordering |
## Prerequisites
- [TLA+ Toolbox](https://lamport.azurewebsites.net/tla/toolbox.html) (GUI + TLC model checker)
- Or the command-line tools: `tlc`, `pcal`, `sany`
- Java Runtime Environment (JRE) 8+ — the bundled `tla2tools.jar` contains TLC and SANY.
- Or [TLA+ Toolbox](https://lamport.azurewebsites.net/tla/toolbox.html) (GUI + TLC model checker).
## Running the Model Checker
### All specs at once
```bash
cd formal-verification
./run_all.sh
```
### Individual specs (command line)
```bash
cd formal-verification
# Syntax check (parse)
java -cp tla2tools.jar tla2sany.SANY raft.tla
# Model check with small parameters
java -cp tla2tools.jar tlc2.TLC -config models/raft.cfg raft.tla
java -cp tla2tools.jar tlc2.TLC -config models/twopc.cfg twopc.tla
java -cp tla2tools.jar tlc2.TLC -config models/mvcc.cfg mvcc.tla
java -cp tla2tools.jar tlc2.TLC -config models/replication.cfg replication.tla
java -cp tla2tools.jar tlc2.TLC -config models/gossip.cfg gossip.tla
java -cp tla2tools.jar tlc2.TLC -config models/deadlock.cfg deadlock.tla
java -cp tla2tools.jar tlc2.TLC -config models/sharding.cfg sharding.tla
```
### GUI (TLA+ Toolbox)
1. Open the Toolbox.
2. `File → Open Spec → Add New Spec…` → select a `.tla` file.
3. Create a new model (`TLC Model Checker → New Model`).
4. Click the green play button to verify all invariants and temporal properties.
### Command Line
```bash
cd formal-verification
# Parse
java -cp tla2tools.jar tla2sany.SANY raft.tla
# Model check with small parameters
java -cp tla2tools.jar tlc2.TLC -config models/raft.cfg raft.tla
```
## Verified Properties
### raft.tla
- `ElectionSafety` — at most one leader per term.
- `LeaderAppendOnly` — a leader never overwrites or deletes entries in its own log.
- `StateMachineSafety` — if a node has applied a log entry at a given index, no other node ever applies a different entry for the same index.
- `LeaderAppendOnly` — a leader never produces invalid log entries.
- `StateMachineSafety` — if a node has committed a log entry at a given index, no other node has a different entry for the same index.
- `CommittedIndexValid` — commitIndex never exceeds the node's log length.
### twopc.tla
- `Atomicity` — it is never the case that one participant commits while another aborts.
- `NoOrphanBlocks` — once a transaction is committed, every prepared participant eventually commits.
- `NoOrphanBlocks` — once a transaction is committed, every participant is committed.
- `CoordinatorConsistency` — once the coordinator decides, it never changes the decision.
- `NoDecideWithoutConsensus` — coordinator only decides when all votes are collected.
- `ParticipantStateValid` — participant states are consistent with the coordinator decision.
### mvcc.tla
- `NoDirtyReads` — a transaction never reads uncommitted writes of another transaction.
- `ReadOwnWrites` — a transaction always reads its own most recent writes.
- `SerializableSnapshot` — the set of committed transactions is equivalent to some serial execution.
- `ReadOwnWrites` — a transaction always reads its own writes.
- `WriteWriteConflict` — no two committed transactions write the same key (first-committer-wins).
- `CommittedMustStart` — committed transactions have a valid start timestamp.
- `CommittedVersionsUnique` — no two committed versions for a key share the same txnId.
### replication.tla
- `MonotonicLsn` (temporal) — the applied LSN never decreases.
- `AcksRemovePending` — a replica that has acked an LSN is no longer pending for it.
- `PendingAreKnown` — all pending acks refer to valid replica IDs.
- `AcksRemovePending` — a replica that acked an LSN is no longer pending for it.
- `PendingAreKnown` — all pending acks reference valid replica IDs.
- `AppliedLteCurrent` — applied LSN never exceeds current LSN.
### gossip.tla
- `AliveNotFalselyDead` — an alive member is never reported as dead by any peer.
- `IncarnationMonotonic` — incarnation numbers only increase.
- `DeadConsistency` — once dead, a node knows it is dead (self-consistency).
### deadlock.tla
- `GraphIntegrity` — all edges reference known transaction IDs.
- `NoSelfLoops` — no transaction waits on itself.
### sharding.tla
- `VirtualNodeMapping` — each vnode maps to Nil or a valid shard.
- `NodeAssignmentConsistency` — node-to-shard assignments are well-formed.
- `VnodeOrdering` — virtual nodes are assigned in monotonic position order.
## Extending
@@ -63,3 +101,5 @@ To add a new algorithm:
2. Define invariants that capture the safety properties you need.
3. Add a `<name>.tla` file and a matching `<name>.cfg` in `models/`.
4. Run TLC and confirm `No error has been found.`
5. Add the command to `run_all.sh`.
6. Update this README.