Deterministic hierarchical statechart engine with a tamper-evident journal and exact decimal arithmetic
fsm
以下摘录自该仓库的 README(片段) · 在 GitHub 读完整 README →
fsm is a deterministic, auditable statechart engine that gives LLMs a workflow substrate: the model translates intent into machines, the engine guarantees the semantics — one event, one transition, a tamper-evident journal, and errors that teach the fix.
60-second demo
Running it unattended
The 60-second demo advances the workflow by hand. fsm execute does it for
you: it watches the outbox, runs an operator-configured table of handlers, and
acks each outcome into the journal, so a workflow triggered in a chat proceeds
gate to gate with nobody watching. Install the operator's supplier handler at
/usr/local/bin/notify-supplier and provision native execution as described in
EMBEDDING.md. Check the complete machine
contract before starting the executor; repair invalid findings and check again.
A second transport, for when more than one client needs the same store:
One process serves every client and holds the writer, so two clients share a
store instead of fighting over it. **The HTTP transport has no TLS and binds
loopback by default**; exposing it to a network is a deployment decision that
means putting it behind a reverse proxy that terminates TLS. See
docs/EMBEDDING.md.
A handler may also be another **MCP server**, which the executor talks to over
its stdio and calls one tool on — so an effect can reach the ecosystem this
engine belongs to rather than only the commands on one host. Handlers retry on
a deterministic backoff, run under a concurrency cap, and leave a dead-letter
report behind when they give up.
The pairing is the point: only the executor writes, and a model on
fsm serve --read-only subscribes to fsm://instance/{id} and is notified
when that instance advances, rather than polling to find out. See
docs/EMBEDDING.md for the handler-table
format and the three run modes.
To author and execute through one MCP connection, start
fsm serve --execute --handlers . Read fsm://executor to discover
its configured effects, required arguments, and outcome events. Call the
read-only executor_check tool with {"spec": }, repair its findings,
check again, then call machine_create and trigger an instance. Its
fsm.executor-check/1 report distinguishes structural compatibility from
runtime progress; unavailable contract evidence is unknown. Explicit
manual_effects keeps operator-owned work pending for manual acknowledgement.
Every start is checked again against current state and the loaded table.
Embedded
stdio execution progresses while stdin stays open, including when quiet;
instance_get, ping, and subscriptions observe that progress. The executor
resource publishes fsm.executor/2 with progress: "autonomous" on supported
Linux production stdio and HTTP. HTTP execution continues through DELETE,
disconnects and zero sessions until the shared host stops; stdio EOF requests
supervised shutdown. Borrowed helpers retain their legacy request-driven contract.
Install
Embedding it
fsm is four crates. Depend on the one you need — the CLI binary is not a
library:
| Crate | Use it for |
|---|---|
| fsm-core | the pure engine: parse, compile, analyse, step, and poll caller-timed deadlines. No I/O, no clock. |
| fsm-store | the durable journal-backed store, if you want ours rather than yours. |
| fsm-execute | the effect executor loop, if you are hosting it yourself rather than running fsm execute. |
| fsm-cli | the fsm binary and MCP server. Not a supported library dependency. |
Replace with an exact annotated tag from the repository's
Releases page; never substitute a branch.
See docs/EMBEDDING.md for the library loop, the Store