Skip to content

Events

Orcho writes lifecycle events to events.jsonl.

events.jsonl is the append-only run timeline. CLI output is one presentation of that timeline. Headless consumers such as MCP clients, dashboards, SDK readers, and reconnecting tools should read events and persisted artifacts instead of scraping terminal text.

Each line is one JSON object:

{
"seq": 12,
"ts": "2026-06-29T14:27:18.123",
"kind": "phase.end",
"phase": "review_changes",
"payload": {
"title": "REVIEW_CHANGES",
"outcome": "rejected"
}
}

Top-level fields:

FieldMeaning
seqMonotonic sequence number within the run event stream.
tsTimestamp written by the event store.
kindStable event kind string such as run.start or gate.end.
phaseActive phase tag when known; null when not phase-scoped.
payloadEvent-specific data. Required keys depend on kind.

The run id is normally the containing run directory or the status/evidence context that pointed the consumer at this file. It is not repeated as a top-level field on every event line.

Required payload keys are a lower bound, not the complete schema. Extra fields are allowed. Unknown event kinds are accepted so plugin authors can emit advisory events without patching core first.

{
"seq": 1,
"ts": "2026-06-29T14:27:00.000",
"kind": "run.start",
"phase": null,
"payload": {
"task": "Add validation to the login endpoint",
"run_kind": "single_project",
"project": "/repo/app",
"profile": "feature"
}
}

Use run.start and run.end to open and close the run lifecycle.

{
"seq": 8,
"ts": "2026-06-29T14:27:10.000",
"kind": "phase.start",
"phase": "implement",
"payload": {
"title": "IMPLEMENT"
}
}

Use phase.start and phase.end to render progress rows.

{
"seq": 31,
"ts": "2026-06-29T14:29:42.000",
"kind": "gate.end",
"phase": "review_changes",
"payload": {
"name": "review_changes",
"outcome": "rejected",
"duration_s": 42.4
}
}

Use gate.start, gate.end, and phase-specific verdict events such as validate_plan.verdict or cross_final_acceptance.verdict to update decision chips.

{
"seq": 44,
"ts": "2026-06-29T14:30:05.000",
"kind": "artifact.created",
"phase": "final_acceptance",
"payload": {
"path": "review.json",
"artifact_kind": "review"
}
}

Use artifact.created to learn that a durable file exists. Read the artifact itself for the full content.

{
"seq": 52,
"ts": "2026-06-29T14:30:40.000",
"kind": "phase.handoff_requested",
"phase": "validate_plan",
"payload": {
"phase": "validate_plan",
"handoff_type": "operator_decision",
"trigger": "plan_rejected",
"round": 2,
"handoff_id": "handoff_20260629_143040"
}
}

Use phase.handoff_requested for pause/resume UX. Do not infer handoff state from terminal banners.

FamilyExamplesUse
Run lifecyclerun.start, run.endOpen and close a run.
Phase lifecyclephase.start, phase.endRender phase progress.
Agent runtimeagent.start, agent.tool_use, agent.summaryShow runtime activity and usage.
Typed contractsagent.contract_ready, plan.parsedKnow that structured output was produced and parsed.
Gatesgate.start, gate.end, validate_plan.verdictUpdate approval/rejection state.
Handoffsphase.handoff_requestedPause and resume safely.
Cross-projectcross_validate_plan.verdict, cross_final_acceptance.verdict, cross.delivery.*Observe cross-project planning, release gate, and delivery.
Subtask DAGsubtask.start, subtask.end, subtask.receiptRender compact DAG implementation progress.
Artifactsartifact.createdLocate durable files.

The canonical registry lives in orcho-core/docs/reference/event_registry.md and the event vocabulary in core/observability/event_kinds.py.

These surfaces answer different questions.

SurfaceQuestionRule
EventsWhat happened, in what order?Durable progress facts.
EvidenceWhy is this run ready or blocked?Proof and delivery explanation.
NotificationsHow does a client learn faster?Delivery channel, not source of truth.

If an observer disconnects, it should resume from durable state. It should not ask the running process to remember what the observer missed.

For MCP clients:

  1. Use orcho_run_status for current state and run id.
  2. Use orcho_run_events_tail for live progress.
  3. Use orcho_run_evidence for proof and final explanation.
  4. Use orcho_run_diagnose when the run stops unexpectedly.
  5. Use delivery or handoff tools only after the typed state says a decision is required.

Use events for progress. Use status for state. Use evidence for readiness.

Event kind strings are wire shape. Do not rename an existing event kind without a migration plan. Adding optional payload fields is compatible. Adding a new required key to an existing event is a breaking change for consumers that validate payloads.