///|
/// A journal event together with the evidence required to verify its position.
pub(all) struct JournalEvent[P] {
  sequence : Int
  kind : String
  payload : P
  correlation_id : String
  previous_hash : Int
  hash : Int
}

///|
/// The result of applying one event to an application state.
pub(all) enum Transition[S] {
  Accepted(S)
  Rejected(String)
}

///|
/// Why a journal failed structural validation.
pub(all) enum ChainIssue {
  /// index, expected sequence, actual sequence
  UnexpectedSequence(Int, Int, Int)
  /// sequence, expected previous hash, actual previous hash
  BrokenPreviousHash(Int, Int, Int)
  /// sequence, expected event hash, actual event hash
  InvalidEventHash(Int, Int, Int)
} derive(Debug, Eq)

///|
/// Structural validation result for an event journal.
pub(all) enum ChainValidation {
  /// event count, tail hash
  Valid(Int, Int)
  Invalid(ChainIssue)
} derive(Debug, Eq)

///|
/// Replay completion status.
pub(all) enum ReplayStatus {
  Completed
  /// sequence, stable rejection reason
  Rejected(Int, String)
  InvalidJournal(ChainIssue)
  InvalidCheckpoint(String)
} derive(Debug, Eq)

///|
/// Evidence produced by a replay.
pub(all) struct ReplayReport[S] {
  status : ReplayStatus
  initial_sequence : Int
  applied_events : Int
  final_sequence : Int
  final_state : S
  final_state_hash : Int
  journal_tail_hash : Int
  state_hashes : Array[Int]
}

///|
/// A state snapshot anchored to a verified journal boundary.
pub(all) struct Checkpoint[S] {
  sequence : Int
  state : S
  state_hash : Int
  journal_hash : Int
}

///|
/// The first point where two executions no longer agree.
pub(all) enum DivergenceKind {
  StateMismatch
  StatusMismatch
  LengthMismatch
  EventMismatch
} derive(Debug, Eq)

///|
/// A stable, serializable explanation of a replay divergence.
pub(all) struct Divergence {
  sequence : Int
  kind : DivergenceKind
  left_hash : Int
  right_hash : Int
  message : String
} derive(Debug, Eq)

///|
/// Result of comparing two reducer versions against the same journal.
pub(all) struct MigrationReport[S] {
  compatible : Bool
  old_report : ReplayReport[S]
  new_report : ReplayReport[S]
  first_divergence : Divergence?
}

///|
/// Result of checking an invariant over every replayed prefix.
pub(all) enum InvariantResult {
  /// number of checked state prefixes
  Holds(Int)
  /// sequence, state hash, stable reason
  Violated(Int, Int, String)
  ReplayFailed(ReplayStatus)
} derive(Debug, Eq)

///|
/// Merkle-style deterministic commitment over event and state evidence.
///
/// This is an integrity and comparison structure, not a cryptographic signature.
pub(all) struct ReplayEvidenceTree {
  event_count : Int
  root : Int
  levels : Array[Array[Int]]
} derive(Debug, Eq)

///|
/// Portable logarithmic proof that one transition belongs to an evidence root.
pub(all) struct ReplayInclusionProof {
  sequence : Int
  event_hash : Int
  state_hash : Int
  leaf_hash : Int
  siblings : Array[Int]
  sibling_on_left : Array[Bool]
  root : Int
} derive(Debug, Eq)