Symphony runs coding agents (Codex or Claude) on your Linear issues and GitHub pull requests, so your team manages the work instead of babysitting the agents.
It watches Linear for issues to pick up, creates an isolated workspace for each one, runs the agent against a workflow prompt you define per repo, and keeps the run moving — retrying failures and recovering stalled sessions — until there is a pull request to review. You can also point it at an existing PR from the CLI to address review comments, fix failing CI, or resolve conflicts.
Warning
Symphony is an engineering preview for operator-controlled, trusted environments. It includes operational guardrails, but it is not a hardened multi-tenant service and should run behind trusted network and authentication boundaries.
Linear issue or PR -> Symphony -> workspace -> agent -> pull request
- Pick up work. Symphony polls Linear and claims eligible issues (or you hand it a PR directly).
- Isolate it. Each run gets a fresh workspace — a clean checkout or worktree, never your source repo.
- Run the agent. It launches the configured agent against that repo's
WORKFLOW.mdprompt. - Keep it moving. Failed runs retry with backoff, stalled agents are detected and recovered, and results are reported back to Linear — so a long queue does not need constant supervision.
Issue runs end with a pull request and validation evidence. PR runs push back to the existing PR head
branch instead of opening a second one. If a claimed issue moves to a terminal state (Done,
Closed, Cancelled, Duplicate), Symphony stops its agent and cleans up the workspace.
Glossary
- Workflow: the repo-owned policy and prompt that tells Symphony what to run.
- Run: one attempt to make progress on a Linear issue.
- Workspace: the isolated checkout or worktree for a run.
- Tracker: the system Symphony polls for work, currently Linear.
- Repo route: an entry under
repositories:insymphony.ymlthat pairs a local checkout with itsWORKFLOW.mdand optional Linear selectors. One Symphony process can supervise many repo routes. - Quality gate: the optional pre-dispatch check that decides whether an issue is clear enough for an agent.
- Harness engineering: the practice of preparing a codebase with scripts, tests, docs, and guardrails so coding agents can work safely.
- Multi-repo orchestration — one process supervises several repositories from a single
symphony.yml, with per-repo Linear selectors and conflict detection. - LiveView dashboard — active runs, watched issues, the retry queue, quality-gate state, per-issue transcripts, and an audit timeline.
- Operator controls — pause, resume, and stop, persisted across restarts.
- PR-driven runs — work an existing pull request from the CLI for review comments, failing CI, and conflict fixes.
- Recovery — a watchdog and retry queue handle stalled or failed sessions.
- Durable run store — run history, retry backoff, captured learnings, token totals, and notification dedupe.
- Workspace guardrails — age-based cleanup, startup orphan removal, and disk free-space pauses.
- Scoped agent tools — current-issue Linear updates, GitHub PR evidence, and attachment handling.
- Quality gate — optionally scores issue clarity before dispatch so unclear work is held back.
- Executor + reviewer runs — an optional read-only reviewer agent gates the executor's push.
- Docker runner — host Symphony with mounted repos, state, logs, and agent credentials.
Symphony works best in codebases that have adopted harness engineering: scripts, tests, docs, and workflow prompts that let coding agents work safely.
-
Get a Linear token from Settings → Security & access → Personal API keys, and export it as
LINEAR_API_KEY. Symphony reads all secrets from the environment — to avoid plaintext.envfiles on disk, load them through a secrets manager such as 1Password Environments,op run, ordirenv(see docs/security.md). -
Install the toolchain and build:
cd symphony mise trust && mise install mise exec -- mix setup mise exec -- mix build
-
Scaffold operator config. Run
mise exec -- ./bin/symphony initfrom your operator repo to createsymphony.yml, then edit the issue scope, agent command, workspace root, andrepositories:. -
Write a workflow per repo. Invoke the
symphony-init-workflowskill from Codex or Claude in each target repo; the agent inspects the repo and writes a tailoredWORKFLOW.md. -
Start Symphony:
mise exec -- ./bin/symphony
The LiveView dashboard runs at http://127.0.0.1:4000 by default. It has no built-in authentication
and binds to loopback only — to expose it remotely, front it with a reverse proxy that handles auth
(Tailscale, Cloudflare Access, nginx). See docs/security.md for details.
Symphony reads two files:
symphony.yml— operator config: issue source, workspaces, agents, pollers, gates, notifications, and therepositories:list. Plain YAML.WORKFLOW.md— repo-local prompt and per-repo hooks. YAML front matter, then the prompt template. Each repo underrepositories:has its own.
Minimal symphony.yml:
issues:
provider: linear
linear:
scope:
project_slug: "..."
workspaces:
root: ~/code/workspaces
agent:
runtime: codex
command: codex app-server
repositories:
- key: my-repo
workflow: ./WORKFLOW.md
# issue_gate is omitted here, so issues are dispatched without LLM scoring.Minimal WORKFLOW.md:
---
hooks:
after_create: |
git clone git@github.com:your-org/your-repo.git .
prompts:
pr: |
You are working on PR {{ pr.url }}.
Intent: {{ pr.intent }}
---
You are working on a Linear issue {{ issue.identifier }}.
Follow this repository's conventions and validation commands before handoff.
Title: {{ issue.title }}
Body: {{ issue.description }}The Markdown body is the issue prompt; prompts.pr is the optional PR-mode template. Symphony
prepends a managed runtime context (workspace isolation, untrusted-input handling, scoped tools,
secret handling, response shape) before either, so keep WORKFLOW.md focused on repo-specific
commands, conventions, and validation gates.
For the full reference — every supported key, defaults, prompt variables, CLI flags, and the issue gate — see docs/configuration.md.
Start the service from a directory containing symphony.yml (or pass --config to point elsewhere):
./bin/symphony # start the service
./bin/symphony --config ./other.yml # use a different operator configRun a single issue synchronously, without the poll loop or dashboard:
./bin/symphony run ACME-123 --timeout 30m --no-retryWork an existing PR:
./bin/symphony pr 123 --intent "address review comments"symphony workflow preview renders the exact base-issue prompt the agent would receive for the
repo-local WORKFLOW.md, using deterministic sample issue data — no Linear access, network, or
running orchestrator required. Use it to confirm your template and {% render %} partials resolve
correctly before a real run:
./bin/symphony workflow preview # renders ./WORKFLOW.md
./bin/symphony workflow preview --file path/to/WORKFLOW.md
./bin/symphony workflow preview --agent claude # default: codexAn unknown {% render %} partial or undefined variable is reported as an error, so the command
doubles as a quick workflow lint.
The dashboard exposes Pause, Resume, and per-issue Stop at /. The same controls are
available from the CLI over a loopback HTTP control plane on the dashboard port — no distributed
Erlang setup required:
mise exec -- mix symphony.pause "deploy window"
mise exec -- mix symphony.resume
mise exec -- mix symphony.stop ACME-123
mise exec -- mix symphony.pr 123 --intent "fix failing CI"Pause stops new dispatches while in-flight agents continue; Stop ends one issue's session and
records it as stopped without changing the Linear issue state.
The Docker runtime mounts your operator config, repositories, credentials, and agent command into the service. See docker/README.md.
- docs/configuration.md — full config reference for
symphony.yml,WORKFLOW.md, CLI flags, and defaults. - docs/security.md — threat model, built-in protections, and best practices.
- docs/development.md — toolchain, testing, packaging, and fork notes.
- docs/releasing.md — how to version and publish a release.
- docs/logging.md, docs/quality_gate_security.md, and docs/token_accounting.md — operational deep-dives.
- WORKFLOW.md — the example in-repo workflow contract and agent prompt.
This repository is a fork of OpenAI's
openai/symphony, introduced in OpenAI's
open-source Codex orchestration Symphony post.
This fork keeps Symphony as the Elixir/OTP service at the repository root and includes local
operational changes. SPEC.md is retained as a behavior reference for this service, not as
instructions for building a separate implementation from scratch.
This project is licensed under the Apache License 2.0.

