Definitively

FSM-based workflow runner for CLI commands, LLM sessions, and git steps.

States are implemented with OTP :gen_statem in Definitively.Workflow.Engine. Node evaluators return Definitively.Outcome values (not raw exit codes).

Full distribution guide (consumer devenv, all install channels, workspace layout): definitively-distribution.md.

Installation

Pick one channel. All ship the same definitively escript CLI.

devenv flake input (recommended for Nix/devenv repos)

Add the repo as a flake input and import its devenv module (provides definitively + graphviz on PATH):

# devenv.yaml
inputs:
  definitively-repo:
    url: github:OWNER/REPO  # or url: . / inputs.repo when developing in-tree
    flake: true
# devenv.nix
{ inputs, ... }: {
  imports = [
    inputs.definitively-repo.devenvModules.definitively
  ];
}

Then devenv shell — the definitively binary is on PATH.

When developing the Mix project inside this repo, set DEFINITIVELY_FROM_SOURCE=1 before devenv shell to build the escript from definitively/ on enter instead of using the flake package.

Nix flake

From a checkout (or after adding the repo as a flake input):

nix build github:OWNER/REPO#definitively
./result/bin/definitively --help  # via usage on unknown args

Or from the repo root: nix build .#definitively.

Hex

When published on Hex:

mix local.hex --force
mix escript.install hex definitively --force
export PATH="$(mix escript.install_path):$PATH"

Requires Elixir ~> 1.18 and Erlang/OTP 27+ on PATH. Add $HOME/.mix/escripts to PATH if needed.

GitHub releases (curl installer)

curl -fsSL https://raw.githubusercontent.com/Industrial/definitively/main/install.sh | bash

Pin a version:

curl -fsSL https://raw.githubusercontent.com/Industrial/definitively/main/install.sh | bash -s -- --version definitively-v0.1.0

Release tarballs are named definitively-<version>-<platform>.tar.gz (platforms: linux-x86_64, darwin-arm64). See GitHub releases.

Homebrew tap

brew tap idcleartomwieland/tap https://github.com/idcleartomwieland/homebrew-tap
brew install definitively

Or install the formula directly:

brew install --formula https://raw.githubusercontent.com/Industrial/definitively/main/homebrew-tap/Formula/definitively.rb

Runtime dependencies

Tool Required? Used by
Erlang/OTP 27+ Yes (Hex/source installs) escript interpreter; bundled/wrapped by the Nix flake package
Elixir 1.18+ Build only (Hex/source) mix escript.build / mix escript.install
Graphviz dot Optional definitively visualize default mode (PNG output); DOT-only works without dot
moon Optional CLI nodes in programs that invoke moon run …
cursor-agent Optional LLM nodes (e.g. dev quality loop fix steps)
git Optional CLI nodes that run git commands in your program YAML

The devenv module adds definitively and graphviz. Other tools are workflow-specific — see your program YAML and .definitively/env.example.

Workspace layout

Programs must live under a .definitively/ directory. The workspace root is the parent of .definitively/ (override with DEFINITIVELY_WORKSPACE).

Scaffold a new workspace from packaged templates:

cd /path/to/your/repo
definitively init              # copies into ./.definitively/ (skips existing files)
definitively init --force      # overwrite existing template files

Templates include programs/example.yml, prompts/example.md, env.example, and visualizations/.gitkeep.

CLI

Set DEFINITIVELY_LOG_LEVEL (TRACEERROR, default INFO) for run visibility.

Run a workflow

Pass the full path to a program YAML under .definitively/:

definitively run "$PWD/.definitively/programs/dev-quality-loop.yml"

On success prints workflow finished and exits 0. Approval gates that cannot auto-approve exit 2.

Visualize a program

Default mode writes both DOT and PNG under .definitively/visualizations/<program-basename> and prints the output paths:

definitively visualize "$PWD/.definitively/programs/dev-quality-loop.yml"
# → .definitively/visualizations/dev-quality-loop.dot
# → .definitively/visualizations/dev-quality-loop.png

Single-format overrides:

definitively visualize program.yml --format dot
definitively visualize program.yml --format png --out /tmp/my-workflow
definitively visualize program.yml --format svg

--format png or svg requires Graphviz dot on PATH. If PNG compilation fails, DOT is still written when using default mode.

Mix task (contributors)

Inside definitively/:

mix definitively run ../.definitively/programs/dev-quality-loop.yml

Development (devenv)

From the repo root:

devenv shell
mix-setup    # first time: hex, rebar, deps
mix-test     # ExUnit

Inside definitively/:

mix test
mix format
iex -S mix

Build the escript locally (also run automatically when DEFINITIVELY_FROM_SOURCE=1):

cd definitively && mix escript.build
export PATH="$(pwd):$PATH"

Quality gates (moon)

From the repo root (devenv shell):

moon run definitively:lint definitively:doctor definitively:test definitively:docs definitively:build
Task What it checks
definitively:lint Credo --strict
definitively:doctor@moduledoc / @doc / @spec coverage (see .doctor.exs)
definitively:test ExUnit + doctests
definitively:docs ExDoc build with --warnings-as-errors
definitively:build Full chain + mix compile --warnings-as-errors

Git hooks: pre-commit runs :format + definitively:doctor; pre-push runs :format + definitively:build (tests, coverage, ExDoc, compile).

Generate HTML docs locally: cd definitively && mix docsdoc/index.html.

Toolchain: Erlang/OTP 27 + Elixir 1.18 (pinned in devenv.nix).

Module layout

lib/definitively/
  outcome.ex           # NodeResult / status
  workflow/engine.ex   # data-driven gen_statem FSM
  nodes/               # CLI and LLM evaluators
  init.ex              # .definitively/ workspace scaffold
  visualize.ex         # Graphviz program graphs
  cli.ex               # CLI entry (escript + Mix task)