Skip to main content

non-deterministic state machine specification to knead workflows

Project description

flowr — non-deterministic state machine specification to knead workflows



Coverage CI Python PyPI MIT License

A declarative, validatable YAML format for non-deterministic state machine workflows.

Read the specification →


The specification

flowr defines what a workflow is — its states, transitions, guard conditions, subflows — not what it does. No execution engine. No side effects. No opinions about retries, timeouts, or error handling. A YAML file declares structure. A validator checks integrity. Tools query, track, and visualise. The format is the foundation.

What the specification covers:

  • States with unique ids, per-state attributes, and transition mappings
  • Transitions that resolve to state ids or declared exit names
  • Guard conditions gated by evidence-based expressions using 6 operators (==, !=, >=, <=, >, <)
  • Named condition groups reusable across transitions on the same state
  • Subflows with call-stack semantics — push on entry, pop on exit
  • Within-flow cycles for iterative workflows
  • Validation rules — structural integrity checks independent of any runtime

What the specification does not cover:

  • Execution engines, side-effect hooks, retry logic, timeout handling
  • Parallel (fork-join) states
  • Orchestration, scheduling, or event dispatch

Full specification with examples and visual diagrams


The reference implementation

This repository contains a Python reference implementation — a CLI and library that validates, queries, and tracks flow definitions conforming to the specification. The specification is the contract; this code is one tool that honours it.

flowr validate deploy.yaml          →  valid: True
flowr states deploy.yaml            →  prepare, execute, review
flowr next deploy.yaml review       →  approve → deployed [blocked]  need: score=>=80
                                      →  reject → failed
flowr transition deploy.yaml review approve --evidence score=85
                                      →  from: review, to: deployed
flowr session init deploy-flow       →  session created at state: prepare
flowr --session transition approve  →  from: prepare, to: review
flowr mermaid deploy.yaml           →  stateDiagram-v2 ...

Validation. Structural constraints — missing fields, ambiguous targets, cross-flow cycles, subflow exit contracts — checked against the specification.

Query. States, transitions, conditions, attributes — ask any question the flow can answer.

Sessions. Init, show, set-state, transition, list. Subflow push/pop for nested workflows. Auto-enters initial subflow on session init. One --session flag turns any command session-aware.

Config. flowr config shows where every value comes from — default, pyproject.toml, or CLI override.

Mermaid export. Generate state diagrams from any flow definition.


Quick start

Install:

pip install flowr

Requires Python 3.13+.

Define a flow:

flow: deploy
version: 1.0.0
exits: [deployed, failed]

states:
  - id: prepare
    next:
      ready: execute

  - id: execute
    next:
      success: deployed
      error: failed

  - id: review
    next:
      approve:
        to: deployed
        when: { score: ">=80" }
      reject: failed

Use it:

$ flowr validate deploy.yaml
valid: True

$ flowr states deploy.yaml
prepare
execute
review

$ flowr next deploy.yaml review
state: review
  approve  deployed [blocked]  need: score=>=80
  reject  failed

$ flowr transition deploy.yaml review approve --evidence score=85
from: review
trigger: approve
to: deployed

$ flowr session init deploy-flow
flow: deploy-flow
state: prepare
name: default

$ flowr --session transition approve
from: prepare
trigger: approve
to: review

$ flowr session show
flow: deploy-flow
state: review
name: default
stack: (none)

$ flowr config
project_root = /my/project  (default)
flows_dir = .flowr/flows  (default)
sessions_dir = .flowr/sessions  (default)
default_flow = main-flow  (default)
default_session = default  (default)

Who is this for?

Specification adopters

You build editors, visualizers, CI systems, or orchestration layers. You need a structural format for workflow state machines — not an execution engine. The flowr specification gives you states, transitions, guard conditions, and subflows in a declarative YAML format with a conforming validator. Any tool can parse it. Read the spec.

Agent operators

You run flowr check, then flowr transition, then flowr check again — each time passing the flow name and current state by hand. Or you let sessions track it: flowr session init deploy-flow, flowr --session transition approve, flowr --session check. The session file remembers where you are. Push into a subflow; pop back out. No state to reconstruct, no context to pass.

Developers

You write a flow YAML. You need to know: is it valid? Which states can I reach from here? Does this transition have guard conditions? flowr validate, flowr states, flowr next, flowr check answer these questions — from the terminal for humans, from the Python library for tools.


CLI Reference

Command Description
flowr validate <flow> Validate a flow definition
flowr states <flow> List all state ids
flowr check <flow> <state> [<target>] Show state details or transition conditions
flowr next <flow> <state> [--evidence K=V] Show all transitions with trigger→target and condition status
flowr transition <flow> <state> <trigger> [--evidence K=V] Compute next state
flowr mermaid <flow> Export as Mermaid state diagram
flowr session init <flow> [--name NAME] Create a new session (auto-enters initial subflow)
flowr session show [--name NAME] [--format FORMAT] Display current session state
flowr session set-state <state> [--name NAME] Update the session's current state
flowr session list [--format FORMAT] List all sessions
flowr config [--json] Show resolved configuration with sources
flowr --session <command> Run a command using session state (works with validate, states, check, next, transition)

<flow> accepts a file path or a short flow name (resolved from .flowr/flows/). Use --flows-dir to override the configured flows directory. All commands accept --json for machine-readable output. Evidence: --evidence key=value (repeatable) or --evidence-json '{"key": "value"}'.


Architecture

flowr/
├── domain/           # Core domain — Flow, State, Transition, Session, conditions, validation
│   ├── flow_definition.py
│   ├── loader.py
│   ├── session.py
│   ├── condition.py
│   ├── validation.py
│   └── mermaid.py
├── infrastructure/   # Adapters — config resolution, session persistence
│   ├── config.py
│   └── session_store.py
├── cli/              # Primary adapter — CLI commands, resolution, output formatting
│   ├── resolution.py
│   ├── session_cmd.py
│   └── output.py
└── __main__.py       # CLI entrypoint — argparse dispatch

Hexagonal architecture. Domain has no infrastructure dependencies. CLI is the primary adapter. Session store is a secondary adapter behind a Protocol port.


Documentation


Development

uv sync --all-extras       # install with dev dependencies
uv run task test            # run tests
uv run task test-fast       # fast tests only
uv run task test-build      # full suite with coverage
uv run task lint            # lint and format
uv run task static-check    # type checking

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

flowr-1.0.0.tar.gz (27.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

flowr-1.0.0-py3-none-any.whl (27.2 kB view details)

Uploaded Python 3

File details

Details for the file flowr-1.0.0.tar.gz.

File metadata

  • Download URL: flowr-1.0.0.tar.gz
  • Upload date:
  • Size: 27.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for flowr-1.0.0.tar.gz
Algorithm Hash digest
SHA256 87e4672b41826d1f7e7f1c0c587427f1bb6b25cf462dc5889a0fb919e599f833
MD5 597d4fe34fa7d713bda73ddfc402b5b6
BLAKE2b-256 0c7322cf442d7dee23efb6b79a30d204c8b8dcef883a37293f495c506d129c8f

See more details on using hashes here.

Provenance

The following attestation bundles were made for flowr-1.0.0.tar.gz:

Publisher: pypi-publish.yml on nullhack/flowr

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file flowr-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: flowr-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 27.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for flowr-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4b1aac01198ee4a14cca6b55299481db955bc111f48a57c228a7f8649d920444
MD5 c7d3081e0e83c7bf327c585d746f7452
BLAKE2b-256 6bea620ffffa51516c809309d8ccc79dddef2b050f851f3a297214b901a9ffb4

See more details on using hashes here.

Provenance

The following attestation bundles were made for flowr-1.0.0-py3-none-any.whl:

Publisher: pypi-publish.yml on nullhack/flowr

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page