Creating YAML Workflows: A Complete Authoring Guide
Build multi-node DAG workflows in Archon using YAML. Covers all node types, parallel execution, conditional branching, and output substitution with examples.
Use this file to discover all available pages before exploring further.
Archon workflows are YAML files that define a directed acyclic graph (DAG) of nodes—each representing an AI agent call, a shell script, a loop, or a human approval gate. This page covers everything you need to author, test, and run production-quality workflows: the full schema, every node type, conditional branching with when:, structured output via output_format, DAG resume, and the patterns used in Archon’s own bundled workflows.
Read Authoring Commands first. Workflows are built from command files; understanding how commands work will make your workflows more effective.
Workflows live in .archon/workflows/ relative to your working directory. Subdirectories work—Archon discovers workflows recursively.
.archon/├── workflows/│ ├── my-workflow.yaml│ └── review/│ └── full-review.yaml # Subdirectory works└── commands/ └── [commands used by workflows]
Browse .archon/workflows/defaults/ for real-world examples—Archon ships 12 bundled workflows. Copy and modify them: cp .archon/workflows/defaults/archon-fix-github-issue.yaml .archon/workflows/my-fix-issue.yaml. Same-named files in .archon/workflows/ override the bundled defaults.
CLI vs Server: The CLI reads workflow files from wherever you run it and sees uncommitted changes. The server reads from ~/.archon/workspaces/owner/repo/, which only syncs from remote before worktree creation—push your changes for the server to pick them up.
# Requiredname: workflow-namedescription: | What this workflow does.# Optional workflow-level configurationprovider: claude # Any registered provider (claude, codex, pi)model: sonnet # Model overrideinteractive: true # Web only: run in foreground (required for approval gates)worktree: enabled: false # false = always run in live checkout; true = require worktreetags: [Review, Triage] # Explicit Web UI filter tags# Claude SDK defaults (inherited by all Claude nodes unless overridden per-node)effort: high # 'low' | 'medium' | 'high' | 'max'thinking: adaptive # 'adaptive' | 'disabled' | { type: enabled, budgetTokens: N }fallbackModel: claude-haiku-4-5betas: ['context-1m-2025-08-07']sandbox: enabled: true# Required: DAG nodesnodes: - id: classify # Unique node ID — used in depends_on and $id.output command: classify-issue # Loads .archon/commands/classify-issue.md output_format: # Structured JSON output (SDK-enforced on Claude/Codex) type: object properties: type: type: string enum: [BUG, FEATURE] required: [type] - id: investigate command: investigate-bug depends_on: [classify] # Wait for classify to complete first when: "$classify.output.type == 'BUG'" # Skip if condition is false context: fresh # Start a fresh AI session for this node - id: plan command: plan-feature depends_on: [classify] when: "$classify.output.type == 'FEATURE'" - id: implement command: implement-changes depends_on: [investigate, plan] trigger_rule: none_failed_min_one_success # Run if at least one dep succeeded provider: claude # Per-node provider override model: opus[1m] # Per-node model override - id: summarize prompt: "Summarize the changes in $implement.output" # Inline prompt depends_on: [implement] effort: low # Override workflow-level effort for this node
An inline prompt string. Good for short, one-off prompts that don’t warrant a separate file.
- id: summarize prompt: | Summarize the implementation described in: $implement.output depends_on: [implement]
Runs a shell script without any AI. stdout is captured as $nodeId.output. Useful for deterministic data preparation, git operations, or environment setup.
Iterative AI execution until a completion signal. See Loop Nodes for the full reference.
- id: implement loop: prompt: | Read the plan. Implement the next incomplete task. Validate. Commit. When all tasks are done: <promise>COMPLETE</promise> until: COMPLETE max_iterations: 15 fresh_context: true
Pauses the workflow for human review. See Approval Nodes for the full reference.
- id: review-gate approval: message: "Review the proposed plan before implementation begins." capture_response: true # Store comment as $review-gate.output on_reject: prompt: "Revise the plan: $REJECTION_REASON" max_attempts: 3 depends_on: [plan]
Runs TypeScript (via bun) or Python (via uv). stdout is captured as $nodeId.output. See Script Nodes for the full reference.
Conditions are fail-closed — invalid or unparseable expressions default to false, causing the node to be skipped with a warning. Parentheses are not supported; use standard AND/OR precedence.
Every node auto-retries on transient errors (SDK crashes, rate limits, network timeouts) with 2 retries (3 total attempts) and 3 s base delay. Customize with a retry: block:
- id: flaky-node command: flaky-command retry: max_attempts: 3 # 3 retries = 4 total attempts delay_ms: 5000 # Base delay, doubles each attempt on_error: transient # 'transient' (default) | 'all'
retry: is not supported on loop: nodes—the loader will reject the workflow at parse time.
When a workflow fails, the run stays in the database as a resume candidate. Resume is explicit—you opt in:
# Resume most recent failed run for this workflow + directoryarchon workflow run large-migration --resume# Target a specific run by IDarchon workflow resume <run-id>
On resume, completed nodes are skipped and only failed/not-yet-run nodes execute.
Example: classify and route (from bundled archon-fix-github-issue)
This excerpt from the bundled archon-fix-github-issue workflow shows classification with structured output, conditional routing, and a bridge node using trigger_rule:
By default, workflows started from the Web UI run in the background—AI output appears only in the workflow run log, not in the chat window.Set interactive: true to run the workflow in the foreground (same behavior as CLI, Slack, Telegram, and GitHub):
name: my-interactive-workflowinteractive: true # Web UI: output visible in chat windownodes: - id: plan prompt: "Create a plan for $USER_MESSAGE" - id: review-gate approval: message: "Does this plan look good?" depends_on: [plan] - id: implement command: implement depends_on: [review-gate]
interactive: true is required whenever the workflow contains approval nodes or interactive loop nodes that need to deliver messages to the user’s chat window.