Appendix B - 13. Composed state-machine model (typed lifecycles + cross-machine invariants)

The judgment — Model the composition, not the machines; the invariants that break live between them.

RoleModels-bridge
FamilySystem models
Used in stacksThe specification + verification stack
EnforcementHard
Related mechanismsCounterpart: Process view (concurrent processes, lanes, and racing edges); Sibling: Agent-orchestration model (developer journeys); Consumer: Formal invariant verification (temporal form → model checking); Layer: Mediator & single-writer contracts

Full description → Composed state-machine model (typed lifecycles + cross-machine invariants).

Intent — Model a concurrent lifecycle as a set of structured state machines running at once, their cross-machine predicates declared as first-class, shape-verified invariants.

Problem

A distributed lifecycle rarely lives in one machine: a parent job fans out into chunks, each moves through its own states, and a completer fans the results back in. The properties that matter span the machines — a chunk is never both leased and free, output is uploaded before the row is marked done, exactly one completer fires. Left implicit, each is a scatter of boolean flags asserted nowhere, and the failures are the worst kind: a rare interleaving double-completes a job, a crash between upload and commit strands a corrupt output as "done." A suite that walks each machine alone reports green while the composition is broken.

Mechanism

Engineering consequences

The lifecycle gains one authoritative source of truth: a new state or invariant is a model edit or the drift gate fails, and that friction is the freshness guarantee. The effort concentrates on naming the cross-machine predicates, the part a single-machine view never forces you to state.

Implementation seam

The model sits on the executable-source-of-truth substrate Appendix B, so the machines are data the build reads; each invariant carries a required, consumed temporal-form field; and at least one exhaustive checker must exist to route to. A separate verifier reads the invariants and runs the checker each form demands — this entry specifies, that one proves, neither useful alone.

Known limitations

A form no checker reads only looks verified, so the field must stay required and consumed. The check proves invariants across the modeled interleavings only; a bug the model abstracts away is out of scope, so the proof is only as strong as the model's fidelity. And it needs a real lifecycle enacted through addressable state to reconcile against — without that, this is a hand-drawn diagram, not a checked model.

© James C. Davis, 2026–present