faction 0.3.2

A no_std + alloc, protocol-independent cluster readiness state machine for startup coordination and readiness quorum tracking.
Documentation
  • Coverage
  • 0%
    0 out of 135 items documented0 out of 73 items with examples
  • Size
  • Source code size: 186.24 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 1.31 MB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 13s Average build duration of successful builds.
  • all releases: 12s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • Homepage
  • Repository
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • umbgtt10

faction

A no_std, 0-unsafe Mealy machine for cluster bootstrapping.

faction is a protocol-agnostic state machine primitive that answers one question:
"When is the cluster ready to proceed?"

It tracks participation and readiness signals across a known set of peers and emits a deterministic exit decision — either Bootstrapped or TimedOut. No network I/O. No consensus algorithm. No opinion on what "ready" means. Just pure, testable state transitions.


Why faction?

Most distributed systems bootstrap with ad-hoc coordination — timeouts, magic numbers, and implicit assumptions that are never tested in isolation. faction replaces that with a Mealy machine that is:

  • Deterministic — same inputs always produce the same outputs. Replay any sequence.
  • Verifiable — every (state, command) pair is explicitly tested. No untested paths.
  • Embeddableno_std + alloc, zero unsafe. Runs on bare metal, WASM, and cloud.
  • Observable — every transition reaches a trait-based Observer. No instrumentation surprises.
  • Slim by construction — each state carries only its active data. Terminal states carry counts, not collections.

How it works

The machine progresses through five states:

Initial → Pinging → Collecting → Bootstrapped
                         ↘           TimedOut
State Carries
Initial Nothing — unit struct
Pinging pinging_peers: Vec<PeerId>, collecting_peers: Vec<PeerId>
Collecting collecting_peers: Vec<PeerId>, pinged_peers: Vec<PeerId>
Bootstrapped pinged_peers: Vec<PeerId>, collected_peers: Vec<PeerId>
TimedOut pinging_peers: Vec<PeerId>, collecting_peers: Vec<PeerId>

Each state implements the State trait with step(), cluster_view(), and accept(). Decision logic is split into focused step structs — PingingStep, ReadyStep, and LocalCompletionStep — each handling exactly one kind of observation without branching on a kind enum.

Five commands drive the machine: ParticipationObserved, ReadyObserved, LocalParticipationCompleted, DeadlineExpired, and Probe. Outcomes cover acceptance, duplication, non-member rejection, local participation completion, broadcast, quorum, and exit.

Full specification in phase-0-specification.md.


Project status

Metric Value
Productive LOC (core) 1,165
Tests (entire codebase) 264
Crappy functions 0
Code coverage (productive) 100%
Unsafe code 0 (enforced by #![deny(unsafe_code)])
no_std Verified

Roadmap

The project is building toward full dynamic membership across six phases. See ROADMAP.md for the detailed plan.


Workspace

Crate Description
core/ State machine — 13 source files, 145 tests
core-validation/ Deterministic multi-node scenario harness — 23 tests
protocol/ Message translator and protocol runtime — 33 tests
protocol-validation/ In-process protocol cluster — 9 tests
system-tests/ Multi-process convergence + timer + transport + observer tests — 54 tests

Quality Gates

powershell -File scripts\run_stage_1.ps1   # format, clippy, no_std checks, tests
powershell -File scripts\run_stage_2.ps1   # CRAP and file risk analysis

Design principles

  • Pure Mealyoutput = F(state, input). No side effects inside the machine.
  • Explicit state ownership — states carry only what they mutate.
  • No dead code — terminal states return false from accept(), making step() unreachable by construction.
  • Observer, not logger — the Observer trait receives every transition. Wire it to telemetry, audit, or testing assertions.
  • Protocol-agnostic — faction does not know what a "peer" is or how the network works. The caller owns network I/O.
  • One struct per file — each step, state, and policy is its own file.
  • No &mut parameters — prefer return values over in-place mutation.

License

Licensed under the MIT License. See LICENSE.


Links