feat(symphony): tracker-agnostic orchestrator plugin

Sketch of a Claude Code port of openai/symphony — a daemon-style
orchestrator that polls an issue tracker, dispatches isolated worker
agents per issue, and reconciles state across ticks. Tracker-agnostic
by design: the project's CLAUDE.md documents how to talk to whatever
tracker is in use (GitHub Issues, Gitea, tracker CLI, Linear, etc.);
the plugin reads those instructions rather than shipping per-tracker
adapters.

Includes:
- /symphony-init for first-time setup (detects gh/gitea/tracker, writes
  the tracker section into project CLAUDE.md, drops WORKFLOW.md, offers
  to schedule the tick)
- /symphony-tick fired by /schedule cron entries (idempotent, silent,
  never prompts)
- per-issue worker agent in isolated worktrees
- on-disk state in .symphony/state.json (survives cron cold starts)

Known divergences from the spec are documented in the plugin CLAUDE.md
(no streaming agent telemetry; no codex.* knobs; hooks run inside the
worker rather than the orchestrator).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
movq
2026-04-29 21:03:21 -05:00
parent 6362a7cf88
commit cd3032458c
8 changed files with 570 additions and 0 deletions

View File

@@ -0,0 +1,17 @@
---
description: Set up Symphony in the current project — detects the issue tracker, writes a tracker section into CLAUDE.md, drops a starter WORKFLOW.md, and offers to schedule the tick. Idempotent — safe to re-run to update.
---
Invoke the `symphony-init` skill. It will:
1. Probe the environment for an existing tracker (gh, gitea MCP, `.tracker/` CLI, etc.)
and existing Symphony config (`./WORKFLOW.md`, tracker section in `./CLAUDE.md`).
2. Interview you for anything it could not detect — which tracker, active/terminal
state names, concurrency cap, branch naming, etc.
3. Write or update the tracker integration section in `./CLAUDE.md` so future ticks
and workers know how to talk to your tracker.
4. Drop `./WORKFLOW.md` from the plugin's template, prefilled with what it learned.
5. Offer to set up a `/schedule` entry that fires `/symphony-tick` on a cadence.
Run this once per repo. Re-run any time the tracker changes or you want to update
the schedule.

View File

@@ -0,0 +1,20 @@
---
description: Run one Symphony orchestrator tick. Reads WORKFLOW.md, polls the tracker, dispatches workers, reconciles state. Idempotent — safe to fire on a cron.
---
Invoke the `symphony` skill with no arguments. The skill owns the full tick:
1. Load `./WORKFLOW.md` (error → log and exit; do not fall through).
2. Read `.symphony/state.json` (create empty if missing).
3. Query the tracker for issues in `active_states`, minus issues already in `running` or
in retry-cooldown.
4. Reconcile: for each `running` entry, confirm via `TaskList` the worker is still alive
and the issue still in an active state; otherwise release.
5. Dispatch up to `max_concurrent_agents - len(running)` new workers via the `Agent` tool
with `subagent_type: symphony-worker`, one per issue. Pass the issue payload + rendered
prompt template. Run workers in the background (`run_in_background: true`) so the tick
returns promptly.
6. Persist state and exit.
This command is fired by a `/schedule` cron entry — the user sets up the cadence with
`/schedule` once; the skill enforces `polling.interval_ms` only as advisory metadata.