Long-horizon multi-agent orchestration via Linear. Claude Code workers run subscription-billed in attachable tmux sessions, optionally paired with Codex via Symphony.
Symphony dispatches Codex workers through its Elixir runtime. This agent skill adds Claude Code workers to the same workflow — running as interactive sessions inside detached tmux panes in isolated git worktrees, tracked through the same Linear backlog, with smart routing that sends each task to the agent best suited for it.
You install the skill, point it at a repo, and your orchestrator agent learns how to route tasks between models, launch Claude workers securely, verify frontend output with Playwright, and close out work through Linear.
Orchestrator
/ \
Symphony claude (tmux)
(Elixir) (interactive session)
| |
Codex workers Claude workers
(sandbox, fast, (browser, reasoning,
parallel) tools, review)
| |
\________Linear________/
(shared issues & state)
Current release candidate: v3.0.0-rc2. The default backend runs Claude workers as interactive sessions in tmux panes instead of
claude -psubprocesses. This bills against the operator's Claude subscription, matches the normal interactive session model, and gives operators attachable long-running workers. Teams that prefer API-priced / headlessclaude -pcan adapt the launcher intentionally; seedocs/backend-options.md.
Long-horizon AI work needs more than "send one prompt and hope." Complex product, infrastructure, and research tasks need a harness: durable issue state, isolated worktrees, observable workers, model-specific routing, validation evidence, closeout checks, and cleanup rules. This skill turns Linear into the shared control plane for that harness, with Claude Code handling work that benefits from visual judgment, deep reasoning, browser verification, or external tools, and Codex/Symphony handling bounded parallel implementation when that is the better fit.
Different AI agents have different strengths. Running both against the same Linear backlog — each claiming tasks that match what it's best at — produces better output than either alone.
| Claude Code | Codex |
|---|---|
| Browser verification, visual judgment | Bounded, sandbox-compatible implementation |
| Deep reasoning (architecture, debugging) | Config, schema, type, migration changes |
| External tools (APIs, databases, MCP) | Test infrastructure (unit tests, fixtures) |
| Security review, code review | Mechanical refactors |
| Documentation, product copy | Parallelizable batch of similar tasks |
| E2E tests (sandbox-incompatible) | Fast execution where speed > judgment |
The skill also supports Claude-only setups for teams that don't use Codex. With the default tmux backend, no API plumbing is required — both Codex and Claude Code are subscription tools with built-in agent capabilities.
The bundled reference launcher defaults to tmux-backed interactive Claude Code because it is attachable, observable, and subscription-billed. It is the recommended path for long-running workers.
If your team prefers API-priced or fully headless execution, keep the same routing profile, Linear state machine, prompt-injection boundary, outcome block, and cleanup rules, then adapt the launcher back to a deliberate claude -p subprocess backend. The skill includes migration notes for both directions in docs/backend-options.md; the important part is choosing one backend explicitly and keeping its billing, observability, and completion semantics documented.
Before installing, make sure you have:
- An existing Symphony + Linear workflow (see symphony-linear-starter if you need to set one up)
- Claude Code and/or Codex installed
- Linear account with an API key (
LINEAR_API_KEYin your environment) - Playwright or equivalent browser automation for visual verification (recommended)
- A target git repo with orchestration configured
- On the dispatcher host:
tmux,jq,git,curl,python3(runbin/claude-doctorafter install to verify)
npx skills add jvogan/symphony-claude-laneThis clones the skill into your local skills directory (e.g. ~/.codex/skills/) so your agent can discover it.
mkdir -p "${CODEX_HOME:-$HOME/.codex}/skills"
cp -R skills/symphony-claude-lane "${CODEX_HOME:-$HOME/.codex}/skills/"Restart Codex after installing so the skill is discoverable.
Copy the skill folder into your project, then add it as a context reference in your CLAUDE.md:
<!-- In your project's CLAUDE.md -->
See @skills/symphony-claude-lane/SKILL.md for multi-model routing.git clone https://github.com/jvogan/symphony-claude-lane.git
cd symphony-claude-lane
export LINEAR_API_KEY="<linear-api-key>"
source ./env.sh
bin/claude-doctorThen install the skill into your agent, add the lane:claude label in Linear, and ask the agent to configure your target repo:
Use $symphony-claude-lane to set up long-horizon multi-agent routing for this
Symphony + Linear repo. Use tmux-backed Claude workers by default, preserve
Codex/Symphony for bounded parallel work, and document closeout and cleanup.
For the expanded setup path, see docs/quickstart.md.
Setup (the skill helps your orchestrator do this):
- Inspect a repo that already uses Symphony + Linear.
- Confirm the base workflow has guardrails (bootstrap assertions, stop-loss) before adding Claude workers.
- Analyze the repo's work patterns and ask about routing preferences.
- Create a routing profile (
.orchestration/claude-lane.yaml) with model selection criteria, label overrides, privacy rules, and cleanup policy. - Set up the Claude worker launcher — the secure process for dispatching interactive
claudesessions in tmux panes against Linear issues in isolated git worktrees. - Document the routing contract so both human operators and agents know how tasks get dispatched.
Dispatch (how it runs after setup):
- The orchestrator plans issues in Linear with routing labels or task analysis.
- Symphony picks up Codex-routed issues and dispatches Codex workers through its Elixir runtime.
- The Claude launcher picks up Claude-routed issues and dispatches interactive Claude sessions in tmux panes in isolated worktrees.
- Both types of workers post structured outcomes back to Linear when done.
- The orchestrator reviews all output in one place, integrates changes, and promotes learnings.
Routing strategies:
- task-characteristic (default): The orchestrator analyzes each issue and picks the best model based on what the task requires. Labels serve as overrides.
- label-only: Routing is determined entirely by Linear labels. Simpler but less adaptive.
The skill includes a reference launcher script and worker launch docs with a full security checklist you can adapt to your environment.
Use $symphony-claude-lane to set up smart multi-model routing for this repo —
analyze what types of work appear in the backlog and recommend which agent
handles what.
Use $symphony-claude-lane to add task-characteristic routing to this
Symphony + Linear repo with label overrides for UI and infra work.
Use $symphony-claude-lane to configure this repo for Claude-only workers
without Codex.
Use $symphony-claude-lane to update the routing profile so Claude also handles
security reviews and complex debugging.
Use $symphony-claude-lane to review the current routing and recommend changes
based on how the last wave performed.
The skill creates or updates a repo-local routing file:
.orchestration/claude-lane.yaml
That file records the adopter's decisions about:
- routing strategy: task-characteristic analysis or label-only
- backend selection: tmux by default,
claude -pby deliberate adaptation, or a hybrid split - model selection criteria: what task characteristics prefer Claude vs Codex
- label overrides: which labels always route to a specific model
- whether this is a mixed-model or Claude-only setup
- whether visual verification is mandatory for frontend work
- preferred Claude models
- which base-workflow guardrails all workers inherit
- closeout and retry behavior
- cleanup and retention policy for worktrees, snapshots, and repo-specific storage hotspots
- privacy rules for issue bodies, comments, screenshots, traces, and other artifacts
Those decisions belong in the adopter repo, not in this shared skill.
| Path | Purpose |
|---|---|
skills/symphony-claude-lane/SKILL.md |
Main routing and dispatch skill |
skills/.../references/ |
Setup, routing, dispatch, worker launch, visual verification, closeout, troubleshooting, examples |
skills/.../assets/claude-lane-profile.example.yaml |
Example repo-local routing profile |
skills/.../assets/claude-lane-guidance.snippet.md |
Starter snippet for adopter repo orchestration docs |
skills/.../assets/claude-worker.reference.sh |
Reference tmux-backed launcher (adapt to your environment) |
skills/.../assets/review-audit.reference.py |
Reference parser for current and legacy outcome comments |
skills/.../assets/worker-prompt.template.md |
Worker prompt template with trust boundary, capabilities, and closeout protocol |
skills/.../assets/linear-outcome-block.example.md |
Example machine-readable closeout comments |
skills/.../agents/openai.yaml |
Skill metadata |
bin/claude-doctor |
Preflight battery — verify env, deps, Linear connectivity, lane state |
bin/claude-version |
Print install root, branch/commit, default model env, and claude CLI version |
bin/claude-tmux-finalize |
Worker-invoked helper that writes the completion sentinel JSON |
env.sh |
Source to set lane defaults (paths, model, routing label, MCP config, env allowlist) |
mcp/worker-mcp.json |
Default MCP config (Linear only) |
mcp/worker-mcp-runpod.json |
Opt-in MCP config (Linear + RunPod) |
settings/claude-settings.tmux.json |
Per-worktree .claude/settings.json with bypassPermissions |
tests/ |
Three fully-isolated regression tests (sentinel-malformed, MCP opt-in, env isolation) |
docs/architecture.md |
Sentinel JSON contract, dispatch lock semantics, autoset-marker pattern |
docs/backend-options.md |
How to choose tmux, claude -p, or a hybrid backend intentionally |
docs/lessons.md |
Bug-by-bug postmortems from the tmux backend build |
docs/linear-setup.md |
How to set up lane:claude + model:* labels in a Linear workspace |
docs/migration-v2-to-v3.md |
What changes if you adopted v2.0.1 |
llms.txt |
Agent-oriented summary of the repo |
- Task-characteristic routing as the default strategy, with labels as overrides
- Smart model selection based on what the task requires, not static lane assignment
- Claude-only mode supported for teams without Codex
- Inherit the base workflow guardrails before expanding routing
- Playwright-first visual verification for work affecting rendered output
- Repo-local routing profiles instead of chat-only preferences
- Fail-closed Claude routing guards before launching full-access workers
- Operator-reviewed closeout by default, with self-close allowed only where proven safe
- Explicit closeout state rendered into worker prompts
- Worker environment allowlists instead of inheriting the full operator shell
- No-side-effect dry-runs for launcher validation
- Safe non-deletion when issue state cannot be confirmed
- Closeout verification so launcher/status tooling distinguishes a clean worker session exit from verified tracker state
- Outcome parser compatibility for current
symphony-outcomeblocks and legacysymphony:outcome verdict=passcomments during migration - Dry-run prompt validation without leaving worktree or run artifacts
- Security/privacy hygiene so secrets, tokens, and personal data stay out of artifacts
These are the operational defaults the lane assumes. Operator-adapted launchers should keep them.
- Explicit routing required. Workers refuse to dispatch unless the issue carries
lane:claude(or a project name matching$CLAUDE_ALLOWED_PROJECT_REGEX, or a configured assignee). Override only with--allow-unroutedfor deliberate trusted dispatch. - Allowlisted worker environment. The worker session is started with
env -i $allowlisted=value … claude …as the tmux session command, so the worker sees only what the dispatcher explicitly forwards — not the full operator shell.tmux new-session -e VAR=valueonly adds to the session env; it does not restrict, so it is not sufficient on its own. - In Review by default. Successful workers move issues to
In Reviewand stop. Use--self-closeonly on trusted direct-Done flows. - Cleanup requires integration verification. Don't remove worktrees just because the tracker says
Done— verify the branch was actually merged or the snapshot promoted first. - Fallback outcome on failure. When a worker dies before posting its outcome, a dispatcher should post a fallback
<!-- symphony-outcome -->comment and move the issue to$CLAUDE_TMUX_FAILURE_STATE(defaultTodo). Prevents stuck-in-In-Progress tickets. - First-launch dialogs handled defensively. Real Claude Code shows trust + bypass-permissions dialogs in interactive mode (no flag suppresses them). The dispatcher must detect and dismiss them via
tmux capture-pane+tmux send-keysbefore pasting the prompt. Seedocs/lessons.md. - MCP defense-in-depth. Tools (
mcp__runpod__*) and credentials (RUNPOD_API_KEY) are jointly opt-in. A worker cannot bypass the MCP gate by calling RunPod via rawcurlbecause the credentials are also withheld.
This is a portable blueprint with a reference implementation, not a turnkey production system.
It includes a reference launcher script (claude-worker.reference.sh) and worker launch docs (references/worker-launch.md) that show the full secure launch pattern. Adapt these to your environment.
The reference launcher spawns an interactive claude session inside a detached tmux pane (tmux new-session -d). The session command is env -i $allowlisted=value … claude … so the worker process starts with a stripped environment containing only the allowlisted variables — tmux -e is not used because it adds vars without restricting them. Workers signal completion through a JSON sentinel file written by the bundled bin/claude-tmux-finalize helper.
It does not bundle:
- a machine-specific
env.shor auth setup - a background watchdog or queue poller
- a one-size-fits-all Linear schema
- hardcoded assumptions about your repo layout or branch strategy
- an implicit cleanup daemon or retention policy
Those belong in the adopter's local tooling or repo-specific orchestration layer.
Multi-model workflows commonly use git worktrees plus run artifacts (logs, screenshots, traces, validation output). Those add up quickly, especially in frontend repos with large dependency trees.
Adopters should treat cleanup as part of the routing design:
- document who cleans terminal-state worktrees and when
- keep
In Reviewartifacts until integration is complete - monitor disk usage during larger waves
- make sure cleanup fails closed when tracker state cannot be confirmed
- record repo-specific storage hotspots in the routing profile
Use Linear labels, projects, or assignee filters to route issues to Claude, then launch a worker into an isolated git worktree. The tmux reference launcher reads the issue, renders a bounded worker prompt, starts claude in an attachable tmux session, and waits for bin/claude-tmux-finalize to write the completion sentinel.
claude -p is headless and API-priced; tmux-backed Claude Code is interactive, attachable, and subscription-billed. The default reference launcher uses tmux because it is better for long-horizon work where an operator may need to observe or recover a live session. If you prefer API pricing or a fully non-interactive subprocess, adapt the launcher using docs/backend-options.md.
Yes. In Claude-only mode, Linear is still the control plane and this skill still gives you routing profiles, closeout rules, prompt safety, visual verification guidance, and cleanup policy. Symphony/Codex becomes optional instead of required.
Long-running multi-agent work needs durable state outside any one chat or terminal. Linear gives operators a shared queue, assignment and label controls, status transitions, and a permanent audit trail for outcomes.
RunPod is opt-in at two layers: MCP tools are only loaded from mcp/worker-mcp-runpod.json, and RunPod environment variables only enter the worker allowlist when CLAUDE_WORKER_ENABLE_RUNPOD=true. The default worker environment excludes RUNPOD_API_KEY.
- symphony-linear-starter — The base orchestration skill for Symphony + Linear, with self-improving runbooks, bootstrap scripts, and issue contracts. Install this first if you don't have Symphony + Linear set up yet.
- OpenAI Symphony — Elixir-based dispatch and isolation runtime for Codex workers
- Linear — issue tracker used for routing and state
- Claude Code — agent runtime for Claude workers
- Codex — agent runtime for Codex workers
- Agent Skills spec — the open standard this skill follows
Contributions and feedback welcome via GitHub issues.
