orc

module
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 23, 2026 License: MIT

README

orc

Deterministic agent orchestrator CLI — run AI workflows as a state machine, not a conversation.

What is orc?

LLM agents that self-manage multi-phase workflows are unreliable. They lose context, skip steps, and hallucinate progress. orc takes a different approach: a deterministic state machine drives the workflow, and context passes through artifact files on disk — not conversational memory.

You define your workflow as a series of phases in a YAML config file. Each phase is a shell script, an AI agent invocation, a human approval gate, a sub-workflow, or a branch that routes to different workflows based on a check script. orc runs them in order, persists state after each phase, and can resume from where it left off if interrupted.

Features

Workflow Engine
  • Five phase types: script (shell commands), agent (Claude AI via claude -p), gate (human approval with feedback), workflow (run a named sub-workflow inline), branch (N-way dispatch to a workflow based on a check script)
  • Convergent loops: Phases can loop back with loop for retry-on-failure and min-iteration enforcement, with optional on-exhaust recovery
  • Parallel execution: Run two phases concurrently with parallel-with
  • Conditional phases: Skip phases based on a shell command exit code
  • Pre-run / post-run hooks: Shell commands that bracket phase dispatch — start services before, clean up after
  • Output validation: Declare expected output files; agents are re-prompted once if outputs are missing
  • Multi-workflow support: Define multiple named workflows (bugfix, refactor, etc.) under .orc/workflows/ with isolated artifacts per workflow
Configuration
  • Variable substitution: $TICKET, $ARTIFACTS_DIR, $WORK_DIR, $PROJECT_ROOT, $WORKFLOW expanded in prompts and commands
  • Custom variables: Define project-specific variables under vars: that reference built-ins and each other
  • Per-phase model and timeout: Choose opus, sonnet, or haiku per agent phase
  • Per-phase working directory: Set cwd on script/agent phases for worktree workflows
  • Cost budgets: Set per-run and per-phase spending limits with max-cost
  • Tool approval: Configure which tools agents can use with default-allow-tools and allow-tools
  • MCP server support: Connect agent phases to MCP servers with mcp-config
Execution Modes
  • Attended mode: Steer agent phases interactively — provide follow-up instructions, approve denied tools, answer agent questions
  • Unattended mode: --auto skips gates and disables all interactive prompts
  • Step-through mode: --step pauses after each phase — continue, rewind to a previous phase, inspect artifacts, or abort
  • Dry-run mode: Preview the phase plan without executing anything
  • Resume from interruption: State is saved after every phase — Ctrl+C and resume with --resume to continue the agent session
Developer Tools
  • orc test: Run a single phase in isolation for rapid prompt iteration — no need to execute the full workflow
  • orc debug: Analyze a phase execution — rendered prompt, tool call sequence, cost/token data, and exit status
  • orc doctor: AI-powered diagnostics for failed runs — gathers logs, timing, and feedback, then recommends next steps
  • orc improve: AI-assisted workflow refinement — one-shot or interactive editing of config and prompts
  • orc eval: Run eval cases against known scenarios to measure workflow quality, cost, and time — compare before and after workflow changes, with a held-out grader the agent never sees
  • orc flow: Visualize the workflow as a rich flow diagram with loop regions, model badges, and hook annotations
  • Prompt recipes: orc init --recipe scaffolds from proven workflow patterns (simple, standard, full-pipeline, review-loop)
Observability
  • Full audit trail: Rendered prompts, agent logs, cost/token data, timing, and state all saved to .orc/artifacts/
  • orc report: Generate a run summary with timing, costs, phase outcomes, loop activity, and artifact listing — markdown or JSON
  • orc stats: Aggregate metrics across runs — success rate, cost/duration distributions, per-phase breakdown, failure categories, and weekly trends
  • orc eval: Measure workflow quality, cost, and time across eval cases pinned to known git refs — track score trends across config and rubric changes, and re-grade saved runs without re-running them
  • Structured exit codes: 0 (success), 1 (phase failure), 2 (timeout), 3 (config error), 4 (cost limit), 5 (interrupted), 6 (resume failure), 7 (infrastructure error), 8 (rate limit)

Prerequisites

  • Go 1.22+ — for building from source
  • Claude CLI — install from claude.ai/code. orc invokes claude -p for agent phases.

Installation

Quick install (Linux / macOS) — downloads the latest release binary, verifies its checksum, and installs it:

curl -sSL https://raw.githubusercontent.com/jorge-barreto/orc/main/scripts/install.sh | sh

The script auto-detects your OS and architecture (linux/darwin × amd64/arm64) and installs to /usr/local/bin when writable, otherwise ~/.local/bin. Override with environment variables:

# Pin a specific version
curl -sSL https://raw.githubusercontent.com/jorge-barreto/orc/main/scripts/install.sh | ORC_VERSION=v0.1.0 sh

# Install to a custom directory
curl -sSL https://raw.githubusercontent.com/jorge-barreto/orc/main/scripts/install.sh | ORC_BIN_DIR=$HOME/bin sh

Prefer to read before you run? Inspect scripts/install.sh, or grab a tarball directly from the Releases page.

Homebrew (macOS / Linux):

brew install jorge-barreto/tap/orc

Go install (pin a released version):

go install github.com/jorge-barreto/orc/cmd/orc@v0.1.0

From source:

make install  # installs to $GOPATH/bin, stamped from the VERSION file (git-describe fallback)

Upgrading: if you installed the release binary (via the install script or a tarball), run orc update to fetch and verify the latest release in place. For Homebrew use brew upgrade orc; for a Go install re-run go install github.com/jorge-barreto/orc/cmd/orc@latest.

Quick Start

# 1. Initialize a new project
cd your-project
orc init                                         # auto-detect
orc init "data pipeline with validation loop"    # or guide with a description
orc init --recipe standard                       # or start from a built-in recipe

# 2. Edit .orc/config.yaml to define your workflow

# 3. Preview the plan
orc run EXAMPLE-1 --dry-run

# 4. Run for real
orc run EXAMPLE-1

CLI Reference

orc init

Analyzes your project and generates a tailored workflow config using AI. Falls back to a default template if AI generation fails.

orc init                                    # auto-detect project and generate workflow
orc init "microservice with integration tests"  # guide generation with a description

Optionally pass a natural-language description to guide the generated workflow toward a specific shape. The description supplements the auto-detected project context.

Creates .orc/config.yaml and one or more .orc/phases/*.md prompt templates named after your workflow phases (e.g., plan.md, implement.md). Also creates .orc/.gitignore to exclude the artifacts directory.

Alternatively, scaffold from a built-in recipe for a proven workflow pattern:

orc init --recipe simple                         # minimal plan → implement → review
orc init --recipe standard                       # quality-assured pipeline with test loop
orc init --recipe full-pipeline                  # AI self-review + human gate
orc init --recipe review-loop                    # convergent AI review loop
orc init --list-recipes                          # show all available recipes
orc init --add-workflow bugfix                   # add a named workflow
orc init --add-workflow bugfix --recipe simple   # add from a recipe

Recipes are deterministic — no AI generation required. The description argument is ignored when --recipe is set.

orc run <ticket>

Runs the workflow for the given ticket identifier.

orc run PROJ-123
orc run PROJ-123 --auto        # unattended — skip gates, no steering
orc run PROJ-123 --dry-run     # preview without executing
orc run PROJ-123 --retry 3           # retry from phase 3
orc run PROJ-123 --from implement    # start from the "implement" phase
orc run PROJ-123 --from 2            # still works with numbers
orc run PROJ-123 --verbose     # save raw stream-json output
orc run PROJ-123 --resume      # resume interrupted agent session
orc run PROJ-123 --step        # step through phases interactively
orc run PROJ-123 --headless    # non-interactive — JSONL output for CI/CD
orc run bugfix PROJ-123         # named workflow (positional)
orc run -w bugfix PROJ-123      # named workflow (explicit flag)
Flag Description
--auto Unattended mode — skip all gates, no interactive steering
--dry-run Print the phase plan without executing
--retry <phase> Retry from phase (number or name), resets loop counts
--from <phase> Start from phase (number or name), resets loop counts
--verbose, -v Save raw stream-json output to .stream.jsonl files in the logs directory
--resume Resume an interrupted agent phase using saved Claude session ID
--step Step-through mode — pause after each phase for inspection
--headless Non-interactive mode — JSONL output, implies --auto, disables color
--workflow, -w Select a named workflow from .orc/workflows/

--retry, --from, and --resume are mutually exclusive.

Attended vs auto mode: By default, orc runs in attended mode — you can type follow-up instructions to steer agent phases, if an agent attempts a tool that wasn't pre-approved, orc prompts you to approve it, and if the agent asks a question (via AskUserQuestion), orc displays it and collects your answer. With --auto, orc runs fully unattended with no stdin interaction.

Step-through mode: --step pauses after each phase with an interactive prompt. You can continue, rewind to a previous phase (forward jumps are rejected), abort, or inspect artifact files. Incompatible with --auto.

Headless mode: --headless (or ORC_HEADLESS=1) runs in fully non-interactive mode — implies --auto (gates auto-approved, no steering), disables ANSI color, and emits machine-readable JSONL instead of decorated text. One JSON line per phase transition to stdout: {"phase":"plan","status":"started"}, {"phase":"plan","status":"complete","duration_s":120.5}. Errors remain on stderr as plain text. Exit codes (0 = success, 1 = phase failure, 2 = timeout, 3 = config error, 4 = cost limit, 5 = interrupted, 6 = resume failure, 7 = infrastructure error, 8 = rate limit) are the primary status signal. Incompatible with --step. Useful for CI/CD pipelines, cron jobs, launchers, monitoring dashboards, and log aggregation.

Color control: orc disables color when any of these are true: --no-color flag is passed, NO_COLOR env var is set (standard no-color.org convention), ORC_NO_COLOR env var is set, or stdout is not a TTY (e.g., piped output). --headless disables color and switches to JSONL output. The --no-color flag is global and works on any command.

orc flow

Visualizes the workflow config as a rich flow diagram with bracket-loop regions, phase icons, model badges, and color.

orc flow                  # colored flow diagram
orc flow --no-color       # without ANSI colors
Flag Description
--no-color Disable colored output
orc status [ticket]

Shows workflow progress. With a ticket argument, shows detailed phase-by-phase execution trace with timing, costs, token counts, and artifacts listing. Without an argument, lists all tickets with their status and cost.

orc status               # list all tickets
orc status PROJ-123      # detailed view for one ticket
orc report [ticket]

Generate a readable summary of a completed, failed, or interrupted run.

orc report                    # report for most recent ticket
orc report PROJ-123           # report for a specific ticket
orc report --json             # structured JSON output for tooling
orc report -w bugfix PROJ-123 # report for a named workflow

Shows status, duration, cost, per-phase results, loop activity, and artifact listing. Missing data (no costs.json, no timing.json) shows "—" placeholders. Use --json for a stable, versioned JSON schema suitable for CI pipelines and dashboards.

orc docs [topic]

Shows built-in documentation. With no argument, lists available topics. With a topic name, prints the full article.

orc docs               # list topics
orc docs config        # config file reference
orc docs variables     # template variables and custom vars
orc docs phases        # phase type details

Topics: quickstart, config, phases, variables, runner, artifacts, quality-loops, workflows, eval.

orc improve [instruction]

AI-assisted workflow refinement. Two modes:

orc improve "add a lint phase parallel with tests"    # one-shot
orc improve                                            # interactive

One-shot mode: Reads your current config and prompt files, sends them to Claude with your instruction, validates the output, and writes changed files.

Interactive mode: Launches Claude in interactive mode with your workflow context pre-loaded for a conversational editing experience.

orc validate

Validates .orc/config.yaml without running anything. Useful for checking config before committing.

orc validate
orc validate --config path/to/config.yaml
orc cancel <ticket>

Cancels a ticket and archives its artifacts to history. Audit data (costs, timing, archived logs) is preserved by rotating to a timestamped directory.

orc cancel PROJ-123
orc cancel PROJ-123 --force    # cancel even if a run appears active
orc cancel PROJ-123 --purge    # remove all artifacts including history
orc history [ticket]

Lists past runs for a ticket with status, date, duration, and cost. Completed runs are archived immediately. Failed or interrupted runs stay in place for --resume/--retry, and are archived automatically when the next fresh orc run starts.

orc history                     # most recent ticket
orc history PROJ-123            # specific ticket
orc history --prune             # remove entries beyond the history limit
orc stats [ticket]

Cross-run aggregate metrics — success rate, cost/duration distributions, per-phase breakdown, failure categories, and weekly cost trends.

orc stats                    # aggregate across all tickets
orc stats KS-42              # aggregate for a single ticket
orc stats --last 20          # limit to last N runs
orc stats --json             # structured JSON output
orc eval [case]

Run eval cases to measure workflow quality. Each case is defined in .orc/evals/<case>/ with a fixture.yaml (git ref + ticket + a required spec: field naming the agent-visible spec file) and a rubric.yaml (scoring criteria). orc replays the workflow in an isolated git worktree, then scores results against the rubric.

The grader is held out: orc removes the entire .orc/evals/ directory from the worktree before the workflow runs, so the agent never sees the rubric, judge prompts, or held-out tests — the grader is read from your live project at grade time only. As an opt-in convenience, orc exports ORC_EVAL=1 and ORC_SPEC_FILE=<abs path> so a workflow that normally fetches a ticket from an external store can read the local spec instead (self-contained workflows need no change).

Grading is separable: --regrade re-scores a saved run against the current rubric without re-running the workflow. It's a boolean flag — the optional run-id is a second positional argument.

orc eval                     # run all eval cases
orc eval bug-fix             # run a specific case
orc eval bug-fix --regrade            # re-grade the latest saved run (no workflow re-run)
orc eval bug-fix --regrade <run-id>   # re-grade a specific saved run
orc eval --report            # show score history (workflow + rubric fingerprints)
orc eval --list              # list available eval cases
orc eval --json              # structured JSON output

See orc docs eval for the full reference — fixture/rubric schema, judge criteria, the eval-mode contract, and fingerprinting.

orc doctor <ticket>

Diagnoses a failed workflow run using AI. Gathers the failed phase's config, logs, rendered prompt, feedback files, timing data, and loop iteration history, then sends everything to Claude for analysis. Recommends whether to --retry, --from, or fix-first.

orc doctor PROJ-123
orc test <phase> <ticket>

Runs a single phase in isolation for testing prompts and scripts without running the entire workflow. Sets up the full environment (variables, artifacts dir) as if the workflow were running, dispatches only the specified phase, and does not modify state or advance the workflow.

orc test plan KS-42              # run just the "plan" phase
orc test implement KS-42         # run just "implement"
orc test 3 KS-42                 # run phase 3 (1-indexed)
orc test -w bugfix fix KS-42     # test a phase from a named workflow
Flag Description
--auto Unattended mode — skip gates, no interactive steering
--verbose, -v Save raw stream-json output to .stream.jsonl files
--with-hooks Run pre-run and post-run hooks around the phase dispatch
--headless Non-interactive mode — JSONL output, implies --auto, disables color

Missing artifacts from prior phases produce a warning listing which files are absent and which earlier phases normally create them.

By default, pre-run and post-run hooks do not run during orc test. Use --with-hooks to execute them with the same semantics as a full workflow run. Without the flag, hooks are skipped and hook side effects (e.g., starting/stopping services) will not occur.

orc debug <phase> [ticket]

Analyzes a phase execution — shows the rendered prompt, tool call sequence, cost/token data, feedback injection, and exit status. Useful for understanding why a phase produced unexpected results without manually reading raw log files.

orc debug plan                    # analyze most recent ticket's "plan" phase
orc debug plan KS-42              # analyze a specific ticket's phase
orc debug 2                       # analyze phase by index (1-indexed)
orc debug -w bugfix plan KS-42    # analyze a phase from a named workflow

When no ticket is specified, analyzes the most recently executed ticket.

orc update

Update orc to the latest release. Downloads the matching release tarball, verifies it against the published checksums.txt, and atomically replaces the running binary. Downloads are verified against the release's published SHA-256 checksums (the same integrity check the install script uses); there is no separate signature.

orc update            # install the latest release in place
orc update --check    # report whether an update is available; install nothing
orc upgrade           # alias for orc update

Binaries installed via Homebrew or go install aren't replaced — orc detects them and points you at brew upgrade orc or go install github.com/jorge-barreto/orc/cmd/orc@latest.

Configuration Reference

Workflows are defined in .orc/config.yaml.

Top-level fields
Field Type Required Description
name string Yes Project name
ticket-pattern string No Regex pattern for ticket IDs (anchored automatically for full-match)
model string No Default model for all agent phases: opus, sonnet, or haiku. Per-phase model overrides this.
effort string No Default effort for all agent phases: low, medium, or high. Per-phase effort overrides this.
cwd string No Default working directory for script and agent phases (expanded with vars). Per-phase cwd overrides this. Not applied to gate phases.
max-cost float No Per-run cost budget in USD. Workflow stops if cumulative cost exceeds this.
history-limit int No Maximum archived runs per ticket (default 10)
default-allow-tools list No Tools auto-approved for all agent phases, merged with built-in defaults.
vars map No Custom variables expanded at startup (declaration order)
phases list Yes Ordered list of phases
Phase fields
Field Type Default Description
name string Unique phase name (required). Must not contain path separators.
type string script, agent, gate, workflow, or branch (required)
description string Human-readable description
run string Shell command (required for script)
prompt string Path to prompt template file, relative to project root (required for agent)
model string opus Claude model: opus, sonnet, or haiku (agent only). Overrides top-level model.
effort string high Effort level: low, medium, or high (agent only). Overrides top-level effort.
timeout int 30 (agent), 10 (script) Timeout in minutes
max-cost float Per-phase cost budget in USD (agent only). Workflow stops if phase cost exceeds this.
outputs list Expected output filenames in artifacts dir
allow-tools list Additional tools to approve for this agent phase, merged with default-allow-tools and built-in defaults
mcp-config string Path to MCP server config file (agent only). Supports variable expansion. Passed as --mcp-config to claude -p. File need not exist at config load time.
condition string Shell command; phase is skipped if exit code is non-zero
parallel-with string Name of another phase to run concurrently
loop object Convergent loop: goto (phase name), min (default 1), max (required), optional check (shell command for pass/fail), optional on-exhaust
cwd string Working directory for this phase (expanded with vars). Not supported on gate phases.
pre-run string Shell command to run before dispatch. Non-zero exit skips dispatch and fails the phase. Post-run still runs.
post-run string Shell command to run after dispatch regardless of outcome (cleanup semantics). Failure overrides dispatch success.
workflow string Name of a workflow in .orc/workflows/ (required for workflow and used by branch)
check string Shell command whose stdout selects a branch key (required for branch)
branches map Map of key → workflow name (required for branch). Each value must reference a workflow in .orc/workflows/.
default string Fallback workflow name if check output doesn't match any branch key (branch only)
Phase types

script — Executes a shell command via bash -c. The run field supports variable substitution. Child processes inherit the parent environment plus ORC_* variables.

agent — Reads a prompt template file, expands variables, and invokes claude -p. Output is streamed to the terminal and saved to .orc/artifacts/<ticket>/logs/. The following tools are always approved by default: Read, Edit, Write, Glob, Grep, Task, WebFetch, WebSearch. Add more via default-allow-tools (all agents) or allow-tools (per phase). If outputs are declared and missing after the agent finishes, orc re-invokes the agent once to produce them. Use mcp-config to connect agents to MCP servers with a dynamically-generated config file.

gate — Prompts the operator for approval. The operator can type y to continue, or any other text to request a revision — the text is captured as feedback in the phase log. Skipped automatically when using --auto.

workflow — Runs a named sub-workflow inline. The workflow field references a config in .orc/workflows/. The child workflow executes in the same process with its own state and artifacts directory (.orc/artifacts/<workflow>/<ticket>/). Child costs are merged into the parent's cost tracking. Supports condition and loop (standard rules). Cannot use parallel-with, prompt, or run.

branch — N-way dispatch: runs a check script, matches its stdout against branches keys, and runs the corresponding workflow. If no key matches, uses default (if set) or fails. Supports condition and loop. Cross-workflow cycle detection catches circular references at config load time.

# Workflow composition example
- name: review
  type: workflow
  workflow: review-pipeline

# Branch example
- name: classify
  type: branch
  check: .orc/scripts/classify.sh
  branches:
    simple: quick-fix
    complex: full-pipeline
  default: full-pipeline

Complete Example Config

name: my-service
ticket-pattern: '[A-Z]+-\d+'
model: opus
max-cost: 10.00

default-allow-tools:
  - Bash

vars:
  WORKTREE: $PROJECT_ROOT/.worktrees/$TICKET

phases:
  - name: setup
    type: script
    description: Create worktree
    run: git worktree add $WORKTREE

  - name: design
    type: agent
    description: Produce a technical design
    prompt: .orc/phases/design.md
    model: opus
    timeout: 20
    cwd: $WORKTREE
    outputs:
      - design.md

  - name: implement
    type: agent
    description: Implement the design
    prompt: .orc/phases/implement.md
    model: opus
    timeout: 45
    cwd: $WORKTREE
    outputs:
      - implementation.md
    loop:
      goto: design
      max: 3
      check: test -f $ARTIFACTS_DIR/review-pass.txt

  - name: test
    type: script
    description: Run test suite
    run: make test
    cwd: $WORKTREE
    condition: test -f Makefile

  - name: lint
    type: script
    description: Run linter
    run: make lint
    cwd: $WORKTREE
    parallel-with: test

  - name: review
    type: gate
    description: Human approval before merge

Variable Substitution

Variables are available using $VAR or ${VAR} syntax in agent prompt templates, script run commands, conditions, loop checks, and pre-run/post-run hooks.

Variable Description
$TICKET The ticket identifier passed to orc run
$ARTIFACTS_DIR Absolute path to .orc/artifacts/<ticket>/
$WORK_DIR Absolute path to the working directory (project root, or cwd if set)
$PROJECT_ROOT Absolute path to the project root (where .orc/ lives)
$WORKFLOW Current workflow name (empty for single-config projects)

For agent prompt templates, cwd, and mcp-config paths, variables are expanded via Go string substitution (with os.Expand falling back to environment variables). For bash-executed fields (run, condition, loop.check, pre-run, post-run), variables are set as environment variables in the child process — standard bash quoting rules apply.

Custom Variables

Define project-specific variables under vars: in config.yaml:

vars:
  WORKTREE: $PROJECT_ROOT/.worktrees/$TICKET
  SRC: $WORKTREE/src

Variables are expanded in declaration order, so later vars can reference earlier ones (SRC references WORKTREE above). Custom vars are available everywhere built-ins are — prompt templates, run commands, condition, loop.check, cwd fields, and pre-run/post-run hooks.

Custom vars cannot override built-in variables (TICKET, WORKFLOW, ARTIFACTS_DIR, WORK_DIR, PROJECT_ROOT).

Artifacts Directory

orc creates a .orc/artifacts/<ticket>/ directory per ticket to store all run data:

.orc/artifacts/<ticket>/
├── state.json              # Current run state (phase_index, ticket, status, failure_category)
├── costs.json              # Per-phase cost and token counts
├── timing.json             # Per-phase timing data
├── loop-counts.json        # Persisted loop iteration counters
├── run-result.json         # Machine-readable run summary with per-phase breakdown
├── prompts/                # Rendered prompt for each phase
├── logs/                   # Agent output for each phase
├── feedback/               # Loop/failure feedback
└── history/                # Archived past runs
    └── <run-id>/           # Timestamp-based directory (same layout as parent)

Feedback auto-injection: When a phase loops (fails or is forced back by min), its output is written to feedback/from-<phase>.md. On the next iteration, all feedback files are automatically prepended to agent prompts — agents see prior failure context without manual intervention.

Audit Directory

orc also maintains .orc/audit/<ticket>/ to preserve data across cancellations and re-runs:

.orc/audit/<ticket>/
├── costs.json              # Persisted cost data (survives cancel)
├── timing.json             # Persisted timing data
├── run-result.json         # Machine-readable run summary with per-phase breakdown
├── logs/
│   ├── phase-1.iter-1.log  # Archived logs from prior loop iterations
│   └── ...
├── prompts/
│   └── phase-1.iter-1.md   # Archived rendered prompts
└── feedback/
    └── ...                 # Archived feedback files

When you run orc cancel, the audit directory is preserved (rotated to a timestamped name). orc status reads from the audit directory for cost and timing data.

History Directory

When a run completes, artifacts are archived immediately. Failed or interrupted runs stay in place for --resume/--retry, and are archived automatically when the next fresh orc run starts. The run-id is a filesystem-safe timestamp. Old entries are pruned based on the history-limit config field (default 10).

Loops

The loop field is orc's core convergence construct, handling both simple retry and deliberate quality iteration.

loop:
  goto: implement       # jump-back target (must be earlier phase)
  min: 1                # minimum iterations even on success (default 1)
  max: 3                # total iterations before exhaustion (required)
  check: test -f $ARTIFACTS_DIR/review-pass.txt  # quality gate (optional)
  on-exhaust: plan      # outer recovery (optional, string or object)

Failure path: When a phase with loop fails, orc writes the failure output to .orc/artifacts/feedback/from-<phase>.md, increments the loop counter, and jumps back to loop.goto. If the counter reaches loop.max, the loop is exhausted.

Success path: When a phase with loop succeeds but the iteration count is less than loop.min, orc forces another iteration (writing the output as feedback). Once iteration >= min, the loop breaks normally.

Check path: When a phase with loop.check succeeds (exit 0), the check command runs. If the check exits non-zero, orc treats it as a loop failure — writing the check output to feedback and looping back. If the check exits 0, the normal success path applies (min enforcement, then advance). Variables ($ARTIFACTS_DIR, etc.) are available as environment variables in the check command. This eliminates the need for a separate *-check script phase.

On-exhaust recovery: When a loop exhausts, if on-exhaust is set, the loop counter resets and orc jumps to the on-exhaust target. This enables outer recovery (e.g., re-plan then re-implement). Accepts a string (on-exhaust: plan) or object (on-exhaust: {goto: plan, max: 2}).

Loop counts are persisted to .orc/artifacts/loop-counts.json and reset when using --retry, --from, or step-mode backward rewind. Note: loop.max means total iterations, not retries.

Parallel Phases

Two phases can run concurrently using parallel-with:

- name: test
  type: script
  run: make test

- name: lint
  type: script
  run: make lint
  parallel-with: test

Both phases start at the same time. If either fails, the other is cancelled. After both complete, the runner advances past both phases.

Constraints: parallel-with and loop cannot be combined on the same phase.

Multi-Workflow Support

Projects can define multiple named workflows for different task types:

.orc/
  config.yaml           # default workflow
  workflows/
    bugfix.yaml         # named workflows
    refactor.yaml
  phases/               # shared prompt files
Running a Named Workflow
orc run bugfix TICKET-123           # positional: first arg matches a workflow name
orc run -w bugfix TICKET-123        # explicit: -w/--workflow flag
orc run TICKET-123                   # uses default workflow
Default Workflow Resolution
Scenario Default
Only config.yaml It's the default (flat artifact layout, backward compatible)
Only workflows/ with one file That sole workflow is the default
config.yaml + workflows/ config.yaml is the default
Multiple in workflows/, no config.yaml Must specify (error lists options)

In multi-workflow projects, artifacts are namespaced: .orc/artifacts/<workflow>/<ticket>/.

Adding a Workflow
orc init --add-workflow bugfix                   # minimal starter
orc init --add-workflow bugfix --recipe simple   # from a recipe

With --recipe, prompt files are also written to .orc/phases/ (existing files are not overwritten). Without --recipe, create prompt files manually.

Multi-Workflow Commands
orc flow                   # show all workflows
orc flow -w bugfix         # one workflow
orc validate               # validate all
orc validate -w bugfix     # one workflow

Environment Variables

Child processes (scripts and agents) inherit the parent environment with these additional variables:

Variable Description
ORC_TICKET The ticket identifier
ORC_WORKFLOW Current workflow name (empty for single-config projects)
ORC_ARTIFACTS_DIR Absolute path to .orc/artifacts/<ticket>/
ORC_WORK_DIR Working directory
ORC_PROJECT_ROOT Project root directory
ORC_PHASE_INDEX Current phase index (0-based)
ORC_PHASE_COUNT Total number of phases
ORC_<NAME> Custom vars get an ORC_ prefix (e.g., WORKTREEORC_WORKTREE)

The CLAUDECODE environment variable is stripped from child processes so that claude -p can run without nesting conflicts.

Signal Handling

When you press Ctrl+C (SIGINT) or send SIGTERM/SIGHUP:

  • The current phase is cancelled via context cancellation
  • State is saved with status interrupted
  • A resume hint is printed: orc run <ticket>

Resume the workflow later — it picks up from the interrupted phase.

Exit Codes

orc run returns structured exit codes for scripting and CI/CD:

Code Meaning
0 Success — workflow completed, all phases passed
1 Phase failure — agent or script phase failed, loop exhausted, gate denied, outputs missing, or sub-workflow/branch failed
2 Timeout — a phase exceeded its configured timeout
3 Configuration error — invalid config, missing prompt file, setup failure
4 Cost limit exceeded — per-phase or per-run cost budget hit
5 Interrupted — SIGINT, SIGTERM, or SIGHUP received
6 Resume failure — cannot resume interrupted session
7 Infrastructure error — all phases completed but state persistence failed
8 Rate limit — Claude API rate limit or subscription usage exhausted

Run Summary

After every run, orc prints a summary table showing each phase's outcome, duration, run count (for looped phases), and separate totals for agent and script time.

For detailed documentation on the execution model, loops, output validation, and more, run orc docs to see all available topics — especially orc docs runner and orc docs quality-loops.

License

MIT

Directories

Path Synopsis
cmd
orc command
internal
selfupdate
Package selfupdate downloads, verifies, and extracts orc release binaries from GitHub Releases.
Package selfupdate downloads, verifies, and extracts orc release binaries from GitHub Releases.
ux
ux/uxtest
Package uxtest provides test helpers for manipulating package-level globals in internal/ux.
Package uxtest provides test helpers for manipulating package-level globals in internal/ux.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL