Skip to content

Events

The event store is an append-only JSONL log per feature. Every state change in a workflow is captured as an event, forming an audit trail that can be queried, replayed, and used for state reconciliation.

Event structure

Each event conforms to the base schema:

typescript
{
  streamId: string,       // Feature ID or shared stream name
  sequence: number,       // Monotonically increasing per stream
  timestamp: string,      // ISO 8601
  type: string,           // Dotted event type (e.g., "task.completed")
  correlationId?: string, // Links related events across operations
  causationId?: string,   // The event that caused this one
  agentId?: string,       // Agent that produced the event
  source?: string,        // Emission context
  schemaVersion: string,  // Data schema version (default "1.0")
  data?: object,          // Type-specific payload
  idempotencyKey?: string // Prevents duplicate appends
}

Emission sources

Each event type has a designated emission source:

SourceMeaningExample
autoEmitted by MCP server handlers (deterministic, no manual emission needed)workflow.started, gate.executed
modelExplicitly emitted by the agent via exarchos_eventteam.spawned, review.finding
hookEmitted by Claude Code lifecycle hooksbenchmark.completed
plannedSchema exists but not yet used in productioneval.run.started

Events marked auto should not be duplicated via manual exarchos_event calls. The MCP server emits them as side effects of workflow operations.

Event types (60 total)

Workflow (13)

TypeSourceDescription
workflow.startedautoWorkflow initialized. For oneshot workflows, the event data includes synthesisPolicy so it survives ES v2 rematerialization
workflow.transitionautoPhase transition
workflow.fix-cycleautoFix cycle incremented
workflow.guard-failedautoTransition guard rejected
workflow.checkpointautoState checkpointed
workflow.compound-entryautoEntered compound state
workflow.compound-exitautoExited compound state
workflow.cancelautoWorkflow cancelled
workflow.cleanupautoPost-merge cleanup
workflow.compensationautoSaga compensation action
workflow.circuit-openautoCircuit breaker tripped
workflow.cas-failedautoCompare-and-swap retry exhausted
workflow.prunedautoBatch-cancelled by prune_stale_workflows. Payload: { featureId, stalenessMinutes, triggeredBy: "manual" | "scheduled", skippedSafeguards? }. Introduced in v2.6.0

Task (5)

TypeSourceDescription
task.assignedmodelTask assigned to agent
task.claimedautoAgent claimed a task
task.progressedmodelTDD phase progress (red/green/refactor)
task.completedautoTask finished with optional evidence
task.failedautoTask failed with error details

Quality (4)

TypeSourceDescription
gate.executedautoConvergence gate ran with pass/fail result
quality.regressionmodelConsecutive gate failures detected
quality.hint.generatedautoQuality hints generated for a skill
quality.refinement.suggestedautoRefinement suggestion based on trends

Evaluation (4)

TypeSourceDescription
eval.run.startedplannedEval suite started
eval.case.completedplannedSingle eval case finished
eval.run.completedplannedEval suite finished
eval.judge.calibratedautoJudge accuracy metrics recorded

Stack (4)

TypeSourceDescription
stack.position-filledautoTask placed in stack position
stack.restackedautoStack rebased
stack.enqueuedautoPRs enqueued for merge
stack.submittedmodelStack submitted with PR numbers

Telemetry (3)

TypeSourceDescription
tool.invokedautoMCP tool call started
tool.completedautoMCP tool call finished with metrics
tool.erroredautoMCP tool call failed

Benchmark (1)

TypeSourceDescription
benchmark.completedhookPerformance benchmark results

Team (7)

TypeSourceDescription
team.spawnedmodelAgent team created
team.task.assignedmodelTask assigned to teammate
team.task.completedmodelTeammate finished a task
team.task.failedmodelTeammate task failed
team.task.plannedmodelTask planned for team
team.teammate.dispatchedmodelTeammate dispatched to worktree
team.disbandedmodelTeam dissolved after work complete

Review (3)

TypeSourceDescription
review.routedmodelPR routed to review destination
review.findingmodelReview finding recorded
review.escalatedmodelReview escalated due to critical finding

Remediation (2)

TypeSourceDescription
remediation.attemptedmodelRemediation strategy attempted
remediation.succeededmodelRemediation completed successfully

Shepherd (4)

TypeSourceDescription
shepherd.startedautoShepherd iteration loop began
shepherd.iterationmodelSingle shepherd assess-fix-resubmit cycle
shepherd.approval_requestedautoReview approval requested
shepherd.completedautoShepherd process finished

Session (8)

TypeSourceDescription
session.taggedmodelSession attributed to a feature/concern
worktree.createdmodelWorktree created for a task
worktree.baselinemodelWorktree baseline test result
test.resultmodelTest suite execution result
typecheck.resultmodelTypecheck execution result
ci.statusmodelCI status for a PR
comment.postedmodelPR comment posted
comment.resolvedmodelPR comment thread resolved

Oneshot choice state (1)

TypeSourceDescription
synthesize.requestedautoAppended by request_synthesize. Consumed by the synthesisOptedIn guard at finalize_oneshot time. Payload: { featureId, reason?, timestamp }. Duplicate appends are benign (any count ≥ 1 → opted in). Introduced in v2.6.0

Other (1)

TypeSourceDescription
state.patchedautoWorkflow state patched directly

Querying events

Query events from a stream with optional type filtering:

typescript
exarchos_event({
  action: "query",
  stream: "my-feature",
  filter: { type: "task.completed" },
  limit: 10
})

Wildcard patterns are supported for type-based queries:

typescript
exarchos_event({
  action: "query",
  stream: "my-feature",
  filter: { type: "workflow.*" }
})

Appending events

Model-emitted events are appended explicitly:

typescript
exarchos_event({
  action: "append",
  stream: "my-feature",
  event: {
    type: "team.spawned",
    data: {
      teamSize: 3,
      teammateNames: ["impl-1", "impl-2", "impl-3"],
      taskCount: 3,
      dispatchMode: "parallel"
    }
  }
})

Optimistic concurrency is supported via expectedSequence to detect conflicting writes.

Custom event types

Custom event types can be registered at runtime for project-specific concerns. Custom types must follow the category.name dot-notation pattern and cannot collide with built-in types.

Released under the Apache-2.0 License.