The Symphony daemon end to end — the standing agent workforce and its label-routed workflows, then the runtime that polls, dispatches, runs and writes back.
1 min read Updated Aug 12, 2026
High-level design
One canvas for the whole service: the workforce that files the work, and the runtime that turns it into merged code.
Symphony end to end. The workforce layer sits above the runtime: eight standing agents inspect the product on a cadence and file ordinary tickets, and the label on each ticket selects the workflow that runs it.
The top layer is the part that actually automates things. Eight standing agents run on their own cadences, and the humans on the team sit in the same row because they enter the system the same way. The agents get no privileged path in — same queue, same labels, same workflow as anything a person raises.
Agent
Routing label
What it inspects
Security review
report:security-agent
daily commit and system vulnerability review
Performance review
report:performance-agent
daily production performance review
Sentry triage
report:sentry-triage
daily triage and health summary
Log analyzer
report:symphony-log-analyzer
daily VPS log and run-efficiency analysis
API contract audit
report:api-contract-audit
weekly endpoint contract and REST audit
Staging regression QA
qa:staging-regression
nightly staging crawl with agent-browser
Local staging E2E
qa:local-staging-e2e
nightly local Playwright run
Dogfood
qa:dogfood
nightly exploratory QA with the repo-local dogfood skill
The label is the whole routing mechanism. routes.md is always rendered into the prompt and conditionally renders one route partial per matching label, so a run loads the instructions for its own route and nothing else. That partial is what tells the agent what to inspect, what evidence to attach, and what it must not touch. The manifest of every route lives in elixir/workflow_context/agencycore/README.md.
For each agent's cadence and its full brief, see the timed jobs pages; the agents section covers the two department controllers.
The part that makes this compound: all eight standing routes are report-only. They never change code. They investigate, cluster and dedupe what they find, and file focused follow-up tickets — which land back in the same queue as ordinary implementation work and get built by the normal workflow. Continuous inspection turns into routed, actionable, de-duplicated tickets without anyone triaging them by hand.
Queue — Linear holds every ticket regardless of who filed it. GitHub and Sentry sit beside it because the terminal guards read durable evidence from them. All three are rented, not run, which is what the dashed borders mean.
Coordinate — the orchestrator polls for candidate tickets, reconciles what is already running, and claims new work up to the concurrency cap. It is the only writer of scheduling state.
Execute — one run attempt per issue: a persistent workspace directory, a coding agent session, and the agent's own tools. The agent writes back to Linear itself, so ticket state, comments and PR links never pass back through the orchestrator.
Operate — the dashboard, the human reviewing and approving over Slack, and the DevOps and Accountant controllers.
Purple marks an agent, and therefore a cost: the workforce, the coding agent session, and the two department controllers are the only things on the canvas that spend an LLM call.
The whole service is a single Elixir/OTP daemon. Optional extensions are in-process OTP controllers, and they are dry-run by default.
The three panels along the bottom touch every stage of the loop, which is why no arrow points at them from it. Drawing one arrow per stage would add fifteen lines and say nothing.
Policy is the target repo's WORKFLOW.md — front matter for runtime settings, body for the prompt. The store watches the file, and the config layer resolves types, defaults and $ENV before anything downstream sees a value. The reload behaviour is not uniform, and the difference bites: the orchestrator and the prompt builder pick up most keys about a second after a save, but the extension controllers read theirs once at boot, so flipping a devops.* or accountant.* key does nothing until the service is restarted.
Observability is strictly read-only. Turn events fan out into structured logs, redacted and retention-bounded, and into per-session metrics — token accounting, rate-limit state and runtime for one issue. Those surface through journald and the loopback-bound /api/v1 snapshot the dashboard reads. Nothing here feeds back into scheduling.
Host hygiene is the three timers that file no ticket. They act on the box directly, which is what separates them from the eight agents in the workforce layer: janitorial work, not delegated work. Their failure path is shared by every timer on the host, agent-filing or janitorial — one templated OnFailure= unit posts the failed unit's name to Slack, so a job that dies silently still surfaces.
For the workflow this design serves, and the day-to-day engineer playbook, see Symphony orchestration.