minerva 0.2.0

Causal ordering for distributed systems
//! The epoch lifecycle rounds (PRD 0024 stage two).
//!
//! The mandatory pins the charter's R5 and R6 requirements name, landed
//! beside their machinery: the concurrent-declaration race across every
//! delivery interleaving (one winner, no adoption before the confirmation
//! watermark, identical post-seal lineage), the deterministic
//! `EpochWindowOpen` refusal, the `EpochUnwitnessed` license, the sealed
//! join's duplicate recognizer, and the multi-epoch retention horizon with
//! the exact `EpochBeyondHorizon` boundary. The reads-across-the-seal half
//! of the R6 duplicate law rides the stage-three shadow and is deliberately
//! not faked here.

extern crate alloc;

mod basis;
mod lineage;
mod race;
mod validation;

use core::num::NonZeroUsize;

use crate::kairos::Kairos;
use crate::metis::{
    Cut, Declaration, Dot, EpochAddress, EpochRefusal, Epochs, SealedEpoch, Stability,
    VersionVector,
};

const ROSTER: [u32; 3] = [1, 2, 3];

/// Builds an identity literal. Panics on the non-dot counter zero (R-91).
#[track_caller]
fn d(station: u32, counter: u64) -> Dot {
    Dot::from_parts(station, counter).expect("test literal names the non-dot counter zero")
}

fn cut(entries: &[(u32, u64)]) -> Cut {
    let mut vector = VersionVector::new();
    for &(station, counter) in entries {
        vector.observe(station, counter);
    }
    Cut::from_witnessed(vector)
}

fn machine() -> Epochs {
    Epochs::new(ROSTER, NonZeroUsize::new(2).unwrap())
}

fn tracker() -> Stability {
    Stability::new(ROSTER)
}

fn top() -> Cut {
    cut(&[(1, 9), (2, 9), (3, 9)])
}