nixfleet_state_machine/rollout/
mod.rs

1//! Pure rollout-level reducer (RFC-0008 §3). Parallel to the per-host
2//! reducer (`crate::step`); same functional-core discipline (RFC-0006 §2):
3//! no I/O, no clock reads, no shared mutable state, deterministic given
4//! `(state, event, now)`.
5//!
6//! Phase 10a ships the skeleton (types + dispatch returning
7//! `RolloutTransitionError::Unimplemented`); Phase 10b lands the
8//! per-source-state transition bodies and proptest invariants.
9
10pub mod effect;
11pub mod error;
12pub mod event;
13pub mod state;
14
15mod transitions;
16
17#[cfg(test)]
18mod tests;
19
20pub use effect::RolloutEffect;
21pub use error::RolloutTransitionError;
22pub use event::{HostId, HostRolloutState, RolloutEvent};
23pub use state::{ChannelId, ClosureHash, RolloutId, RolloutRecord, RolloutState};
24
25use chrono::{DateTime, Utc};
26
27/// Pure rollout-level reducer. CP-side only (rollout events are
28/// synthesized from inbound agent events; agents never emit `RolloutEvent`s).
29///
30/// `now` is a parameter (no `chrono::Utc::now()` inside the crate); the
31/// applier supplies it from its own `ClockHandle` so test fixtures with
32/// `FakeClock` stay deterministic.
33pub fn step(
34    record: RolloutRecord,
35    event: RolloutEvent,
36    now: DateTime<Utc>,
37) -> Result<(RolloutRecord, Vec<RolloutEffect>), RolloutTransitionError> {
38    transitions::dispatch(record, event, now)
39}