Example workflows
Complete WORKFLOW.md files you can copy, from a ClickUp sprint in Docker behind LiteLLM to a GitHub repository on Cloudflare.
Each example is a complete file. Copy one into your repository's root as WORKFLOW.md, replace the placeholders, and check the Workflow tab's inspector for anything still unset.
ClickUp sprint, Docker, LiteLLM gateway#
A web app whose tasks come from the current ClickUp sprint. Agents run in Docker, route model traffic through a LiteLLM proxy with per-task spend tags, test the app in a browser, and open draft pull requests on GitHub.
Set these first:
CLICKUP_API_TOKENin Settings → Environment (the wizard does this for you).LITELLM_API_KEY, a LiteLLM virtual key with a budget, in Edit Project → Environment, so this project has its own key and budget.- The agent and browser images, from Sandboxes.
---
# SI Fabrik · Symphony workflow for shop-storefront
tracker:
kind: clickup
provider:
api_token: $CLICKUP_API_TOKEN # Settings → Environment
sprint_folder_id: "90120000000" # Sprints folder: tasks from the current sprint (auto-rolls over)
assignee: me # only tasks assigned to the token's owner
active_states: ["to do", "in progress"]
terminal_states: ["complete", "closed"]
required_labels: [agent] # only tasks tagged "agent" are dispatched
polling:
interval_ms: 15000
workspace:
root: ~/HarnessWorkspaces/shop-storefront
git:
base: main
save: true
push: true
remote: origin
pull_request: draft
hooks:
timeout_ms: 120000
agent:
max_concurrent_agents: 3
max_turns: 12
max_retry_backoff_ms: 300000
limits:
daily_budget_usd: 40
max_cost_per_issue_usd: 12
max_attempts_per_issue: 4
pause_after_consecutive_failures: 5
runner:
kind: claude_code
claude:
command: claude
model: claude-opus-5-5
permission_mode: bypassPermissions
effort: high
max_budget_usd: 6
codex:
turn_timeout_ms: 3600000
stall_timeout_ms: 600000
docker:
enabled: true
image: harness-agent:latest
memory: 6g
cpus: 4
gateway:
enabled: true
base_url: http://localhost:4000 # rewritten to host.docker.internal inside Docker
api_key: $LITELLM_API_KEY # project variable: its own LiteLLM budget
models:
opus: claude-opus-5-5
sonnet: claude-sonnet-5-5
haiku: claude-haiku-5-5 # set it: Claude Code uses Haiku for background tasks
headers: { X-Team: storefront }
tags: true # x-litellm-tags: harness,project:shop-storefront,issue:<id>
browser:
enabled: true
viewport: 1440x900
preview:
setup: npm ci
command: npm run dev -- -H 0.0.0.0
port: 3000
ready: /api/health
ready_timeout_s: 300
sandbox:
network:
allow: [api.stripe.com, "*.storefront-staging.example.com"]
---
You are an autonomous senior engineer working on **{{ issue.identifier }}: {{ issue.title }}**.
{% if attempt %}
> This is attempt {{ attempt }}. Read the ClickUp comments and the workspace to see what was already done.
{% endif %}
{{ issue.description | default: "_No description provided._" }}
1. Read `AGENTS.md`, then plan before editing.
2. Implement the change with tests. Run `npm run lint` and `npm test`.
3. Check user-facing changes in the browser at http://localhost:3000 and save screenshots under `.harness/artifacts/`.
4. Commit on this branch. Don't push or open pull requests yourself.
5. When it's done and verified, move the task to **review** with `clickup_set_status` and comment with a Markdown
summary: what changed, how you verified it, what to look at. It becomes the pull request description.
6. If you're blocked, say why in a comment and stop.required_labels is a cheap way to roll out agents gradually: only tasks someone tagged agent are picked up.
Built-in board, no sandbox#
The smallest useful setup, for a trusted repository on your Mac. Agents run on the host with your Claude login.
---
tracker:
kind: local
provider:
path: .symphony/board.json
prefix: DOC
active_states: [Todo, In Progress]
terminal_states: [Done, Canceled]
board_states: [Backlog, Todo, In Progress, Human Review, Done, Canceled]
workspace:
root: ~/HarnessWorkspaces/docs-site
git:
pull_request: off # keep task branches in this repo; no push
agent:
max_concurrent_agents: 2
max_turns: 10
docker:
enabled: false
---
Work on **{{ issue.identifier }}: {{ issue.title }}**.
{{ issue.description }}
Commit your change. When done, move the issue to **Human Review** with `board_set_state` and comment with a summary.Without a sandbox, bypassPermissions lets the agent run any command as you, without asking. The inspector warns about this. Use it only for repositories you trust.
GitHub Issues on Cloudflare#
Issues labelled agent in a GitHub repository, with workspaces in Cloudflare Containers. Model keys and the GitHub token stay on your Mac or server; the sandbox only sees a placeholder.
---
tracker:
kind: github
provider:
repo: your-org/api-service
token: $GITHUB_TOKEN # falls back to `gh auth token`
exclude_labels: [human-review, blocked]
active_states: [open]
terminal_states: [closed]
required_labels: [agent]
workspace:
root: ~/HarnessWorkspaces/api-service
git:
base: main
pull_request: ready
agent:
max_concurrent_agents: 4
max_turns: 15
docker:
env: [SENTRY_DSN] # host variables passed into the sandbox, by name
sandbox:
provider: cloudflare # bridge URL and token in Settings → Sandbox
network:
allow: [pypi.org, files.pythonhosted.org]
---
You're fixing GitHub issue {{ issue.identifier }}: {{ issue.title }}.
{{ issue.description }}
Run `make test` before you hand off. When it's done, comment with `github_comment` and add the
`human-review` label with `github_add_labels`.GitHub boards are read-only in SI Fabrik; the hand-off is the human-review label, which also stops the issue from being dispatched again.
Codex runner#
The same idea with Codex. Approvals are accepted for the session; the policies are passed through to Codex unchanged.
---
tracker:
kind: local
active_states: [Todo, In Progress]
terminal_states: [Done, Canceled]
workspace:
root: ~/HarnessWorkspaces/cli-tool
runner:
kind: codex
codex:
command: codex app-server
model: gpt-5.5-codex
approval_policy: never
thread_sandbox: workspace-write
turn_timeout_ms: 3600000
stall_timeout_ms: 600000
docker:
enabled: true
git:
pull_request: draft
---
Implement {{ issue.identifier }}: {{ issue.title }}.
{{ issue.description }}
When finished, move the issue to **Human Review** and comment with what you changed.Codex in Docker needs an OpenAI API key in Settings → Credentials, or a gateway.
A library shared with an app#
Two projects: shared-lib publishes code, shop-storefront uses it from source and may file tasks in it.
share_with: [shop-storefront] # shop-storefront may use this project's code and app
accept_tasks_from: [shop-storefront] # its agents may file tasks here
linked_tasks_state: Backlog # a person approves them before an agent runslinks:
packages:
- name: "@your-scope/shared"
from: source
project: shared-lib
ref: main
services:
- name: api
env: API_URL
url: https://staging-api.example.comSee Project links and Linked tasks.