Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Orchestrator

The orchestrator is the brain of agentful - the conductor that leads a symphony of specialized agents without ever playing an instrument itself. It doesn't write code. It thinks, plans, delegates, validates, and tracks progress.

What is the Orchestrator?

The orchestrator is an AI agent with a unique constraint:

---
name: orchestrator
description: Coordinates autonomous product development. Reads state, delegates to specialists, tracks progress. NEVER writes code directly.
model: opus
tools: Read, Write, Edit, Glob, Grep, Task, AskUserQuestion, TodoWrite
---
Key characteristics:
  • Uses Opus model (most capable for reasoning)
  • Has Task tool (can spawn other agents)
  • Has AskUserQuestion tool (can request input)
  • Cannot write code directly (by design)
  • Coordinates through state files

Why "Never Code Directly"?

The Anti-Pattern

An orchestrator that writes code leads to:

  • Scope confusion - Mixing frontend and backend concerns
  • Quality inconsistency - Not following domain-specific patterns
  • Bypassing specialists - Underutilizing expert agents
  • Bottlenecks - Everything depends on one agent's knowledge

The agentful Pattern

The orchestrator that only delegates ensures:

  • Clear separation - Backend agent handles backend, frontend handles frontend
  • Pattern consistency - Each agent follows its domain's best practices
  • Parallel execution - Multiple agents can work simultaneously
  • Expert utilization - Right tool for the right job
❌ Bad Orchestrator:
"I'll implement authentication myself"
  → Writes auth service
  → Writes login page
  → Writes tests
  → Everything looks the same, no domain expertise
 
✅ Good Orchestrator:
"Backend agent, implement JWT service"
"Frontend agent, create login page"
"Tester agent, write auth tests"
  → Each uses domain-specific patterns
  → Quality is higher
  → Work can be parallelized

The Orchestrator's Responsibilities

1. State Management

The orchestrator is the steward of state. It always reads these files first:

# Read in this order
1. PRODUCT.md              # What we're building
2. .agentful/state.json    # Current work state
3. .agentful/completion.json  # What's done/not done
4. .agentful/decisions.json   # Pending user decisions
State JSON structure:

.agentful/state.json

{
  "version": "1.0",
  "current_task": "user-profile-backend",
  "current_phase": "implementing",
  "iterations": 7,
  "last_updated": "2026-01-18T00:00:00Z",
  "blocked_on": []
}

.agentful/completion.json

{
  "features": {
    "authentication": {
      "status": "complete",
      "score": 100,
      "completed_at": "2026-01-18T01:00:00Z"
    },
    "user-profile": {
      "status": "in_progress",
      "score": 45,
      "notes": "Backend done, frontend pending"
    }
  },
  "gates": {
    "tests_passing": true,
    "no_type_errors": true,
    "no_dead_code": true,
    "coverage_80": false
  },
  "overall": 48
}

2. Delegation

The orchestrator's primary job is picking the right agent for each task:

// Backend work
Task("backend", "Implement user authentication with JWT per PRODUCT.md")
 
// Frontend work
Task("frontend", "Create login page with email/password form")
 
// Tests
Task("tester", "Write unit tests for auth service")
 
// After ANY work, ALWAYS run reviewer
Task("reviewer", "Review all changes in src/auth/")
Delegation rules:
  • Always use Task tool (never implement directly)
  • Be specific about what needs to be done
  • Reference PRODUCT.md for context
  • Follow with reviewer for validation

3. Decision Handling

When user input is needed, the orchestrator:

  1. Adds to decisions.json:
{
  "id": "decision-001",
  "question": "Should auth use JWT or session cookies?",
  "options": [
    "JWT (stateless, scalable)",
    "Sessions (simpler, built-in)",
    "Clerk (managed service)"
  ],
  "context": "Building authentication system for PRODUCT.md",
  "blocking": ["auth-feature", "user-profile-feature"],
  "timestamp": "2026-01-18T00:00:00Z"
}
  1. STOPS work on blocked features
  2. MOVES to next non-blocked work
  3. TELLS user to run /agentful-decide

4. Completion Tracking

After validated work, the orchestrator updates completion.json:

{
  "features": {
    "authentication": {
      "status": "complete",
      "score": 100,
      "completed_at": "2026-01-18T01:00:00Z"
    }
  },
  "gates": {
    "tests_passing": true,
    "no_type_errors": true,
    "no_dead_code": true,
    "coverage_80": true
  },
  "overall": 100
}

5. Work Selection Priority

When selecting next work, the orchestrator uses this order:

1. Critical failures
   → Broken tests, type errors, blocked PRs
 
2. Unblock work
   → Things waiting on a single small decision
 
3. High priority features
   → As defined in PRODUCT.md
 
4. Medium priority features
 
5. Tests for completed features
 
6. Polish/Optimization
   → Only when everything else is done

The Orchestrator Loop

Continuous Iteration

The orchestrator loops until complete:

┌─────────────────────────────────────────────────────────────┐
│                    Orchestrator Loop                         │
└─────────────────────────────────────────────────────────────┘
 
1. Read state files
   - state.json (current work)
   - completion.json (progress)
   - decisions.json (blockers)
 
2. Check for blockers
   - If pending decisions exist
     → Move to unblocked work
     → Tell user to run /agentful-decide
 
3. Pick next task
   - Use priority order
   - Select highest value unblocked work
 
4. Delegate to specialist
   - Task("@backend", "Implement user profile API")
   - Wait for completion
 
5. Validate results
   - Task("@reviewer", "Review profile changes")
   - If issues found → Task("@fixer", "Fix issues")
   - Loop validation until clean
 
6. Update state
   - completion.json: feature = complete, score = 100
   - state.json: current_task = null
 
7. Check completion
   - overall == 100?
   - All gates passing?
   - All features complete?
 
   YES → Output: AGENTFUL_COMPLETE
   NO  → Loop to step 1

Example Flow

[Read state]
  → completion.json: auth = 30% (backend done)
  → state.json: current_task = null
 
[Delegate]
  → Task("@frontend", "Create login page component")
 
[Wait]
  → Frontend agent completes:
     - Created login-form.tsx
     - Added useAuth hook
     - Styled with Tailwind
 
[Validate]
  → Task("@reviewer", "Review login form")
 
[Reviewer finds]
  - Missing error handling
  - Unused import
  - No tests yet
 
[Fix]
  → Task("@fixer", "Fix reviewer issues")
  → Fixer removes unused import
  → Fixer adds error handling
  → Note: Tests will be added by tester agent
 
[Re-validate]
  → Task("@reviewer", "Re-review login form")
  → Reviewer: All checks passed ✅
 
[Update]
  → completion.json: auth = 60% (frontend done)
 
[Loop]
  → What's next? Read state...
  → Pick next task: "Write auth tests"

Orchestrator Decision Making

How It Picks Tasks

The orchestrator uses multi-factor decision making:

// Pseudocode of orchestrator logic
function pickNextTask(state, completion, decisions) {
  // Factor 1: Critical failures (highest priority)
  const failures = getCriticalFailures(completion.gates);
  if (failures.length > 0) {
    return fixCriticalFailure(failures[0]);
  }
 
  // Factor 2: Unblock work (high value, low effort)
  const blocked = getBlockedFeatures(decisions);
  const unblockable = blocked.filter(f => f.unblockEffort === 'low');
  if (unblockable.length > 0) {
    return unblockFeature(unblockable[0]);
  }
 
  // Factor 3: High priority features
  const highPriority = getFeaturesByPriority(completion, 'HIGH');
  const incomplete = highPriority.filter(f => f.status !== 'complete');
  if (incomplete.length > 0) {
    return continueFeature(incomplete[0]);
  }
 
  // Factor 4: Tests for completed features
  const untested = getCompletedButUntested(completion);
  if (untested.length > 0) {
    return testFeature(untested[0]);
  }
 
  // Factor 5: Polish (only when everything else done)
  if (completion.overall === 100 && allGatesPassing(completion)) {
    return null; // Done!
  }
 
  return continueNextFeature();
}

Intelligent Task Batching

The orchestrator can batch related work:

// Instead of:
Task("backend", "Create user repository")
Task("backend", "Create user service")
Task("backend", "Create user routes")
 
// It batches:
Task("backend", "Implement complete user module:
  - UserRepository with CRUD operations
  - UserService with business logic
  - User routes (GET /api/users, POST /api/users)
  Per PRODUCT.md section 4")

This reduces:

  • Context switching
  • Validation overhead
  • State update frequency

Orchestrator Communication

With Specialist Agents

The orchestrator communicates via Task tool delegation:

// Clear, specific delegation
Task("backend", `
  Implement JWT authentication per PRODUCT.md section 3:
  - Create Auth service with login/register methods
  - Add JWT token generation and validation
  - Create /api/auth/login and /api/auth/register routes
  - Use bcrypt for password hashing
  - Return appropriate error responses
`)
 
// Specialist agent completes and reports back
// Orchestrator reads output and validates

With User

The orchestrator uses state files and slash commands:

// When decision needed:
// 1. Add to decisions.json
{
  "id": "decision-001",
  "question": "Should auth use JWT or session cookies?",
  "blocking": ["auth-feature"]
}
 
// 2. Update state.json
{
  "blocked_on": ["auth-feature"]
}
 
// 3. Tell user
"⚠️  Pending decision needed. Run /agentful-decide"
 
// 4. User runs /agentful-decide
// 5. Orchestrator reads resolved decision
// 6. Removes from blocked_on
// 7. Continues work

With State Files

The orchestrator continuously updates state:

// Before work
{
  "current_task": "user-profile-backend",
  "current_phase": "implementing",
  "iterations": 7
}
 
// After work
{
  "current_task": null,
  "current_phase": "idle",
  "iterations": 8
}
 
// After validation
{
  "features": {
    "user-profile": {
      "status": "complete",
      "score": 100
    }
  },
  "overall": 72
}

Orchestrator in Ralph Loop

Ralph Wiggum Integration

When running in continuous mode (/ralph-loop), the orchestrator:

  1. Outputs completion promise ONLY when truly complete:
<promise>AGENTFUL_COMPLETE</promise>
  1. Loops continuously until complete:
Each iteration:
  1. Re-read state files (they may have changed)
  2. Pick next work item
  3. Delegate to specialist agent
  4. Wait for agent to complete
  5. Run reviewer
  6. Fix any issues found
  7. Update completion state
  8. Loop (don't output AGENTFUL_COMPLETE yet)
  1. Never outputs AGENTFUL_COMPLETE prematurely:
// ❌ WRONG - Outputs too early
if (featureComplete) {
  output("<promise>AGENTFUL_COMPLETE</promise>");
}
 
// ✅ RIGHT - Only when truly done
if (allFeaturesComplete && allGatesPassing) {
  output("<promise>AGENTFUL_COMPLETE</promise>");
}

Continuous Mode Example

# User starts continuous mode
/ralph-loop "/agentful-start" --max-iterations 50 --completion-promise "AGENTFUL_COMPLETE"
 
# Orchestrator runs 24/7:
Iteration 1:
 Implement auth backend (backend agent)
 Review finds: 3 issues
 Fix issues (fixer agent)
 Re-review: Clean
 
Iteration 2:
 Implement auth frontend (frontend agent)
 Review: Clean
 Write tests (tester agent)
 Coverage: 85%
 
Iteration 3:
 Implement user profile backend
 Need decision: "Which fields to include?"
 Add to decisions.json
 Move to unblocked feature: settings page
 
[... continues for hours ...]
 
Iteration 47:
 All features complete (100%)
 All gates passing
 Output: <promise>AGENTFUL_COMPLETE</promise>
 
# Loop exits, work complete!

Orchestrator Best Practices

DO ✅

  • Always read state first - Before any action
  • Always delegate - Never implement directly
  • Always validate - Reviewer after every change
  • Always update state - Track progress accurately
  • Move on when blocked - Don't wait for decisions
  • Batch related work - Reduce overhead
  • Be specific - Clear delegation instructions

DON'T ❌

  • Never write code - Delegate to specialists
  • Never skip validation - Always run reviewer
  • Never guess decisions - Ask user via decisions.json
  • Never block on single item - Work on unblocked features
  • Never ignore state - It's the source of truth
  • Never promise complete early - Only when truly done

Orchestrator vs. Traditional Project Manager

AspectTraditional PMagentful Orchestrator
Task assignmentManual to team membersAutomatic to agents
Progress trackingUpdates, spreadsheetsstate.json files
Quality controlManual code reviewAutomated reviewer
Blocker handlingMeetings, emailsdecisions.json
Work selectionIntuition, priority listsAlgorithmic + priority
AvailabilityBusiness hours24/7
SpeedDays/weeksMinutes/hours

Summary

The orchestrator is agentful's coordination layer:

  • Thinks, doesn't code - Delegates to specialists
  • State-driven - All decisions based on state files
  • Continuous - Loops until 100% complete
  • Blocker-aware - Works around decisions needed
  • Quality-focused - Validates everything
  • Intelligent - Picks highest value work

It's the difference between a micro-manager (doing everything yourself) and a conductor (coordinating experts to create a symphony).

Next: Learn about slash commands