Agent systems
Symphony
A workspace for running coding agents, following their work, and carrying changes through review and delivery.
Symphony carries coding work from an issue through implementation, review, and a decision about delivery. It gives me a place to see what the agents are doing, stop them, and take a closer look.
I built it from OpenAI’s original specification. That release provided the spec. I wrote an independent implementation and have since changed both the system and its specification.
A workflow picks up an issue and assigns a lead agent. The lead can ask helpers to investigate or make changes. Helpers that write code get separate worktrees. Codex, Claude, and Pi connect through their own protocols, and workers can run locally or over SSH.
Before a merge, Symphony checks the required reviews, the risk rules, and CI for the commit in question. If the branch changes, it has to be checked again. The cockpit shows the queue, individual runs, retries, and usage, with controls to pause, inspect, or rerun work.
The control plane runs on one node. I’m working on recovery when providers fail and testing the delivery path from end to end, including optional deployment and rollback.
How it works / Explore the workflow
From an issue to a merge
An issue gets a workspace and a lead agent. When a pull request is ready, Symphony checks the required reviews and can read CI for that commit. The operator can inspect or pause the work. When merging is enabled, only the checked commit can be merged.
Learnings
“Finished” is a surprisingly expensive word in an agent interface. It can mean that a process stopped, a message ended, or the requested work succeeded. The next system in the chain needs to know which one happened. In Symphony, a completed Codex turn could contain an authentication failure; a Pi end event could arrive before retry or compaction had settled.
The broader problem is translating between systems that divide work differently. Each provider has its own idea of a turn, an error, and a chance to continue. An adapter has to preserve those distinctions long enough for the caller to make a sound decision. Giving unlike events the same name only moves the confusion downstream.
Review and CI bring time into the problem. Approval applies to a particular change. A passing check applies to the code it ran against. When another commit arrives, those facts still exist, but their scope has not grown with the branch. Automation needs to carry that scope all the way to the merge decision, especially when several agents can change the work.