# 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](https://github.com/Industrial/definitively/blob/main/docs/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):
```yaml
# devenv.yaml
inputs:
definitively-repo:
url: github:OWNER/REPO # or url: . / inputs.repo when developing in-tree
flake: true
```
```nix
# 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):
```bash
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:
```bash
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)
```bash
curl -fsSL https://raw.githubusercontent.com/Industrial/definitively/main/install.sh | bash
```
Pin a version:
```bash
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](https://github.com/Industrial/definitively/releases).
### Homebrew tap
```bash
brew tap idcleartomwieland/tap https://github.com/idcleartomwieland/homebrew-tap
brew install definitively
```
Or install the formula directly:
```bash
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`](../.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:
```bash
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` (`TRACE` … `ERROR`, default `INFO`) for run visibility.
### Run a workflow
Pass the **full path** to a program YAML under `.definitively/`:
```bash
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:
```bash
definitively visualize "$PWD/.definitively/programs/dev-quality-loop.yml"
# → .definitively/visualizations/dev-quality-loop.dot
# → .definitively/visualizations/dev-quality-loop.png
```
Single-format overrides:
```bash
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/`:
```bash
mix definitively run ../.definitively/programs/dev-quality-loop.yml
```
## Development (devenv)
From the repo root:
```bash
devenv shell
mix-setup # first time: hex, rebar, deps
mix-test # ExUnit
```
Inside `definitively/`:
```bash
mix test
mix format
iex -S mix
```
Build the escript locally (also run automatically when `DEFINITIVELY_FROM_SOURCE=1`):
```bash
cd definitively && mix escript.build
export PATH="$(pwd):$PATH"
```
## Quality gates (moon)
From the repo root (devenv shell):
```bash
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 docs` → `doc/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)
```