@harness-engineering/orchestrator
v0.6.0
Published
Orchestrator daemon for dispatching coding agents to issues
Maintainers
Readme
@harness-engineering/orchestrator
Orchestrator daemon for dispatching coding agents to issues. Polls an issue tracker for candidate tasks, manages ephemeral workspaces, runs agents to resolve issues, and updates the tracker with progress.
Architecture
┌──────────────────────────────────────────────────┐
│ Issue Tracker │
│ RoadmapTrackerAdapter · Linear Extension │
└──────────────────┬───────────────────────────────┘
▼
┌──────────────────────────────────────────────────┐
│ Intelligence Pipeline (optional) │
│ SEL (spec enrichment) → CML (complexity) → │
│ ConcernSignals → PESL (simulation + abort) │
│ (@harness-engineering/intelligence) │
└──────────────────┬───────────────────────────────┘
▼
┌──────────────────────────────────────────────────┐
│ Core State Machine │
│ Candidate Selection · Concurrency Control │
│ Model Routing (routeIssue + concern signals) │
│ Reconciliation · Retry Logic │
│ Event Sourcing (applyEvent → side effects) │
└──────────────────┬───────────────────────────────┘
▼
┌────────────────┐ ┌─────────────────┐
│ Agent Runner │ │ Workspaces │
│ Claude Backend│ │ WorkspaceManager│
│ Mock Backend │ │ WorkspaceHooks │
└───────┬────────┘ └────────┬────────┘
└────────┬───────────┘
▼
┌──────────────────────────────────────────────────┐
│ Prompt Rendering (LiquidJS) │
└──────────────────────────────────────────────────┘Quick Start
import { Orchestrator, WorkflowLoader } from '@harness-engineering/orchestrator';
// Load workflow definition (config + prompt template) from a harness.orchestrator.md file
const loader = new WorkflowLoader();
const result = await loader.loadWorkflow('./harness.orchestrator.md');
if (!result.ok) throw result.error;
const { config, promptTemplate } = result.value;
// Create and start the orchestrator
const orchestrator = new Orchestrator(config, promptTemplate);
await orchestrator.start();Core Concepts
Event-Sourced State Machine
The orchestrator uses an event-sourced architecture. All state transitions are modeled as events (OrchestratorEvent) that produce side effects (SideEffect):
import { applyEvent, createEmptyState } from '@harness-engineering/orchestrator';
import type { WorkflowConfig } from '@harness-engineering/types';
const state = createEmptyState(config); // config: WorkflowConfig
const { state: next, effects } = applyEvent(state, event);
// effects: DispatchEffect, StopEffect, ScheduleRetryEffect, etc.Candidate Selection
Issues are ranked and filtered before dispatch:
import { sortCandidates, selectCandidates, isEligible } from '@harness-engineering/orchestrator';
const ranked = sortCandidates(issues);
const selected = selectCandidates(ranked, availableSlots);Intelligence Pipeline Integration
When config.intelligence.enabled is true, the orchestrator runs the intelligence pipeline during each tick:
- Pre-routing — For each candidate issue,
preprocessIssue()runs SEL (spec enrichment) and CML (complexity scoring), producingConcernSignal[]that feed intorouteIssue(). ForalwaysHumantiers, the enriched spec is attached to the escalation for human context. - Post-routing — For locally-routed issues, PESL simulation runs. If
abort: true(confidence < 0.3), the dispatch converts to an escalation. - Post-execution — On
worker_exit, execution outcomes are recorded into the graph for future CML historical scoring.
When disabled (default), the pipeline is skipped entirely and routing uses empty concern signals.
See @harness-engineering/intelligence README for full pipeline documentation.
Agent Backends
Two backends are available:
ClaudeBackend— Production backend using the Claude APIMockBackend— Test backend for deterministic behavior in tests
Workspace Management
Each agent run gets an ephemeral workspace with lifecycle hooks:
import { WorkspaceManager, WorkspaceHooks } from '@harness-engineering/orchestrator';
const manager = new WorkspaceManager(config);
const hooks = new WorkspaceHooks(config);API
Orchestrator
The main class that ties everything together:
start()— Begin polling and dispatchingstop()— Gracefully shut down- Events:
state_change,agent_event
Core Functions
| Export | Description |
| --------------------- | ----------------------------------------------------------- |
| applyEvent | Apply an event to state, returning new state + side effects |
| createEmptyState | Create an initial empty orchestrator state |
| sortCandidates | Rank issues by priority and eligibility |
| selectCandidates | Select top candidates within concurrency limits |
| isEligible | Check if an issue is eligible for dispatch |
| getAvailableSlots | Get number of available agent slots |
| canDispatch | Check if dispatch is possible given current state |
| reconcile | Reconcile expected state against actual state |
| calculateRetryDelay | Compute exponential backoff delay |
Tracker Adapters
| Export | Description |
| ------------------------ | ---------------------------------------------------- |
| RoadmapTrackerAdapter | Reads issues from docs/roadmap.md |
| LinearTrackerExtension | Extends tracking with Linear integration (planned) |
Prompt Rendering
| Export | Description |
| ---------------- | -------------------------------------------- |
| PromptRenderer | Renders LiquidJS templates for agent prompts |
License
MIT
