Skip to main content
Stoneforge orchestrates AI coding agents through three primary roles: Director, Worker, and Steward. Each role has distinct responsibilities and lifecycle patterns.

Role Overview

Director

Strategic plannerCreates and prioritizes tasks

Worker

Code producerExecutes tasks in isolation

Steward

Maintenance agentHandles merge and recovery

Director

The Director is the strategic coordinator that translates human goals into actionable work.

Responsibilities

  • Receives goals from human operators
  • Breaks down work into discrete tasks
  • Sets priorities (1-5 scale, 1 is highest)
  • Defines task dependencies
  • Creates plans for related task groups
  • Reports status to human when requested
  • Does NOT monitor workers (handled by daemon)
  • Does NOT dispatch tasks (handled by daemon)
  • Focuses on strategic planning, not tactical execution

Session Type

Persistent (Interactive) - Directors run continuously in an interactive session.
// Register a Director
const director = await orchestrator.registerDirector({
  name: 'project-director',
  createdBy: humanId,
  maxConcurrentTasks: 1,
});

// Start interactive session
await orchestrator.startSession(director.id, {
  mode: 'interactive',
  initialPrompt: 'Ready to plan work',
});

Example Workflow

Directors create tasks but do not assign them. The Dispatch Daemon handles assignment automatically.

Worker

Workers execute tasks and produce code. They come in two flavors: Ephemeral and Persistent.

Ephemeral Worker

Short-lived workers spawned per-task by the Dispatch Daemon.Key Characteristics:
  • Auto-spawned when task is available
  • Runs in isolated git worktree
  • Auto-terminates after task completion
  • Reports to Director (indirectly)

Worktree Isolation

Each ephemeral worker gets its own git worktree:
# Worktree path pattern
agent/{worker-name}/{task-id}-{slug}/

# Example
agent/e-worker-1/abc123-implement-login/
Worktrees provide true isolation - multiple workers can work on the same repository simultaneously without conflicts.

Persistent Worker

Long-lived workers for interactive, exploratory work with a human.Key Characteristics:
  • Manually started and stopped
  • Not auto-dispatched by daemon
  • Responds to human in real-time
  • Session-scoped worktree

Worker Task Execution

When a worker receives a task:
1

Read Task Context

  • Task title and description
  • Acceptance criteria
  • Dependencies and blockers
  • Handoff notes (if continuing previous work)
2

Execute Work

  • Make code changes
  • Run tests
  • Commit frequently with clear messages
  • Push to remote regularly
3

Complete or Handoff

Complete: sf task complete <task-id>
  • Moves task to REVIEW status
  • Creates merge request
  • Triggers Merge Steward
Handoff: sf task handoff <task-id> --message "reason"
  • Unassigns worker
  • Preserves worktree and branch
  • Appends handoff note to description
  • Returns task to pool for next worker

Steward

Stewards handle specialized maintenance workflows that keep the system running smoothly.

Steward Types

Focus: Code integration and quality gatesTriggers: Task moves to REVIEW statusWorkflow:
  1. Run test command
  2. If tests pass: squash-merge to main
  3. If tests fail: create handoff task with error logs
  4. Clean up merged worktree and branch
Configuration:
await orchestrator.registerSteward({
  name: 'm-steward-1',
  stewardFocus: 'merge',
  createdBy: directorId,
  triggers: [{
    type: 'event',
    event: 'task_review_ready',
  }],
});

Steward Execution Model

Stewards are ephemeral by default:
// Steward lifecycle
1. Trigger fires (event or cron)
2. Daemon spawns steward session
3. Steward executes workflow
4. Session terminates
5. Wait for next trigger
Stewards should be idempotent - safe to run multiple times without side effects.

Role Comparison Matrix

AttributeDirectorEphemeral WorkerPersistent WorkerSteward
Session TypePersistentEphemeralPersistentEphemeral
Reports ToHumanDirectorHumanSystem
DispatchManualAutomaticManualTrigger-based
WorktreeOptionalRequiredOptionalTemporary
Concurrency1Pool-limited1Pool-limited
Use CasePlanningProductionExplorationMaintenance

Registration Examples

// Register and start a Director
const director = await orchestrator.registerDirector({
  name: 'project-director',
  createdBy: humanId,
  provider: 'claude-code',
  model: 'claude-sonnet-4',
});

await orchestrator.startSession(director.id, {
  mode: 'interactive',
});

Next Steps

Orchestration Loop

See how agents are dispatched and coordinated

Task Management

Learn about task lifecycle and handoffs

Workflows

Build reusable task sequences

Dependencies

Understand blocking relationships

Build docs developers (and LLMs) love