You write the steps in plain YAML. Deterministic code runs them in order, tests every output, retries what fails, and resumes exactly where it stopped — leaving proof of everything in a plain folder.
Quickstart · How it works · Commands · Examples · Docs
AI agents are great at doing work and unreliable at following plans:
- they skip steps when the context gets long;
- they declare unfinished work done — confidence is not a test;
- they lose everything when a step fails halfway through.
Agent Workflows flips who is in charge. A model may write a step's content,
but plain code decides what runs next, and a real test — the gate, an
ordinary shell command — decides pass or fail. An agent cannot talk its
way past exit 1.
python3 -m pip install "git+https://github.com/ali-abassi/agent-workflows.git@v0.2.0"
piw doctor # → status: agent-readyCreate and run your first workflow — no model, no API key, zero cost:
piw create hello
piw run hello --input Ada --strict --json{"ok": true, "run": "hello-20260823-232621", "status": "completed",
"steps": {"normalize": "passed", "result": "passed"}}That receipt is real, and so is the folder behind it:
$ ls hello/runs/hello-20260823-232621/
input.txt log.md normalize.md result.md state.json workflow.yaml
ledger.json manifest.json run-owner.json run.lock trace.jsonl .git/
The frozen input, every step's output, a full timeline, git history of the run — and a ledger of what each step actually cost:
{"id": "analyze", "model": "openai-codex/gpt-5.6-luna", "attempts": 1,
"passed": true, "seconds": 8.3, "input": 5288, "output": 168, "cost": 0.0012592}Prefer an isolated install? pipx install "git+https://github.com/ali-abassi/agent-workflows.git@v0.2.0" —
or see the setup guide for source checkouts and troubleshooting.
flowchart LR
A["📄 steps.yaml"] -->|piw run| B["deterministic runner"]
B --> C["step executes<br/>shell · claude · codex · pi"]
C --> D{"gate:<br/>a real test"}
D -->|pass| E["next eligible step"]
D -->|fail| F["bounded retry"]
F --> C
F -->|budget spent| G["run stops loudly"]
G -->|fix cause, piw resume| C
E --> H[("runs/ folder<br/>of proof")]
- You describe the steps — each with a command (or prompt), what it needs, and a gate that proves it worked.
- Code runs the graph — dependency order, typed routing, bounded retries, timeouts, and parallel dispatch of independent steps are all deterministic.
- Every output faces its gate — a shell command that checks the artifact, not the model's confidence.
- Nothing is lost — a failed run stops with state intact;
piw resumeverifies the workflow hasn't drifted and continues from the exact step.
A complete workflow is this small:
version: 1
workflow: uppercase
input:
required: true
description: One immutable string
steps:
- id: transform
cmd: tr '[:lower:]' '[:upper:]' < "$INPUT"
gate: tr '[:lower:]' '[:upper:]' < "$INPUT" | cmp - "$OUT"
- id: report
needs: [transform]
cmd: printf 'Result: %s\n' "$(cat "$RUN/transform.md")"
gate: grep -q '^Result: ' "$OUT"| You want to | Run |
|---|---|
| Start a new workflow file | piw create NAME |
| Check the file is valid (free, nothing executes) | piw validate NAME --strict |
| See the step order before running | piw graph NAME |
| Execute the workflow | piw run NAME --input "..." --strict --json |
| See what a run did, produced, and cost | piw inspect NAME --json |
| Continue a stopped or failed run | piw resume NAME RUN_ID --json |
| Check your machine is ready | piw doctor |
Every command has --help; every receipt is available as JSON, so agents can
operate piw as easily as humans.
Any agent — or any human — can use this in two roles:
- As the operator.
piwis a plain CLI with--jsonreceipts, so Claude Code, Codex, Pi, or a shell script can create, validate, run, inspect, and resume workflows. - As a node runtime. A
cmd:node wraps any non-interactive agent command, and the gate judges its output like any other node. Nativeprompt:nodes run through the Pi CLI with per-step model, thinking, schema, and tool pins.
examples/any-agent.steps.yaml runs Claude
Code and Codex side by side, gated identically:
{"ok": true, "status": "completed",
"steps": {"claude-code": "passed", "codex": "passed", "combine": "passed"}}To add native model nodes:
npm install -g @earendil-works/pi-coding-agent
pi # authenticate once
piw create review --template agent --model openai-codex/gpt-5.6-luna
piw run review --input-file request.md --strict --jsonModel calls are isolated and pin their model and thinking level. Tool selection is routing — not operating-system sandboxing.
Reach for Agent Workflows when:
- a job has more than one step and skipping or fudging a step is not acceptable — releases, migrations, content pipelines, review chains;
- a human must approve a checkpoint midway, and the job should stop and later resume exactly there;
- you need to show what ran, what it produced, and what it cost.
Skip it when a single command or one-off prompt does the job — or when you need something on this list:
| If you need | Use |
|---|---|
| Org-wide orchestration with a server, database, and durable timers | Temporal, Prefect, Dagster |
| Graphs wired in Python around one agent framework | LangGraph |
| File-timestamp incremental builds | Make |
| A local, auditable run contract for agent work | Agent Workflows |
The bet is auditability over throughput: gates are shell commands, state is a
readable directory, resume is fingerprint-verified — no server, no daemon, no
database. A run is a folder you can ls, diff, and commit.
- Validated YAML DAG with explicit and inferred dependencies.
- Four node runtimes: shell command, isolated completion, allowlisted tools, full agent loop.
- Typed JSON output contracts and code-owned conditional routing (
when:). - Mechanical gates that check artifacts or side effects — not model confidence.
- Classified, bounded retries with fixed or exponential delay and deterministic jitter.
- Concurrent dispatch of dependency-ready nodes (
workers:, default 4);needs:is the serialization guarantee. - Immutable per-run input and frozen workflow fingerprints (drift is refused).
- Atomic state, contiguous JSONL trace, one-writer locking, crash recovery.
- Content-addressed cache, per-step cost ledger, inspectable Git history.
- Optional per-step LLM
judge:loops and a final independentqa:review.
Full reference: usage guide · architecture · workflow schema.
The test suite exercises atomic-write failures, bootstrap recovery, one-writer locking, concurrent transitions, torn traces, workflow drift, immutable input, branch skips, SIGKILL recovery, and surgical resume. CI runs on Linux and macOS with Python 3.10 and 3.14, builds the wheel, installs it into a clean environment, and executes the installed command.
That evidence supports the kernel behavior tested here. It is not a claim that arbitrary workflows are safe or that model output is deterministic.
Alpha software; macOS and Linux with Python 3.10+. Workflow commands execute with your user permissions — review third-party workflows and use a container or isolated account when filesystem, process, network, or credential isolation matters. Read SECURITY.md before running untrusted workflows, and never place credentials in workflow files, prompts, command arguments, or committed run artifacts.
This repo is the reduced, public kernel of
ali-abassi/pi-graph; Studio, batch
processing, evaluations, scheduling, and hosted worker fleets live there. The
projects share the steps.yaml contract.
Setup · Usage · Architecture · Examples · Changelog · Security · Contributing · MIT license