.reliant/workflows/, so it is natural to work on it where you work on the code: in an editor, with a terminal beside it. The reliant workflow commands support that loop in two halves.
The first half needs no sign-in, no machine and no network: validate, validate-tree, scenario, eval and list read the files on disk and run the same checks and the same workflow engine the app uses. That makes them quick enough to run on every save and safe to run in CI. The second half talks to Reliant: run starts a workflow, and watch, status, wait-for-gate, answer and their siblings follow and steer it while it runs.
This page walks through one small workflow from first draft to scheduled run. For the YAML format, see Creating custom workflows. For the scenario file format, see Testing workflows.
The example
The workflow runs the project’s tests. If they pass, it records that and stops. If they fail, it hands the failure to an agent to fix. This first draft has a mistake in it, which the next section finds:.reliant/workflows/test-then-fix.yaml
Validate
reliant workflow validate checks every workflow in .reliant/workflows/, or just the file you name. It covers structure, CEL expressions, input and output types, and references between workflows. Run against the draft above, it finds a real mistake:
compute node exists to produce values, so it must declare at least one. Give passed an output:
validate exits 1 when any workflow has an error, so it works as a pre-commit hook or a CI step. Add --json for output a program can read.
reliant workflow validate-tree <ref> goes further for one workflow. It follows every workflow the target calls, through project:// and builtin:// references, and checks presets against the inputs they set. This is the check the server runs when a chat starts. Pass the workflow as a file path, project://<name> or builtin://<name>:
validate --trigger-payload '{…}' also runs each trigger’s filter, inputs mapping and prompt against a sample event. Automations shows how.
Test with scenarios
Validation proves the file is well formed. A scenario proves it behaves as you intend: it runs the workflow on the real engine, with each node’s result supplied by you instead of a real command or model. No model is called and nothing is spent. A scenario lives in.reliant/workflows/<name>/scenarios/, one per file. These two cover both branches:
.reliant/workflows/test-then-fix/scenarios/green_tests_skip_the_agent.yaml
.reliant/workflows/test-then-fix/scenarios/red_tests_go_to_the_agent.yaml
black_box: true stands in for the whole fix sub-workflow, so the scenario tests this workflow’s routing, not the agent’s.
scenario run exits 1 if any scenario fails. --filter runs only scenarios whose name contains a string, and --fail-fast stops at the first failure. The app lists the same scenario files, so the CLI and the app always agree on what is tested.
Try an expression before you commit to it
Conditions and templates are CEL.reliant workflow eval evaluates one against data you supply and prints the value and its type, which is quicker than editing, validating and running a scenario to find out what an expression returns:
null, as it would be in a real run, and the hint says how to guard against it:
--integration github --event issues.opened --scope trigger generates a realistic event payload for you. CEL expressions is the language reference.
Run it
Running a workflow needs you to be signed in and a project to run in. A run is a chat.reliant workflow run starts one exactly as the app would, so the run appears in the app and you can open it there at any time:
--project-path finds the Reliant project at that path, or creates it, so a new checkout needs no setup. --project-id names a project directly. Inputs come from --input key=value (repeatable) or --input-file inputs.json, and --message sets the chat’s first message. The command prints the chat’s ID, which is also the execution ID every supervision command takes.
Supervise it
Pick the command that fits the person, or program, watching:status prints two separate facts, and it is worth knowing the difference. Status is the lifecycle: did the run finish? Outcome is the run’s own verdict: did the work pass? A workflow that fails its checks and ends at a failure node finishes cleanly, so it reads Status COMPLETED, Outcome FAILURE. watch reports such a run as ✗ workflow ended WITHOUT PASSING rather than a tick. Scripting and CI lists the exit code of each command.
When a run asks a question, reliant workflow questions <id> shows it and its options, and reliant workflow answer <id> answers it. Pass --select "<option label>" and/or --text "<feedback>", or give no flags to pick interactively. Combined with wait-for-gate, that makes a supervision loop:
wait-for-gate exits 3 while a gate is open, so the loop continues until the run finishes. pause, resume and terminate do what their names say. A paused run keeps its state and can be resumed later.
Put it on a schedule
reliant trigger create runs a workflow on a cron or interval schedule, on a machine you name with --daemon (its ID or hostname). Scheduled runs are unattended, so the agent is told to decide and proceed instead of asking questions:
trigger list, get, fire (run now), events, enable, disable, update and delete manage it afterwards. Turning an automation on is your decision, so create, update and enable refuse to run from an agent’s shell. Schedules covers schedule options, catch-up after an outage, and overlapping runs.
Related topics
- Creating custom workflows and Testing workflows
- Scripting and CI: running validation and scenarios on every pull request
- CLI reference:
reliant workflowandreliant trigger