Determa State — Python reference implementation of the Determa statechart engine
Project description
determa-state
Reference implementation (Python) of the Determa State statechart engine.
The normative SPEC.md, the JSON Schema for machine YAML, and the cross-language
conformance suite live in the spec repo. This repository implements that spec in
Python and is correct iff it passes the conformance suite.
Implements the Determa State spec v0.0.5 (early alpha; all Determa State repos share one synchronized version).
Status: passing the full conformance suite — all 31 engine cases
(conformance/01–31) plus conformance/cli/01–03. Implements YAML 1.2 loading
- validation, the full statechart semantics (RTC dispatch, hierarchy, orthogonal
regions +
done, shallow/deep history, choice pseudostates, submachine states, esvs, CEL guards, structured actions, active objects + bus, defer, timers, faults), static contracts, snapshot round-trip + safe-point migration, Mermaidexport, and the §13 CLI. Built up the build order in issue #3.
Conformance suite
The cross-language conformance suite is the single source of truth for correctness;
this repository is correct iff it passes it. The suite lives in
fruwehq/determa-state-conformance; the test
harness fetches it at the matching release tag (v0.0.5) into a gitignored
.cache/ — no git submodule. The normative SPEC.md and JSON Schema live in
fruwehq/determa-state-spec; the schema-drift test fetches the
schema at the same tag.
For offline work, point the harness at a local checkout:
export DETERMA_CONFORMANCE_DIR=/path/to/determa-state-conformance # the suite
export DETERMA_SPEC_DIR=/path/to/determa-state-spec # the schema (optional)
Scope (per the spec)
- Load and validate machine YAML against
schema/machine.schema.json, parsed under the YAML 1.2 core schema (onlytrue/falseare booleans). - Execute statecharts per
SPEC.md: run-to-completion; hierarchy; orthogonal regions (+done); shallow/deep history;initialtransitions;esvs(extended-state variables declared in states, hierarchical) includingexternalesvs + theenvevent andrefresh;defer(deferred-set, edge-triggered); timers via an injected clock; active-object spawning;publish(directed / by subscription / scoped); and faults (theerrorevent). - Guards in CEL (e.g.
cel-python); structured actions (assign/publish/refresh/spawn/stop) with CEL values. - Adapters — bus / queue / clock / store / observer (SPEC §8), each with a simple in-memory default for tests.
- An
exportcommand that renders a machine (and an instance's currentstate_config) to MermaidstateDiagram-v2(SPEC §12), behind a pluggable exporter interface so more formats (PlantUML, SCXML, …) can be added later. - A test harness that runs the upstream conformance cases against this engine.
Use as a library
The CLI (determa-state …) is a thin wrapper over a programmatic API; an engine can be
embedded in a host program without the CLI or the file-backed store (SPEC §2):
import determa.state as ds
defs = ds.load_definitions(open("gate.yaml").read())
ds.validate(defs[0].raw) # raises ValidationError if invalid
host = ds.Host()
host.register_all(defs)
inst = host.create_root(host.machines["gate"], "g1", external={"fare": 50})
host.run_to_quiescence()
host.deliver("g1", "coin", {"amount": 100}) # typed event; False if rejected
host.run_to_quiescence()
assert inst.active_leaf_names() == ["unlocked"]
assert inst.resolved_esvs()["fare"] == 50
assert inst.status is ds.Status.ACTIVE
host.advance("30s") # virtual clock
snaps = host.snapshot_all() # persist / round-trip (§8)
host.restore_all(snaps)
The public surface is everything exported from the determa.state package
(determa.state.__all__): Host, Instance, Definition, Machine, Status, Event,
load_definitions / load_definition, validate / collect_errors, and the
error types. See tests/test_library_api.py.
Observing transitions (SPEC §8)
Pass an observer — a passive callback invoked once per RTC step (automatic or
manual) with { instance, event, transition, entered, exited, published, spawned, faulted }. Built-ins: JsonlObserver(stream) (a drop-in transition log) and
CollectingObserver (records to a list).
import sys
import determa.state as ds
host = ds.Host(observer=ds.JsonlObserver(sys.stdout)) # one JSON line per step
The Observer is domain observability (what the machine did). For operational
diagnostics the engine also emits standard-library logging under the determa.state logger
(dispatch/transition at DEBUG, faults/dead-letter at WARNING). It is silent by
default (a NullHandler is attached); enable it from the host app:
import logging
logging.basicConfig(level=logging.DEBUG) # or logging.getLogger("determa.state").setLevel(...)
Layout
src/determa/state/— the package.tests/— the implementation's own unit tests (hermetic, offline).conformance/— the harness that runs the external conformance suite black-box against this implementation (kept separate from the unit tests).
Develop
python -m venv .venv && . .venv/bin/activate
pip install -e '.[dev]'
make check # ruff + mypy + unit tests (hermetic, offline) — the PR gate
make conformance # download & run the language-agnostic conformance suite
Equivalently: pytest runs the unit tests only; pytest conformance runs the
conformance suite (it fetches determa-state-conformance into .cache/ on first run — set
DETERMA_CONFORMANCE_DIR to use a local checkout offline). The two are separate:
unit tests never touch the network; conformance is opt-in.
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file determa_state-0.0.5.tar.gz.
File metadata
- Download URL: determa_state-0.0.5.tar.gz
- Upload date:
- Size: 56.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2dac244ce11a028b38146ddbc5c006f36c1d1c9c67cba11b7a16e8e92171ee36
|
|
| MD5 |
a5e77a3dc81bd66f9d1b71adef2f8fd7
|
|
| BLAKE2b-256 |
08d876832c5f5375834a93ca2192ee98fa37510598546ec5449ef01f3a767833
|
Provenance
The following attestation bundles were made for determa_state-0.0.5.tar.gz:
Publisher:
release.yml on fruwehq/determa-state-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
determa_state-0.0.5.tar.gz -
Subject digest:
2dac244ce11a028b38146ddbc5c006f36c1d1c9c67cba11b7a16e8e92171ee36 - Sigstore transparency entry: 2082208547
- Sigstore integration time:
-
Permalink:
fruwehq/determa-state-python@00f5e053b96faf6c5f1822fdde3d6323abdd317f -
Branch / Tag:
refs/tags/v0.0.5 - Owner: https://github.com/fruwehq
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@00f5e053b96faf6c5f1822fdde3d6323abdd317f -
Trigger Event:
push
-
Statement type:
File details
Details for the file determa_state-0.0.5-py3-none-any.whl.
File metadata
- Download URL: determa_state-0.0.5-py3-none-any.whl
- Upload date:
- Size: 45.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cb9d357c5fcd7c74e8d351802ca1e3057ba02a1e35ec8bfb63f5686c1f19800a
|
|
| MD5 |
6c539f949d4f469c32dc01df699e10e8
|
|
| BLAKE2b-256 |
48eeb0dfb7792689bddaedfc69f6350a8e7bf6c522c8bcf37527670dcfc6292e
|
Provenance
The following attestation bundles were made for determa_state-0.0.5-py3-none-any.whl:
Publisher:
release.yml on fruwehq/determa-state-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
determa_state-0.0.5-py3-none-any.whl -
Subject digest:
cb9d357c5fcd7c74e8d351802ca1e3057ba02a1e35ec8bfb63f5686c1f19800a - Sigstore transparency entry: 2082208555
- Sigstore integration time:
-
Permalink:
fruwehq/determa-state-python@00f5e053b96faf6c5f1822fdde3d6323abdd317f -
Branch / Tag:
refs/tags/v0.0.5 - Owner: https://github.com/fruwehq
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@00f5e053b96faf6c5f1822fdde3d6323abdd317f -
Trigger Event:
push
-
Statement type: