Skip to content

Data Model ​

Single SQLite file: /var/lib/orchestra/state/orchestra.db

Tables ​

mas_tasks — inbound work queue ​

ColumnNotes
idsource identifier — STU-806, gh-pr-1234, cron-maintainer-...
sourcelinear | github | slack | scheduled | maintainer | handoff | sentry | langfuse | developer. maintainer is used when the dispatcher routes approved proposals; handoff when an agent-delegated handoff creates a new task for a target agent; sentry/langfuse for observability webhook dispatches
source_event_ididempotency key (UNIQUE); NULL for handoff tasks (no external event to dedup)
source_meta_jsonsource-specific back-channel data (Linear: issue_id, team_id, urls, creator_id, creator_name, creator_email); the listener resolves the Linear issue creator via API before the delegator spawns; used by the dispatcher for Slack @-mention resolution; for handoff tasks: {"origin_task_id": "<id>", "origin_agent": "<name>"}; for scheduled manual triggers: {"operator_comment": "<text>"} passed via run-scheduled-agent.sh --comment
statuspending → running → done | failed | waiting_for_human | skipped; skipped is set by run-scheduled-agent.sh when a timer fires but a prior invocation of the same agent is still active
plan_jsonfull dispatch plan; the listener writes a placeholder row before the delegator spawns, then the delegator fills in the plan via UPDATE; validated by the dispatcher
proposal_jsonmaintainer proposal JSON (source=maintainer only)
created_at / updated_attimestamps
errorset on failure; also set for skipped rows with the overlap reason

human_tasks — agent→human questions ​

ColumnNotes
iduuid
mas_task_idFK → mas_tasks
agentwhich agent is blocked
questionshort headline for the TUI list
payload_jsonstructured AskUserQuestion payload (1–4 questions + options); free-text answers are mapped to human-readable question text by the listener using this field
statusopen → approved | declined | answered → consumed
answerJSON object keyed by question header (short label), with full question text as fallback for backward compatibility
slack_ts / slack_channelfor updating the Slack message
created_at / resolved_attimestamps

running_workers — crash recovery ​

ColumnNotes
plan_id + worker_idcomposite PK
pidOS pid; checked on dispatcher restart
started_attimestamp
workspaceworker workspace path
session_idclaude session uuid; captured from the stream-json init event; used for --resume
agentagent role name (e.g. developer)
statusrunning → done | failed | waiting_for_human | retry_requested; orphaned workers on dispatcher restart are marked retry_requested instead of failed so dispatchRetries() auto-resumes them

seen_events — webhook dedup ​

event_id + received_at. Purged after 24h by the dispatcher on startup and by the listener every 6h.

Agent state files ​

Outside the database, some agents persist state as plain files:

FileWritten byPurpose
${ORCHESTRA_STATE_DIR:-/var/lib/orchestra/state}/documenter-last-sha.txtdocumenterLast processed commit SHA for daily doc updates
${ORCHESTRA_STATE_DIR:-/var/lib/orchestra/state}/auditor-last-sha.txtauditorLast processed commit SHA for weekly security scans
${ORCHESTRA_STATE_DIR:-/var/lib/orchestra/state}/maintainer-last-sha.txtmaintainerLast processed commit SHA for commit-delta context
${ORCHESTRA_STATE_DIR:-/var/lib/orchestra/state}/maintainer-acceptance.txtmaintainerCumulative proposal acceptance-rate metrics (total, approved) broken down by target agent and priority band; serves as a calibration signal when drafting proposals; bootstrapped with zeros on first run
${ORCHESTRA_STATE_DIR:-/var/lib/orchestra/state}/monitor-metrics-prev.jsonmonitorPrevious metrics snapshot for delta-based alerting — stores total_requests, error_count, and latency counters from the last run; used to detect degradation (elevated error rates, latency spikes) between scrapes
agents/<agent>/artifacts/<plan_id>.mddocumenter, memoriser, monitor, maintainer, reviewer, auditorPer-session markdown summaries written by scheduled and event-driven agents; surfaced in the TUI Artifacts tab

Plan JSON shape ​

Written by the delegator into mas_tasks.plan_json. Validated by the dispatcher via Zod (planSchema.ts).

Standard plan (delegator-created):

json
{
  "schema_version": "1",
  "task_id": "STU-806",
  "source": "linear",
  "source_event_id": "...",
  "created_at": "...",
  "context": {},
  "workers": [{
    "id": "w1",
    "agent": "developer",
    "repo": "example-docgen",
    "branch": "agent/developer/STU-806",
    "task_input": {}
  }]
}

Handoff plan (dispatcher-created, source=handoff):

json
{
  "schema_version": "1",
  "task_id": "hoff-a1b2c3d4",
  "source": "handoff",
  "created_at": "2026-06-15T12:00:00.000Z",
  "context": {
    "handoff_from_agent": "monitor",
    "handoff_from_task_id": "cron-monitor-20260615T080000Z-12345"
  },
  "workers": [{
    "id": "w1",
    "agent": "builder",
    "repo": "orchestra",
    "branch": "agent/builder/hoff-a1b2c3d4",
    "task_input": {"summary": "...", "details": "..."}
  }]
}

Validation rules enforced by the dispatcher:

  • branch must equal agent/{agent}/{task_id}
  • repo must match [A-Za-z0-9._-]+ (no slashes)
  • schema_version must be "1"
  • workers min length 1

Indexes ​

  • idx_mas_tasks_status on mas_tasks(status) — for dispatcher poll queries
  • idx_mas_tasks_source on mas_tasks(source) — for TUI Maintenance panel filtering by source type
  • idx_human_tasks_status on human_tasks(status)
  • idx_human_tasks_mas_task on human_tasks(mas_task_id)
  • idx_seen_events_received_at on seen_events(received_at)
  • idx_running_workers_pid on running_workers(pid)
  • idx_running_workers_status on running_workers(status)
  • idx_running_workers_agent on running_workers(agent) — optimizes overlap checks in run-scheduled-agent.sh that query for active workers by agent name

TUI database queries ​

The TUI reads directly from the SQLite database for display purposes (read-only):

  • latestScheduledPerAgent() — For each unique scheduled agent, returns the most recent mas_tasks row (by updated_at) so the Scheduled panel can display last-run status (done/skipped/failed/running) inline with each timer.
  • openMonitorTaskCount() — Counts open human_tasks for the monitor agent. Used by the Scheduled panel's health badge: 0 → "Healthy", >0 → alert count.

Task lifecycle ​

pending (listener writes placeholder → delegator fills in plan via UPDATE)
  └─ dispatcher picks up → validates plan
       ├─ invalid → failed
       └─ valid → running
            └─ all workers exit 0, no open human_tasks → done
            └─ any worker exit non-0 → failed
            └─ worker opened human_task → waiting_for_human
                 ├─ human answers, no handoff → running (resumed) → done | failed
                 └─ human answers, handoff present → new pending task (source=handoff) for target agent → delegating worker marked done

Re-dispatch of same source_event_id: failed | done → revived to pending
  (dedup entry cleared; delegator re-spawned with fresh context)