Skip to main content

Runtime events

Everything the runtime does that another part of the system can react to travels as one RuntimeEvent on a single in-process broadcast bus. The desktop application, the HTTP streams, the notification engine, the audit journal and the observability store are all readers of that one bus.

This page is the catalogue. It is generated from the Rust source, so it says what the binary carries and not what an earlier design intended.

What a variant name is​

A variant name is a wire contract. It reaches the desktop application inside the runtime-event envelope as event_type, and it reaches an HTTP client through the task and chat event streams. Renaming one breaks every reader that matched on it, so a rename is a wire-format change, not a refactor.

Categories, and why they matter more than names​

The desktop bridge does not forward variant names for the interface to switch on. It attaches a category, and the webview dispatches on that: one category maps to one refresh, one store, one panel. A variant added to an existing category is read by whatever already reads that category; a variant given a new category is read by nobody until a listener exists for it.

That asymmetry is why the category is in the table below. Three variants sat in categories no listener read, and the interface received them and did nothing, which no test and no compiler could see.

Lag​

The bus is a bounded ring. A subscriber that falls behind receives a lag report rather than the events it missed. The rule is one line and it lives in one place, apollia_core::events::ResilientReceiver: log a WARN naming the subscriber and the number of events dropped, resubscribe to the tail, and carry on. Never panic on lag, and never drop events without saying so.

The server-sent-event routes are the one exception, named as such: they hand a stream to the HTTP layer and a stream owns its receiver, so there is nothing to resubscribe. They keep the half of the rule that is reachable, the WARN.

The catalogue​

Before the table, one caveat it does not carry. HookDecisionRecorded reports the decision of a PreToolUse hook. That decision is applied best effort: a handler that times out, fails to deliver, or answers with something unparseable falls back to allow, and the tool call proceeds.

A second one, on PermissionRequired. Its row reads "A tool invocation requires a human approval", the first line of a doc-comment whose rest the table cannot carry. The one production emitter is the agent mailbox guard: it fires when a gated agent-to-agent send is refused, with tool_name set to mailbox:send. The send does not wait for an answer, it raises on the spot, so the request_id the event carries announces a request that is already settled.

a2a​

VariantPayloadWhat it reports
A2ACompatibilityWarningnamed fieldsSemver compatibility mismatch between the required and advertised version.
A2AGuardTriggerednamed fieldsAn A2A safeguard blocked an inter-agent invocation.
A2AInvocationCompletednamed fieldsAn A2A invocation finished, emitted after the result or a failure is received.
A2AInvocationStartednamed fieldsAn A2A invocation started, emitted by A2AInvoker before task submission.
A2ASkillCompletednamed fieldsAn A2A skill just finished, emitted after the result is received.
A2ASkillInvokednamed fieldsAn A2A skill was just invoked, emitted before the effective submission.

agent-changed​

VariantPayloadWhat it reports
AgentDegradednamed fieldsAn agent moved to a degraded state.
AgentInstallednamed fieldsAn agent was installed permanently.
AgentMessageAckednamed fieldsA delivered message was acknowledged and removed from the store.
AgentMessageDeliverednamed fieldsA pending message was leased to its recipient (delivered on receive).
AgentMessageDroppednamed fieldsA message was dropped without being processed.
AgentMessageSentnamed fieldsA message was sent between two agents via the AgentMailbox.
AgentReadytupleAn agent finished initializing and is operational (state: Active).
AgentRegisteredtupleAn agent was registered in the Registry (state: Initializing).
AgentStoppedtupleAn agent stopped cleanly.
AgentStoppingtupleAn agent is shutting down (state: Stopping, draining tasks).
AgentUninstallednamed fieldsAn installed agent was removed.
MailboxGuardTriggerednamed fieldsA mailbox safeguard blocked a send.

approval-changed​

VariantPayloadWhat it reports
BatchItemAwaitingApprovalnamed fieldsAn item of a batch waits for a decision on an access nobody granted.
PermissionRequirednamed fieldsA tool invocation requires a human approval.
TaskApprovalTimeoutnamed fieldsAn input_required task expired, canceled automatically by the TimeoutWatcher.
TaskInputRequirednamed fieldsA task is suspended awaiting human input.
TaskResumednamed fieldsA task resumed after a HITL suspension.

chat-changed​

VariantPayloadWhat it reports
ChatApprovalRequirednamed fieldsA human approval is required for a tool call in the chat.
ChatApprovalResolvednamed fieldsA tool-call approval was resolved by the user.
ChatApprovalTimeoutnamed fieldsA tool-call approval expired (timeout).
ChatErrornamed fieldsAn error occurred in a chat session.
ChatMessageSentnamed fieldsA user message was sent in a session.
ChatResponseCompletednamed fieldsThe full response was generated.
ChatResponseStartednamed fieldsThe runtime began generating a response.
ChatSessionClosednamed fieldsA chat session was closed.
ChatSessionCreatednamed fieldsA chat session was created.
ChatToolCallCompletednamed fieldsA tool call finished in a chat session.
ChatToolCallStartednamed fieldsA tool call started in a chat session.
ChatUserInputRequirednamed fieldsThe agent requests information from the user via the ask_user tool.
ChatUserInputResolvednamed fieldsThe user answered the ask_user tool's questions.
DecisionPointRecordednamed fieldsA significant decision point was captured with its alternatives.
ThinkingEndednamed fieldsEmitted at the end of the Reasoner phase, reasoning is complete.
ThinkingStartednamed fieldsEmitted at the start of the Reasoner phase, the agent begins "thinking".
ToolCallRetryingnamed fieldsA tool call is being retried after a transient failure.

chat-token​

VariantPayloadWhat it reports
ChatTokennamed fieldsA streaming token was produced by the LLM.

hook-decision​

VariantPayloadWhat it reports
HookDecisionRecordednamed fieldsA PreToolUse hook resolved a decision for a tool call.

llm-changed​

VariantPayloadWhat it reports
CostCeilingReachednamed fieldsThe hybrid routing cost ceiling was reached while HardStop is active.
LlmAgentModelFallbacknamed fieldsThe model assigned to an agent is not available, so the call runs on the default model.
LlmCallCompletednamed fieldsAn LLM call finished, emitted by complete_with_observability().
LlmCallFailednamed fieldsAn LLM call failed, emitted by complete_with_observability() when the
LlmFallbackTriggerednamed fieldsThe LLM router switched to a secondary backend.
LlmModelFailednamed fieldsLoading an LLM backend failed: backend skipped, runtime continues.
LlmModelLoadingnamed fieldsAn LLM backend is loading (before load() or HTTP initialization).
LlmModelReadynamed fieldsAn LLM backend is ready: model loaded in memory or cloud connection verified.
LlmModelReloadednamed fieldsA resident local model was relaunched under its preset's new load settings.
LlmModelUnloadednamed fieldsA resident local model was unloaded and its memory given back.
LlmResponseCapturednamed fieldsA full LLM response captured for deterministic replay.
MetaLlmBudgetExceedednamed fieldsEmitted by MetaLlmOrchestrator when the tokens/session budget is exceeded.
TokenBudgetUpdatednamed fieldsSession budget update, emitted after each LLM call.

memory-changed​

VariantPayloadWhat it reports
SharedNamespaceAddednamed fieldsAn agent gained access to a shared memory namespace.

onboarding-changed​

VariantPayloadWhat it reports
OnboardingCompletednamed fieldsEmitted when the onboarding state machine reaches the Done phase.
OnboardingRequirednoneEmitted on first launch when the UserMemory is empty.
OnboardingStartednamed fieldsEmitted when an onboarding session is triggered (full or partial).

plan-approval​

VariantPayloadWhat it reports
PlanAbandonednamed fieldsA run was abandoned after hitting the replan limit or a fatal replan error.
PlanApprovalRequirednamed fieldsA plan was generated and is awaiting an operator decision before execution.
PlanApprovednamed fieldsA plan gate decision resolved to approval; the ActorLoop is starting.
PlanRejectednamed fieldsAn operator rejected a plan; the engine will replan with the feedback.

plan-mode​

VariantPayloadWhat it reports
ChatPlanApprovednamed fieldsA submitted session plan was approved by the operator.
ChatPlanPhaseChangednamed fieldsThe plan-mode lifecycle phase of a session changed.
ChatPlanRejectednamed fieldsA submitted session plan was rejected by the operator.
PlanSubmittednamed fieldsA session plan was submitted for approval.
PlanUpdatednamed fieldsA session plan was mutated (proposed, edited, reordered, or a step status changed).

session-metrics​

VariantPayloadWhat it reports
SessionMetricsUpdatednamed fieldsAggregated session metrics updated.

stt-changed​

VariantPayloadWhat it reports
SttModelLoadednamed fieldsThe STT model was loaded successfully, engine operational.
SttRecordingStartednoneSTT audio recording started (hotkey activated).
SttRecordingStoppednamed fieldsSTT audio recording stopped (hotkey released or silence detected).
SttTranscribednamed fieldsAn STT transcription completed successfully.
SttTranscriptionFailednamed fieldsAn error occurred during an STT transcription.

system​

VariantPayloadWhat it reports
AllReadynoneAll components are ready, runtime operational.
ConfigInvalidnamed fieldsThe apollia.toml read at startup was refused: the embedded runtime
ConfigReloadednamed fieldsA new apollia.toml, saved through the configuration routes or changed
ContextCompactednamed fieldsEmitted by ContextManager when the conversation history was compacted.
FileModifiedSinceReadnamed fieldsA previously read file was modified between two accesses.
GovernanceFailClosednamed fieldsGovernance started or stopped failing closed.
McpServerHealthChangednamed fieldsAn MCP server's operational health changed.
McpServerReloadednamed fieldsAn MCP server was hot-reloaded successfully.
ShutdownRequestednoneShutdown requested (SIGTERM or CLI command).
ToolCircuitBrokennamed fieldsA tool circuit breaker opened.
ToolCircuitRestorednamed fieldsA tool circuit breaker closed again after recovery.
ToolOutputCapturednamed fieldsA tool output captured for deterministic replay.

task-changed​

VariantPayloadWhat it reports
BashFilePathsExtractednamed fieldsFile paths extracted from a bash command's output.
BatchEndednamed fieldsA batch ended, with its successes and failures.
PlanAlternativesGeneratednamed fieldsTwo alternative plans were generated in parallel by the Reasoner.
PlanCacheHitnamed fieldsA plan was retrieved from the cache instead of being generated by the Reasoner.
PlanCompletednamed fieldsAll steps completed successfully, plan finished.
PlanFailednamed fieldsThe plan failed irrecoverably.
PlanGeneratednamed fieldsAn ExecutionPlan was generated by the Reasoner and persisted to SQLite.
PlanReplanningnamed fieldsA replan was triggered after a retryable step failed.
StepCompletednamed fieldsA step completed successfully, emitted by ActorLoop after each successful call.
StepFailednamed fieldsA step failed, emitted by ActorLoop after each failure.
StepStartednamed fieldsA step started executing, emitted by ActorLoop before each tool or LLM call.
TaskCancelednamed fieldsA task was canceled.
TaskCompletednamed fieldsA task finished (success or failure).
TaskStartednamed fieldsA task started on an agent.
TodoUpdatednamed fieldsThe session todo list changed after a successful todo_write.
VerificationCompletednamed fieldsThe post-run verification pass produced a verdict on an orchestrated run.
WorkflowStepCompletednamed fieldsA step of a workflow run ended without error.
WorkflowStepFailednamed fieldsA step of a workflow run raised, or was stopped with its run.
WorkflowStepStartednamed fieldsA declared step of a workflow run opened.

trace-event​

VariantPayloadWhat it reports
A2AInvokeCompletednamed fieldsAn A2A invocation finished.
A2AInvokeStartednamed fieldsAn A2A (agent-to-agent) invocation starts.
ActionParseErrornamed fieldsThe LLM returned an invalid action JSON that could not be repaired.
AgentLognamed fieldsAn agent emitted a message via ctx.log(level, msg, **fields).
LlmCallStartednamed fieldsAn LLM call is about to be sent (before LlmProxy::complete).
ProfileReadnamed fieldsAn agent read the user profile through ctx.profile.
Retrynamed fieldsThe ReAct loop retries a step (parse error, tool failure, etc.).
Thoughtnamed fieldsThe LLM emitted a ReAct thought (reasoning chain).
ToolCallCompletednamed fieldsThe tool finished its execution.
ToolCallDeniednamed fieldsThe tool was denied (manifest, permission rule, HITL).
ToolCallStartednamed fieldsA tool is about to be invoked (before the dispatcher).

trigger-fired​

VariantPayloadWhat it reports
TriggerDisablednamed fieldsA trigger was disabled via the CLI or the API.
TriggerEnablednamed fieldsA trigger was enabled via the CLI or the API.
TriggerErrornamed fieldsAn error occurred while processing a trigger.
TriggerFirednamed fieldsA trigger fired, task submitted to the runtime.
TriggerQueueFullnamed fieldsA trigger's bounded queue is full, the trigger is dropped.
TriggerSkippednamed fieldsA trigger was skipped (OnBusyPolicy::Skip or agent busy).
TriggersReloadednamed fieldsThe TriggerEngine reloaded its configuration (hot reload or initial start).