Skip to main content
After this guide, you run a workflow end to end on your machine, force each branch of its graph, and fail a CI job when a step breaks. Use it before every lua push workflow; for the real model and real approvers, start a run on the platform instead. Verified against lua-cli 3.33.0. Before you begin
  • A project with a workflow listed under workflows on its LuaAgent. Only listed workflows are compiled.
  • Signed in with lua auth configure. Code steps run with your credential, so a step that calls Data, AI, or Channels reaches the platform.
1

Run the graph with every decision answered

lua test workflow compiles the project without registering anything on the server and drives the graph in one process. Code steps run for real, agent steps return a fake reply, and approvals are answered from flags.
Output
An agent step with an outputSchema returns an object shaped from the schema (strings '', numbers 0, booleans false); without one it returns { text: '[fake:<id>] <prompt>' }. --deny <id[=@reason]> answers an approval with approved: false and --signal <name=json> supplies a waitForSignal payload. Tool steps and nested workflows cannot run offline: give them an output with --step-output.
2

Force a branch with --step-output

A fake reply never satisfies a predicate, so complete the step the predicate reads with the output you want; the value is validated against the step’s outputSchema before anything runs.
Output
With "priority":"low" the escalate line reads skipped. A value that does not match the schema stops before the run starts, with exit 2 and a line such as step-output-schema --step-output draftEmail: $.subject: required; $.body: required; $.nope: not allowed. The flag repeats and takes @file.
3

Simulate a fault, a retry, and a clock

--park <id> stands in for a platform fault on that step. Offline the run cannot wait for a person, so it fails with exit 4 after printing what the platform would do.
Output
On a terminal the driver offers retry, skip, complete, or fail instead. A step that throws is retried under its retry policy and prints <id> · retry · attempt 2/3; --fast-retries collapses the backoff waits. Sleeps and deadlines run on a virtual clock, and --now <iso> sets its start, so a business-hours escalation needs no waiting.
4

Seed completed steps from a platform run

To re-drive only what did not finish, seed the ledger from a platform run: each completed step whose upstream steps are also seeded keeps its output and once() effects, and the driver starts at the first pending step.
The driver prints [from-run] <n> step(s) seeded from <runId> before the timeline. A run that does not exist exits 3.
5

Record real agent replies and replay them

--agents live sends each agent step to your agent through the platform. --record writes each live reply as a fixture (tool steps never run offline, so nothing else is recorded); --fixtures replays them without a model in the loop.
A fixture is <dir>/<stepId>.<attempt>.json holding { input, output, ms }; only output is replayed, and a step without one fails the run with exit 5:
Output
6

Verify in CI

In CI, stdin is not a terminal, so anything left unanswered ends the run with exit 2 and a line such as APPROVAL_UNANSWERED approval "reviewDraft" needs --approve/--deny reviewDraft (no interactive stdin). --ci makes a prompt on a developer’s terminal fail instead of waiting.
--json prints one document on stdout, { "success": true, "data": { "status", "output", "exitCode", "ledger" } }, sends the compile lines to stderr, and prints no timeline. The exit code is the verdict:

Options you may need

lua workflows run and --env

lua workflows run <name> is the same driver with every flag on this page plus --env KEY=value, a local overlay for env.template('KEY') placeholders; a placeholder with no value exits 2 with env-template-missing, and the values never reach the ledger.

Job-tier steps

A step with tier: 'job' gets ctx.workspace, ctx.exec, and ctx.$ only with --workspace <dir>, the checkout to run in; --job-wall <s> fakes a long coding turn as 14,400-second segments. See Use the Job tier.

The ledger

--ledger-out <file> writes the run as JSON: runId, workflowId, graphHash, status, input, steps, state, effects (settled once() results), events, and output. --artefacts-dir <dir> backs ctx.artefacts on disk; without it, put and get throw.

If it isn’t working

A toolStep has no offline executor. Supply its output with --step-output <id>=<json> or a fixture; a nested .workflow() step reports SUBRUN_NOT_SUPPORTED_OFFLINE and takes the same fix.
A Job-tier step called ctx.exec or ctx.$ without --workspace <dir>. Pass the directory the step should run in.
A step called ctx.suspend() and no terminal was attached to type its resumeData. Run the command in a terminal without --ci, or complete the step with --step-output <id>=<json>.

Next steps

Operate runs

Start, watch, approve, and repair runs on the platform.

lua test reference

Every workflow flag and its default.

Automate releases in CI

Exit codes, --ci, and the JSON envelope across the CLI.

Author a workflow

Bindings, predicates, retries, and the script form.