Writing Custom Workflows
Animus workflows are defined in YAML and live in .animus/workflows.yaml and .animus/workflows/*.yaml. These files describe project-local workflows, overrides, and pack composition. They usually wrap canonical pack-qualified refs such as animus.task/standard instead of copying task or requirement semantics into the repository.
For the target design of universal phase verdicts and YAML-defined phase-local fields, see Phase Contracts.
File Location
Place workflow files in either:
.animus/workflows.yaml.animus/workflows/*.yaml
Example:
.animus/
workflows.yaml
workflows/
custom.yaml
premium.yamlAnimus loads the single-file form and the directory form together. You can keep everything in one file or split workflows across multiple files.
YAML Structure Overview
A workflow file can contain the following top-level sections:
mcp_servers: # External tool integrations
agents: # Agent definitions (model, tool, system_prompt/system_prompt_file)
models: # Named model+tool registry (agents reference by name)
phase_catalog: # Phase metadata (label, description, category, tags)
phases: # Phase execution config (mode, directive, command)
workflows: # Workflow definitions (sequence of phases)Agents
Agents define which model and tool to use, plus an optional system prompt. For long prompts, you can keep the text in a separate UTF-8 file with system_prompt_file instead of embedding it inline:
agents:
default:
model: claude-sonnet-4-6
tool: claude
tool_profile: main
po-reviewer:
system_prompt: |
You are a Product Owner reviewing completed development work.
Your job is to verify that ALL acceptance criteria and requirements
from the original task are fully met by the implementation.
model: claude-sonnet-4-6
tool: claude
research-agent:
model: gemini-3.1-pro-preview
tool: gemini
reviewer:
system_prompt_file: prompts/reviewer.md
model: claude-sonnet-4-6
tool: claudeThe tool field specifies which CLI tool runs the agent: claude, codex, gemini, opencode, or oai-runner.
system_prompt and system_prompt_file are mutually exclusive on the same agent. Relative prompt-file paths resolve from the YAML file that declares the agent.
For Claude-only account routing, set tool_profile on a Claude agent or in a phase runtime: block. The profile name resolves against the user's global Animus config and typically injects CLAUDE_CONFIG_DIR. Initial login for each profile still happens interactively in Claude Code.
MCP Servers
Declare MCP servers that agents can use as external tools:
mcp_servers:
animus:
command: animus
args: ["mcp", "serve"]
hubspot:
command: npx
args: ["-y", "@hubspot/mcp-server"]
env:
HUBSPOT_ACCESS_TOKEN: "${HUBSPOT_ACCESS_TOKEN}"
tools:
- contacts.search
- contacts.getEnvironment variables use ${VAR} interpolation syntax. The tools field is optional and restricts which tools from the server are exposed to agents.
Agents reference MCP servers by name:
agents:
sales-agent:
model: claude-sonnet-4-6
tool: claude
mcp_servers:
- animus
- hubspotPhase Catalog
The phase catalog provides metadata for phases. This is separate from the phase execution config:
phase_catalog:
implementation:
label: "Implementation"
description: "Implement production-quality code changes"
category: development
tags: [coding, implementation]
code-review:
label: "Code Review"
description: "Review implementation for defects and maintainability"
category: review
tags: [review, quality]Categories include: planning, development, review, verification.
Phases
Phases define how work is executed. There are two modes: agent-driven and command-driven.
Longer term, every phase should also participate in the same universal verdict-driven output model, with YAML declaring any additional phase-specific fields that the phase emits.
Agent-Driven Phases
Agent phases dispatch work to an AI agent:
phases:
implementation:
mode: agent
agent: default
directive: "Implement the task requirements"
code-review:
mode: agent
agent: po-reviewer
directive: "Review the implementation"mode is required on every phase definition (agent, command, or manual). max_rework_attempts is not a phase-definition field — it belongs on a rich phase entry inside a workflow's phases: list (see Phase Configuration Within Workflows).
Command-Driven Phases
Command phases run a CLI command directly:
phases:
unit-test:
mode: command
directive: "Run the workspace test suite"
command:
program: cargo
args: ["test", "--workspace"]
timeout_secs: 600
lint:
mode: command
directive: "Run clippy with deny warnings"
command:
program: cargo
args: ["clippy", "--workspace", "--", "-D", "warnings"]
timeout_secs: 120Workflows with Shared Sequences
Workflows are the top-level unit. A workflow that embeds another workflow (via workflow_ref) achieves the same reuse as a "pipeline" concept — the referenced workflow's phases are expanded inline at dispatch time:
workflows:
- id: review-cycle
name: "Review Cycle"
description: "Reusable code review and testing sequence"
phases:
- code-review:
on_verdict:
rework:
target: code-review
- testing
- id: quick-fix
name: "Quick Fix"
description: "Fast pipeline for small bug fixes"
phases:
- implementation
- testingPhase Configuration Within Workflows
Phases in a pipeline support these options:
on_verdict routing -- When a review phase returns a rework verdict, route back to a target phase:
phases:
- code-review:
on_verdict:
rework:
target: implementationskip_if conditions -- Skip a phase based on task properties:
phases:
- implementation:
skip_if:
- "task.type == 'docs'"Sub-workflow references -- Embed another workflow definition by ID:
phases:
- requirements
- implementation
- workflow_ref: review-cycleWorkflows
Workflows tie everything together. They are the top-level units that get dispatched against subjects. A project-local workflow can delegate to bundled or installed pack refs:
workflows:
- id: standard-workflow
name: Standard Workflow
phases:
- workflow_ref: animus.task/standardworkflows:
- id: requirement-task-generation
name: "Requirement Task Generation"
description: "Create or refine requirement-linked Animus tasks"
phases:
- requirement-task-generationGit Operations Are Command Phases
Animus does not perform git operations (commit, push, PR, merge) as runner automation. The post_success.merge config block was removed in v0.5.x — a workflow that still sets post_success.merge (or integrations.git.auto_merge) is rejected at parse time.
Express commit, push, PR creation, and merge as command phases: a phase with a command: block that runs git or gh. They run in the task worktree and sequence in phases: like any other phase, so they pick up verdict routing, retries, and approval gates for free.
phases:
create-pr:
mode: command
directive: "Open a GitHub PR from the current branch"
command:
program: gh
args: ["pr", "create", "--fill", "--base", "main"]
cwd_mode: task_root
timeout_secs: 60
success_exit_codes: [0]
workflows:
- id: full
name: "Full Lifecycle"
phases:
- triage
- refine-requirements
- implementation
- unit-test:
on_verdict:
rework:
target: implementation
- code-review:
on_verdict:
rework:
target: implementation
- po-review:
on_verdict:
rework:
target: implementation
- create-pr # command phase running `gh pr create`A human still performs the final merge of the PR (or you add an explicit gh pr merge command phase, gated by an approval if desired).
Variables
Variables live inside a workflow definition (not at the file's top level) and can be overridden at runtime via --input-json:
workflows:
- id: my-workflow
name: My Workflow
phases: [implementation]
variables:
- name: target_branch
default: main
- name: review_depth
default: standardComplete Example: Code Review Workflow
agents:
reviewer:
system_prompt: |
You are a senior code reviewer. Focus on correctness, performance,
and adherence to the project's coding conventions. Flag any security
concerns. Use Animus MCP tools to update task checklists with findings.
model: claude-sonnet-4-6
tool: claude
implementer:
model: claude-sonnet-4-6
tool: claude
phase_catalog:
implement:
label: "Implementation"
category: development
tags: [coding]
review:
label: "Code Review"
category: review
tags: [review, quality]
test:
label: "Testing"
category: verification
tags: [testing]
phases:
run-tests:
mode: command
directive: "Run tests"
command:
program: cargo
args: ["test", "--workspace"]
timeout_secs: 600
workflows:
- id: reviewed-implementation
name: "Reviewed Implementation"
description: "Implement, test, review with rework loop"
phases:
- implement
- run-tests:
on_verdict:
rework:
target: implement
- review:
on_verdict:
rework:
target: implement
- create-pr # command phase running `gh pr create`Tips
- Use
${VAR}syntax for environment variable interpolation inenvfields. - Reuse agents across phases by referencing the same agent name.
- Order phases so that fast-failing checks (lint, tests) run before expensive reviews.
- Keep
max_rework_attemptsreasonable (2-3) to avoid infinite loops. - Validate your workflow config with
animus workflow config validate.