SPEC.md) that enables implementations in any programming language. This guide walks through building a compliant implementation.
Specification Overview
FromSPEC.md:
Symphony is a long-running automation service that continuously reads work from an issue tracker (Linear in this specification version), creates an isolated workspace for each issue, and runs a coding agent session for that issue inside the workspace.The service solves four operational problems:
- Turns issue execution into a repeatable daemon workflow
- Isolates agent execution in per-issue workspaces
- Keeps workflow policy in-repo (
WORKFLOW.md) - Provides observability to operate and debug concurrent agent runs
Architecture Layers
Symphony is organized into these abstraction levels:Policy Layer
Repository-defined workflow in
WORKFLOW.md:- YAML frontmatter for runtime settings
- Markdown prompt template for agent instructions
- Team-specific rules for ticket handling
Configuration Layer
Typed getters that parse frontmatter:
- Defaults and environment variable indirection
- Path normalization
- Validation used by orchestrator before dispatch
Coordination Layer
Orchestrator that manages:
- Polling loop and issue eligibility
- Concurrency limits and retry backoff
- Reconciliation and cleanup
Execution Layer
Workspace management and agent subprocess:
- Filesystem lifecycle
- Workspace preparation
- Coding agent protocol (app-server mode over stdio)
Core Components
1. Workflow Loader
ParsesWORKFLOW.md into config and prompt template.
2. Config Layer
Provides typed access to configuration values with defaults and environment variable resolution.Configuration Schema (from SPEC.md)
Configuration Schema (from SPEC.md)
- Environment variable resolution:
$VAR_NAMEin string values - Path expansion:
~and path separators - Type coercion: Strings to integers where specified
- Defaults: Specified in SPEC.md section 6.4
- Validation: Preflight checks before dispatch (section 6.3)
3. Issue Tracker Client
Normalizes tracker payloads into the Symphony issue model.fetch_candidate_issues()- Return issues in active statesfetch_issues_by_states(state_names)- For startup cleanupfetch_issue_states_by_ids(issue_ids)- For reconciliation
4. Orchestrator
The orchestrator owns the polling loop and runtime state.Runtime State (from SPEC.md section 4.1.8)
Runtime State (from SPEC.md section 4.1.8)
Poll Tick
- Reconcile running issues
- Validate config
- Fetch candidates
- Sort by priority
- Dispatch until slots full
Concurrency Control
- Global limit:
max_concurrent_agents - Per-state limits:
max_concurrent_agents_by_state - Available slots = max - running
Retry & Backoff
- Continuation: 1 second fixed
- Failure:
min(10000 * 2^(attempt-1), max_retry_backoff_ms) - Cap at configured max (default 5 minutes)
Reconciliation
- Stall detection based on event inactivity
- Fetch current states for running issues
- Stop workers for terminal/inactive states
5. Workspace Manager
Safety Invariants (SPEC.md section 9.5):after_create: Fatal if fails, runs once on creationbefore_run: Fatal if fails, runs before each attemptafter_run: Non-fatal, runs after each attemptbefore_remove: Non-fatal, runs before deletion
6. Agent Runner
Launches Codex in app-server mode and streams events to orchestrator.App-Server Protocol (from SPEC.md section 10)
App-Server Protocol (from SPEC.md section 10)
Launch contract:Startup sequence:
initializerequest with client info and capabilitiesinitializednotificationthread/startrequest with approval policy, sandbox, cwd, toolsturn/startrequest with threadId, input (prompt), title
- Read
thread_idfromthread/startresult - Read
turn_idfromturn/startresult - Compose
session_id = "<thread_id>-<turn_id>"
turn/completed→ successturn/failed→ failureturn/cancelled→ failure- turn timeout → failure
- subprocess exit → failure
7. Prompt Builder
Renders the prompt template with issue context.Implementation Checklist
Config Layer
- Environment variable resolution (
$VAR) - Path expansion (
~, separators) - Type coercion (string to int)
- Defaults (SPEC.md section 6.4)
- Dispatch preflight validation
Tracker Client
- Implement required operations
- Normalize to issue model
- Handle pagination
- Error categorization
Orchestrator
- Poll loop with interval
- Runtime state management
- Concurrency control
- Retry with backoff
- Reconciliation (stall + state refresh)
Workspace Manager
- Path sanitization
- Safety validation
- Hook execution (sh -lc)
- Hook timeout handling
- Terminal cleanup
Agent Runner
- App-server subprocess launch
- Protocol handshake
- Event streaming
- Timeout handling
- Approval/tool handling
Testing Strategy
Unit Tests
- Workflow parsing edge cases
- Config resolution and defaults
- Issue normalization
- Workspace path validation
- Prompt rendering
Integration Tests
- In-memory tracker for orchestrator tests
- Mock app-server for agent runner tests
- Filesystem workspace lifecycle
Conformance Tests
Test against SPEC.md requirements:- Dispatch eligibility rules (section 8.2)
- Concurrency limits (section 8.3)
- Retry backoff formula (section 8.4)
- Workspace safety invariants (section 9.5)
- Protocol message ordering (section 10.2)
Language-Specific Considerations
- Elixir/Erlang
- Python
- Go
- TypeScript/Node.js
Strengths:
- Supervision trees for worker isolation
- Built-in state management (GenServer, Agent)
- Excellent concurrency primitives
- String vs atom keys in config maps
- Timeout precision (milliseconds)
- Port vs OS process for subprocess
Conformance Validation
Must Implement
From SPEC.md section 2.1 (Goals):- Poll tracker on fixed cadence
- Maintain authoritative orchestrator state
- Create deterministic per-issue workspaces
- Stop runs when issue state changes
- Recover from transient failures with backoff
- Load runtime behavior from
WORKFLOW.md - Expose structured logs
- Support restart recovery without persistent DB
Optional Extensions
- Rich web UI (section 13.7)
- Custom tracker types beyond Linear
- Additional dynamic tools
- Telemetry/metrics integrations
Reference Implementation
The Elixir implementation is the reference: Key modules:SymphonyElixir.Workflow- Workflow loaderSymphonyElixir.Config- Config layerSymphonyElixir.Orchestrator- CoordinationSymphonyElixir.Workspace- Workspace managementSymphonyElixir.AgentRunner- Codex integrationSymphonyElixir.Linear.Adapter- Tracker client
Next Steps
Read SPEC.md
Complete language-agnostic specification
Study Reference Implementation
Elixir implementation with tests
Custom Skills
Create reusable workflow components
Extending Symphony
Add trackers, tools, and extensions