Skip to content

Workflows & Phases

A workflow is the workflow section of team.yml. It declares which phases exist, how they connect, and what configuration each phase carries. The orchestrator reads this definition, resolves the dependency graph, and executes phases in the right order.

A phase is one step in a pipeline. Every phase has a name and a type. The type determines what the orchestrator does — whether it launches an agent, runs automated commands, fetches external files, or all three.

For the complete field-by-field schema, see team.yml Reference.

workflow:
phases:
- name: architect
type: standard
- name: developer
type: standard
depends_on: [architect]
- name: reviewer
type: gate
depends_on: [developer]
commands:
- name: tests
run: npm test
max_iterations: 3

TypeAgent?Commands?What it does
standardYesNoRuns an agent that does work and signals done
gateYesYesRuns commands, then an agent that renders a verdict (automated)
hugYesYesRuns commands, then a human reviewer renders a verdict via the HUG review page
execNoYes (required)Runs shell commands with no agent — pass or escalate
pullNoNoFetches external content into .cliq/pull/ before downstream phases run
pushNoNoPublishes local files to external destinations after upstream phases complete

The workhorse. A standard phase launches an agent, gives it a role and the task requirements, and waits for it to signal completion. This is where the real work happens — writing code, designing architecture, authoring tests, producing documents.

- name: developer
type: standard
depends_on: [architect]

The agent SDK reads the role file and incoming channel handoffs from predecessors, passes them to the implementation, captures the result, writes handoff notes for successors, and signals done.


A gate is a quality checkpoint that combines automated commands with agent intelligence. Gates create feedback loops that let work improve iteratively.

- name: reviewer
type: gate
depends_on: [developer]
commands:
- name: build
run: npm run build
- name: tests
run: npm test
max_iterations: 3

When a gate’s dependencies complete:

  1. Run commands — the orchestrator executes each command as a shell command (exit 0 = pass, non-zero = fail). Command outcomes are evaluated by the agent, not the orchestrator.
  2. Build gate context — command results and verdict history are written to .cliq/gate_context.md
  3. Launch the gate agent — the agent reviews the work and produces a structured verdict
VerdictWhat happens
PASSQuality bar is met. Pipeline continues to the next phase.
ROUTE:<phase>Work needs revision. The named phase is re-activated with feedback. When it finishes, the gate re-evaluates from step 1.
ESCALATEHuman intervention required. The pipeline halts.

On a ROUTE verdict, the orchestrator:

  1. Writes feedback to the gate channel (e.g. .cliq/channels/reviewer--developer/handoff.md)
  2. Re-activates the target phase (which reads the feedback and fixes the issues)
  3. Waits for the target to signal done
  4. Re-runs the gate’s commands
  5. Launches the gate agent again with updated results and the growing verdict history

This loop continues until the gate passes, escalates, or exhausts its max_iterations budget. The default is 3 iterations; the maximum is 5. After the budget is spent, the orchestrator auto-escalates.

The gate agent sees the full history of previous verdicts, so it can make increasingly informed decisions — for example, escalating after a second failed route to the same phase.


An exec phase runs shell commands with no agent and no prompt. Each exec phase gets its own tmux pane where commands execute with real-time output. Each command has an optional escalate_on_fail boolean (default true). Commands with escalate_on_fail: false log failures as warnings and continue.

- name: git-verify
type: exec
depends_on: [git-finalize]
commands:
- name: pushed
run: "git ls-remote --heads origin $(git branch --show-current) | grep -q ."
- name: pr-exists
run: "cliq tool run pr-exists"
- name: changelog-updated
run: "test -f CHANGELOG.md"
escalate_on_fail: false

Use exec phases to verify that critical external actions actually happened — things like “was the code pushed?” or “does the PR exist?” — where an agent’s self-report isn’t reliable enough. Exec phases must have at least one command and cannot have max_iterations.


A pull phase fetches external content into .cliq/pull/ before downstream phases run. It has no agent, no role file, and no tmux pane — the orchestrator executes it directly.

- name: fetch-data
type: pull
sources:
- url: "gdrive://$(inputs.folder_id)"
name: data-room
- url: "https://example.com/report.pdf"
name: market-report

Downstream phases reference pulled content as local files (e.g., .cliq/pull/data-room/). See Pull & Push for source types, conversion rules, template variables, authentication, and security.


A push phase publishes local files to external destinations. Like pull, it has no agent, no role file, and no tmux pane.

- name: publish-report
type: push
depends_on: [quality-gate]
targets:
- file: reports/report.md
to: "gdrive://$(inputs.output_folder_id)/"
mode: create
name: "$(team_name)-report-$(date)"

Push phases are typically placed after a gate so deliverables are only published after quality checks pass. See Pull & Push for destination URIs, modes, template variables, and security.


A hug phase pauses the pipeline for human review. Instead of an AI agent rendering the verdict, a real person reviews the work on a web-based review page and decides the outcome.

- name: human-review
type: hug
depends_on: [developer]
commands:
- name: tests
run: npm test
review:
reviewer: architects
timeout: 48h

Hug phases use the same PASS / ROUTE / ESCALATE verdict model as automated gates. The review block is required — it tells the orchestrator who reviews, which artifacts to present, and how long to wait.

See Human Gate (HUG) for the full setup and configuration.


Phases connect through depends_on. A phase won’t start until all of its dependencies have completed. Phases with no shared dependencies run in parallel automatically.

- name: architect
type: standard
- name: tester
type: standard
depends_on: [architect]
- name: security-auditor
type: standard
depends_on: [architect]
- name: developer
type: standard
depends_on: [tester, security-auditor]

Here, tester and security-auditor both depend on architect and nothing else — so they run simultaneously once the architect finishes. developer waits for both (fan-in). The orchestrator handles all of this from the depends_on declarations.

A phase with no depends_on is a root phase — it starts immediately when the pipeline runs. Every workflow must have at least one root phase.


Commands are shell commands attached to gate, hug, and exec phases. Each command runs as a subprocess — exit code 0 means pass, non-zero means fail.

commands:
- name: build
run: npm run build
scope: repo
if: "test -f package.json"
- name: tests
run: npm test
- name: output-exists
run: "test -f output.md"

See team.yml Reference — Commands for the full field reference.

The if field lets you skip commands when they don’t apply:

- name: build
run: npm run build
if: "test -f package.json"

If package.json doesn’t exist, the command is skipped — not failed. This is common in teams that work across different project types.

By default, commands run from the project workspace directory. In multi-repo setups, scope: repo runs the command in each repository:

- name: tests
run: npm test
scope: repo
if: "test -f package.json"

In a single-repo workspace, scope: repo behaves identically to scope: workspace.


A support phase sits idle until a gate routes work to it. Support phases are declared in a separate support section under workflow, not in the main phases list.

workflow:
phases:
- name: developer
type: standard
- name: reviewer
type: gate
depends_on: [developer]
commands:
- name: tests
run: npm test
max_iterations: 3
support:
- name: fixer
type: standard
- name: git-resolver
type: standard

Support phases have their real functional type (standard, gate, etc.) — they’re just topologically separated from the main flow. They must not have depends_on and are only reachable through gate routing.

Use support phases for specialized remediation: a git-resolver that fixes merge conflicts, a security-fixer that patches vulnerabilities, a fixer that addresses gate feedback.


By default, every phase uses the runtime’s default agent. The agent field overrides this for a specific phase:

- name: security-audit
type: standard
depends_on: [developer]
agent: security-scanner

The value must be a built-in agent name or an agent declared in the team’s agents section. See Cliq SDK for details on choosing and configuring agents.


When cliq run ends in an escalation or failure, you don’t need to re-run cliq req — the requirement hasn’t changed. Fix the issue and run again.

ScenarioWhat happens
Early escalation — first gate fails before any agent did workcliq run silently cleans prior artifacts and proceeds
Mid-pipeline failure — some agents completed phasescliq run warns which phases completed and asks for confirmation
Successful completion — pipeline finished cleanlycliq run refuses. Start a new task with cliq req
Terminal window
cliq run # auto-cleans if no agents did real work
cliq run -f # force re-run, skip confirmation

cliq team validate checks your workflow for structural correctness. See team.yml Reference — Validation Rules for the full list of checks and error messages.

Key rules:

  • Every phase must have name and type
  • No duplicate phase names, no cycles in depends_on, at least one root phase
  • Exec phases must have commands and no max_iterations
  • Pull phases must have sources; push phases must have targets
  • hug phases must have a review block; other types must not
  • escalate_on_fail is only allowed on exec phase commands
  • Every non-exec, non-pull, non-push phase must have a matching roles/<name>.md

workflow:
phases:
- name: architect
type: standard
- name: developer
type: standard
depends_on: [architect]
- name: reviewer
type: gate
depends_on: [developer]
commands:
- name: tests
run: npm test
max_iterations: 3
workflow:
phases:
- name: architect
type: standard
- name: tester
type: standard
depends_on: [architect]
- name: security-auditor
type: standard
depends_on: [architect]
- name: developer
type: standard
depends_on: [tester, security-auditor]
- name: reviewer
type: gate
depends_on: [developer]
commands:
- name: build
run: npm run build
- name: tests
run: npm test
max_iterations: 3
workflow:
phases:
- name: fetch-data
type: pull
sources:
- url: "gdrive://$(inputs.folder_id)"
name: source-docs
- name: architect
type: standard
depends_on: [fetch-data]
- name: developer
type: standard
depends_on: [architect]
- name: tester
type: standard
depends_on: [architect]
agent: test-specialist
- name: reviewer
type: gate
depends_on: [developer, tester]
commands:
- name: build
run: npm run build
scope: repo
if: "test -f package.json"
- name: tests
run: npm test
scope: repo
if: "test -f package.json"
max_iterations: 3
- name: git-finalize
type: standard
depends_on: [reviewer]
- name: git-verify
type: exec
depends_on: [git-finalize]
commands:
- name: pushed
run: "git ls-remote --heads origin $(git branch --show-current) | grep -q ."
- name: pr-exists
run: "cliq tool run pr-exists"
- name: publish
type: push
depends_on: [git-verify]
targets:
- file: reports/summary.md
to: "gdrive://$(inputs.output_folder)/"
mode: create
name: "$(team_name)-$(date)"
support:
- name: git-resolver
type: standard
- name: hotfix-dev
type: standard