run

Validate and execute your workflow. Runs the state machine from the current or initial state until a terminal state is reached.

Usage

raili run                              # Resume or start the main workflow
raili run --clean                      # Force a clean run (clears context, re-prompts for inputs)
raili run --continue                   # Resume from last state
raili run --dry-run                    # Validate workflow and registries without executing
raili run --var key=value              # Supply workflow inputs
raili run --workflow <name>            # Run a named workflow (e.g. .raili/dev/)
raili run --workflow <name> --clean    # Start a named workflow fresh
raili run --next=2                     # Execute the next N states (forces continue mode)
raili run --next                       # Shorthand for `--next=1` (execute the next single state)
raili run --rollback=<N|state>         # Truncate stateHistory and resume from target (forces continue mode)
raili run --resolve-vars [key=val ...] # Use workspace vars-resolver to provide/augment inputs

Examples

Basic run

raili run
# Prompts to continue existing run or start clean

Clean run with inputs

raili run --clean --var ticket_id=PROJ-123 --var branch=main

Named workflow

# Runs .raili/dev/workflow.yaml
raili run --workflow dev --clean --var ticket_id=PROJ-123

Resume from last state

raili run --continue
# Reuses context.json from previous run

Limiting execution with --next

# Execute the next 2 states from the current position (forces continue mode)
raili run --next=2

# Execute exactly one next state (shorthand)
raili run --next

# Resume existing run and execute two more states
raili run --continue --next=2

Multiple input variables

raili run --clean \
  --var ticket_id=TICKET-456 \
  --var description="Fix login bug" \
  --var branch=develop

Workflow Directories

raili run always operates on a workflow directory under .raili/. The --workflow flag selects which one:

Command Workflow directory
raili run .raili/main/
raili run --workflow dev .raili/dev/
raili run --workflow test .raili/test/

The selected directory must already exist and contain a workflow.yaml. Registries (agent-registry.json, script-registry.json) are always loaded from .raili/ root and are shared.

Each workflow directory keeps its own isolated artifacts:

.raili/
├── agent-registry.json        # shared
├── script-registry.json       # shared
├── main/
│   ├── workflow.yaml
│   ├── vars.yaml
│   ├── context.json           # main run state
│   ├── outputs/
│   └── config.json            # optional: resolver & trigger configuration
└── dev/
    ├── workflow.yaml
    ├── vars.yaml
    ├── context.json           # dev run state (independent)
    ├── outputs/
    └── config.json            # optional per-workflow config

config.json (optional) allows tuning resolver and trigger behavior for the workflow. See documentation/approval.md for the supported fields and defaults (trigger.interval, trigger.timeout, trigger.retry_interval, approval.timeout, feedback.timeout).

Dry-run mode

The --dry-run flag performs the full startup validation without entering the runner execution loop. It verifies workflow YAML/schema, builds and validates the state machine, loads and validates shared registries (agent-registry.json, script-registry.json), resolves referenced agent/script files, and (for --clean) reads declared inputs from .raili/<workflow>/vars.yaml and merges CLI flags. Dry-run is non-interactive: it implicitly accepts any skip confirmations and will not prompt for missing inputs. No on-disk artifacts are modified — context, outputs, and the run-log are not written.

Example:

# Validate using vars.yaml and flags, but do not execute handlers
raili run --dry-run

# Validate a named workflow with an inline var
raili run --workflow main --dry-run --var ticket_id=123

Execution Flow

  1. Load & Validate → Reads .raili/ directory, shared registries, and the selected workflow
  2. Initialize Context → On clean run, creates a fresh, deterministic initial context (declared inputs merged with vars and a default workflow variable); on continue, loads saved state and preserves existing workflow value. If --rollback is provided in continue mode, Raili will truncate context.stateHistory according to the supplied value (numeric count or state ID), save the rolled-back context immediately, and then resume execution from the new last entry in the history.
  3. Build State Machine → Converts workflow.yaml into a runtime state DAG
  4. Run Loop → Executes states in order:
    • Enter state (run notify hook if present)
    • Clear outputs (if reset_outputs specified)
    • Execute handler (agent, script, command, or engine)
    • Route based on outcome
    • Save context to <workflow>/context.json

Startup confirmation: If any states in the selected workflow have skip configured, Raili will display a confirmation listing those states and prompt the user: pressing Enter accepts the skips and proceeds; typing any non-empty input cancels the run. In tests or CI you can bypass the interactive prompt by setting the environment variable RAILI_MANUAL_CHOICE=PASSED (accept) or RAILI_MANUAL_CHOICE=FAILED (decline).

  1. Stop → Terminal state reached or error occurred

Input Variables

Declare inputs in workflow.yaml

inputs:
  - ticket_id
  - branch
  - description

Supply values (precedence)

  1. CLI flags (highest priority)

    raili run --var ticket_id=PROJ-123
    
  2. Vars file (optional, git-ignored)

    • .raili/<workflow>/vars.yaml — workflow-specific
    • .raili/vars.yaml — shared fallback
    ticket_id: PROJ-123
    branch: main
    
  3. Interactive prompt (lowest priority, clean runs only)

    ticket_id: PROJ-123
    branch: main
    description: Fix bug
    

Context & Resumption

Raili saves execution state to <workflow>/context.json:

Resume behavior

Named workflow resume behavior

When --workflow is given and no context.json exists, Raili treats the workflow as a fresh run and initializes an empty context so execution proceeds. Use --continue only to resume an existing run; use --clean to explicitly start fresh.

Monitoring

Check last run state

cat .raili/main/context.json | jq '.stateHistory[-1]'

View stored outputs

ls -la .raili/main/outputs/
cat .raili/main/outputs/analyze.md       # Output from 'analyze' state

Error Handling

Fail-fast validation

If any of these fail, execution stops immediately:

Error states

If workflow defines error: error_state, engine routes to that state on unhandled exceptions.

Exit Codes

Tips

Use --clean when:

Use --continue when:

Use --workflow when:

Run log (JSONL)

Raili appends a one-line JSON summary to .raili/<workflow>/run-log.jsonl when a run reaches a terminal state. Each line contains run metadata useful for longitudinal metrics (runId, inputs, state counts, loops, approval failures, terminalState, duration). Use this file to build trend dashboards or telemetry.

Example:

cat .raili/main/run-log.jsonl | jq '.[-1]'