Purpose: Remove the human as the routing bottleneck between triage and execution. The orchestrator is a phase, not a daemon. It runs at defined trigger points inside the existing autopilot loop.
INBOX ──/triage──> BACKLOG ──/workflow──> TODO-Today ──/autopilot──> DONE-Today
│
┌────┴────┐
│ ROUTE │ ← orchestrator phase
└────┬────┘
│
agent executes
The ROUTE phase inserts between queue population and execution.
It does NOT replace /workflow — it augments the autopilot's task pickup.
The orchestrator fires at exactly two trigger points:
After reading the next - [ ] item from TODO-Today.md, before DOR check:
- Stall check — Is the current/last item stuck? (see §Stall Detection)
- Assignment check — Does the item have an
@agenttag? If not, route it. - Unblock scan — Did a recently completed item satisfy any
needs:dependency in BACKLOG.md? If yes, surface it for queuing. - Context preload — Assemble file refs, risk flags, and prior art into
_Context:_line.
After queue done moves an item to DONE-Today.md:
- Dependency cascade — Check BACKLOG.md for items with
needs: <completed_item>. If found and Ready, auto-suggest queuing with routing assignment. - Stall reset — Clear
stall:Ncounter on the completed item's slot. - Planning trigger — If queue has <= 1 unchecked item, suggest a planning round (per §8.5).
The orchestrator reads:
- The task description (bold text after checkbox)
- The
/sc:command hint (line 2 of queue format) - The
_Context:_line (line 3, optional)
For each registered agent in AGENT_CAPABILITIES.md:
score = sum(keyword_match(task_keywords, agent.strengths))
+ context_bonus(task_files, agent.context_access)
- constraint_penalty(task_requirements, agent.constraints)
keyword_match: Each task keyword that appears in an agent'sstrengthslist scores +1.context_bonus: +2 if the agent has direct access to the files mentioned in Context.constraint_penalty: -10 if the agent cannot satisfy a hard requirement (e.g., no repo write access for an implementation task).
The orchestrator annotates the TODO-Today item:
- [ ] **implement** FE-32 font preview refresh `@claude` `stall:0`
`/sc:implement "font preview refresh" --focus frontend`
_Context: font_detail.html, fonts.js — confidence:0.9_New fields (appended to line 1 or line 3):
@agent— routed assignment (from capability scoring)stall:N— stall counter (starts at 0, incremented by supervisor)confidence:X.X— routing confidence score (0.0–1.0), informational
If no agent scores above 0.3 confidence, or if multiple agents tie:
- Tag as
@unrouted - Write to
.claude-action:"ROUTE: unrouted task — manual assignment needed" - Autopilot continues with next routable item (does not block)
A task is considered stalled when:
- Time-based:
.claude-actionand.claude-activityboth unchanged for > N minutes (threshold from supervisor config, default: 10min, 30min for requirements sessions) - Error-loop: Same error pattern appears 3+ times in
.console-logtail (100 lines) - Explicit: Agent writes
STALLED: <reason>to.claude-action
| Stall Level | Trigger | Action |
|---|---|---|
stall:1 |
First detection | Log warning, increment counter |
stall:2 |
Second consecutive check | Write to .claude-action: "STALL WARNING: <task> — 2 cycles" |
stall:3 |
Third consecutive check | Pause autopilot, toast notification, escalate to human |
When a stall is detected on a multi-agent setup:
- If another agent has capability for the task, suggest re-routing
- Otherwise, escalate to human
Counter resets to 0 when:
.claude-actioncontent changes (agent made progress).claude-activitymtime advances- Task is completed or manually re-assigned
When the orchestrator assigns a task, it assembles a context hint in the _Context:_ line:
- File references — Files mentioned in the task description or spec
- Related Tether threads — If the task originated from a Tether message, include thread name
- Prior art — If DONE-Today or archives contain related completed items, reference them
- Risk flags — If the task touches an item in
BACKLOG.md ## Risks, surface the risk entry
This is informational — the executing agent reads it as starting context, not as a binding constraint.
After task execution, before commit (runs inside the Cleanup Sub-Loop):
- Greenlight — Project's greenlight must pass (existing gate, unchanged)
- KNOWN_PATTERNS scan — Check diff against
KNOWN_PATTERNS.mdfor anti-pattern reintroduction - Constraint check — Verify no CLAUDE.md constraint violation in the diff
If validation fails, the orchestrator does NOT accept the result:
- Low findings: auto-fix loop (existing behavior)
- Medium+ findings: pause autopilot (existing behavior)
This gate already exists in CLAUDE-LOOP.md's Cleanup Sub-Loop. The orchestrator adds no new validation steps — it just names the existing gate as part of the routing lifecycle.
Existing format (unchanged):
- [ ] **Phase: Task description**
`/sc:command "args" --attribute`
_Context: brief notes, file refs, links_Extended format (orchestrator adds):
- [ ] **Phase: Task description** `@claude` `stall:0`
`/sc:command "args" --attribute`
_Context: brief notes, file refs, links — confidence:0.85_New optional fields:
| Field | Location | Set by | Meaning |
|---|---|---|---|
@agent |
Line 1, after description | Orchestrator | Assigned agent |
stall:N |
Line 1, after @agent | Supervisor | Stall counter |
confidence:X.X |
Line 3, in Context | Orchestrator | Routing confidence |
All fields are optional. Items without @agent are treated as @claude (default agent). The autopilot executor ignores these tags — they are metadata for the orchestrator and supervisor.
The supervisor already monitors stall conditions via .claude-action mtime. The orchestrator formalizes this into the stall:N counter. No changes to supervisor needed — it continues to monitor files. The orchestrator reads supervisor output, not the reverse.
When multiple agents are active:
- Orchestrator posts task assignments via
tether_send(to=agent, subject="task-assignment", ...) - Agent reports completion via
tether_send(to="orchestrator", subject="task-complete", ...) - For Claude-only mode (current): Tether is not used. Routing is local file annotation only.
The orchestrator participates in planning rounds by providing:
- Routing statistics (how many tasks routed to each agent)
- Stall history (which tasks stalled, how resolved)
- Unblock cascade results (which dependencies were auto-resolved)
The orchestrator respects the semaphore exactly like the executor:
run→ proceed with routingpause→ stop, do not route- The orchestrator can write
pause(on stall:3 escalation)
- Does NOT replace
/workflow— queue population is still human-driven or planning-round-driven - Does NOT execute tasks — it routes and monitors, the executor runs
- Does NOT manage BACKLOG graduation — that stays with DOR/DOD gates
- Does NOT spawn parallel agents — single-threaded execution preserved
- Does NOT require Tether for Claude-only mode — pure file annotation
- Does NOT add new quality gates — reuses existing greenlight + cleanup sub-loop
The orchestrator is implemented as part of the /autopilot skill, not as a separate skill or daemon.
Phase 1 (current): Claude-only routing. The orchestrator always assigns @claude with confidence 1.0. Value comes from stall detection, dependency cascade, and context preloading — not from multi-agent routing.
Phase 2 (future): When Gemini/ChatGPT are active via Tether, the scoring logic selects the best agent. Routing confidence < 1.0 triggers human confirmation before assignment.
Phase 3 (future): Orchestrator-as-agent via Tether. The orchestrator itself becomes an agent that other agents can query for priority and assignment information.