Crate nixfleet_state_machine

Crate nixfleet_state_machine 

Source
Expand description

Pure per-host rollout state-machine reducer.

Implements RFC-0005 §3 (6-state machine) and RFC-0006 §3 (functional core / imperative shell). The reducer is a single function:

step(state, event, now, policy) -> Result<(state, Vec<Effect>), TransitionError>

Properties enforced by the crate’s structure:

  • No I/O. Cargo.toml declares no tokio, no reqwest, no rusqlite. CI verifies via cargo tree -p nixfleet-state-machine (RFC-0006 §11).
  • No clock reads. chrono::Utc::now() is not called anywhere in this crate; now is always a parameter.
  • Pure transitions. step is deterministic for a given input. Same (state, event, now, policy) → same (state, effects).
  • Side effects as data. Effect is a description, not an execution. The agent runtime (RFC-0006 §7.1) and CP runtime (§7.2) each exhaustively match on Effect variants; adding a variant is a compiler-enforced change at every applier.

§Same code, both sides

The CP-mirror view of per-host state (RFC-0006 §2 principle 4) runs the same step() as the agent. Event carries both Local* (agent-side, synthesized from worker output) and Remote* (CP-side, synthesized from inbound agent events) variants — the transitions they drive are identical by construction.

Modules§

effect 🔒
Reducer outputs. Descriptions of side effects, not executions.
error 🔒
Reducer error path. Distinct from runtime errors — these mean the input event is structurally inapplicable to the current state, which is a runtime invariant violation (out-of-order event, stale seq, etc.). The runtime layer decides whether to log + drop, request replay, or panic.
event 🔒
Reducer inputs. Maps RFC-0005 §4.2 wire events onto reducer transitions.
rehydration 🔒
Snapshot rehydration — effect emission rules for state restored from a CP-supplied HostRolloutSnapshot (RFC-0005 §9.5 / LIFT #3).
rollout
Pure rollout-level reducer (RFC-0008 §3). Parallel to the per-host reducer (crate::step); same functional-core discipline (RFC-0006 §2): no I/O, no clock reads, no shared mutable state, deterministic given (state, event, now).
state 🔒
Per-(rollout, host) reducer state. Maps RFC-0005 §5 HostRolloutRecord.
transitions 🔒
Transition dispatcher. Routes (state, event) to the per-source-state handler in a sibling module, after performing the universal pre-checks (seq monotonicity, basic structural validity).
wire_conversions 🔒
Bidirectional conversions between the wire-format types in nixfleet-proto::agent_event and the state-machine’s effect / event types. Both directions live in this crate (the state-machine) by the orphan rule: every conversion has a state-machine-local type on at least one side. Keeps nixfleet-proto free of state-machine awareness (proto is the leaf crate) and CP free of duplicate wire definitions (the architect’s d013 lift per RFC-0004 §2).

Structs§

HostRolloutState
Per-(rollout, host) reducer state. Mirrors RFC-0005 §5 HostRolloutRecord; the persistence schema in Phase 4 serializes this struct.
ProbeRecord
ProbeSubResult
Per-control sub-result on a kind = evidence probe (RFC-0007 §7.1). None aggregate for non-evidence probes; Some(vec) for evidence probes — the applier’s probe_failures co-write iterates sub_results to populate one row per failing control_id.
ProbeTopologyEntry
One entry in a LocalProbeTopologyDeclared / RemoteProbeTopologyDeclared event. Carries the per-probe metadata CP needs to evaluate the gate without reading the agent’s filesystem (RFC-0007 §8). Threading mode per-event would also work, but the upfront declaration also lets the gate distinguish “this enforce probe declared but never reported” from “no enforce probe declared at all” — the difference matters for wave-hold semantics.
RolloutId
Content-addressed rollout identifier (RFC-0008 §6.3).

Enums§

Effect
Event
Inputs to crate::step. Each variant maps to exactly one (legal) outbound or inbound RFC-0005 §4.2 event.
HostState
6-state rollout machine per RFC-0005 §3. Replaces the pre-v0.2 9-variant nixfleet_proto::HostRolloutState (the Queued / Dispatched / ConfirmWindow / Healthy / Soaked variants are removed — phases 4-6 delete the old enum entirely once the new machine is wired through).
LogLevel
OutboundAgentEvent
Outbound wire payloads (POST /v1/agent/events). Defined here for the reducer’s LocalEmitEvent effect; Phase 6/7 lifts these into nixfleet-proto::agent_wire once the HTTP routes are wired.
ProbeMode
Per-probe gate participation (RFC-0007 §3.4). Threaded through every probe event so CP can decide whether to gate on a result without consulting a separate topology table.
ProbeStatus
TransitionError

Functions§

rehydration_effects
Effects to emit immediately after applying a HostRolloutSnapshot to the agent’s in-memory state. Workers consume these to refresh any cached per-rollout state seeded by prior process incarnations.
step
Pure reducer. Same signature on agent and CP-mirror sides.

Type Aliases§

ClosureHash
ProbeName