Ennio emits structured events for every significant state change. Events flow through multiple channels for real-time and historical access.
Every event contains:
Field Type Description
idEventIdUnique identifier
event_typeEventTypeWhat happened
priorityEventPrioritySeverity level
session_idSessionIdAffected session
project_idProjectIdOwning project
timestampDateTime<Utc>When it happened
messageStringHuman-readable description
dataJSONStructured payload
Type Description
SessionSpawnedNew session created and agent launched
SessionWorkingAgent began active work
SessionExitedAgent process exited unexpectedly
SessionKilledSession manually terminated
SessionRestoredExited session restarted
SessionCleanedSession workspace cleaned up
Type Description
StatusChangedSession transitioned to a new status
ActivityChangedSession activity state changed
Type Description
PrCreatedPull request created
PrUpdatedPull request updated (new commits)
PrMergedPull request merged
PrClosedPull request closed without merging
Type Description
CiPassingCI checks are green
CiFailingCI checks failed
CiFixSentAgent pushed a CI fix
CiFixFailedCI fix attempt also failed
Type Description
ReviewPendingAwaiting code review
ReviewApprovedPR approved
ReviewChangesRequestedReviewer requested changes
ReviewCommentsSentReview comments forwarded to agent
Type Description
MergeReadyPR ready to merge (approved + CI green)
MergeConflictsMerge conflicts detected
MergeCompletedPR merged successfully
Type Description
ReactionTriggeredA reaction rule fired
ReactionEscalatedReaction escalated after timeout
AllCompleteAll project sessions completed
Type Description
NodeConnectedConnected to remote node
NodeDisconnectedDisconnected from remote node
NodeLaunchedRemote node daemon started
NodeHealthCheckNode health check performed
Priority Use Case
InfoStatus updates, completions
ActionSomething needs attention
UrgentImmediate human attention needed
CriticalSystem-level failures
Priorities are ordered: Info < Action < Urgent < Critical.
Tokio broadcast channel with capacity 1024. Subscribers receive events in real-time. Used by the lifecycle manager, web API (SSE), and internal consumers.
#![allow(unused)]
fn main() {
let rx = event_bus.subscribe(EventType::CiFailing);
while let Ok(event) = rx.recv().await {
// handle event
}
}
Events are published to category-based NATS topics. Each event type maps to a topic category:
Category Topic Format Event Types
Sessions ennio.sessions.{project_id}.{action}Spawned, Working, Exited, Killed, Restored, Cleaned, StatusChanged, ActivityChanged
Pull Requests ennio.pr.{project_id}.{action}PrCreated, PrUpdated, PrMerged, PrClosed
CI ennio.ci.{project_id}.{action}CiPassing, CiFailing, CiFixSent, CiFixFailed
Reviews ennio.review.{project_id}.{action}ReviewPending, ReviewApproved, ReviewChangesRequested, ReviewCommentsSent
Merge ennio.merge.{project_id}.{action}MergeReady, MergeConflicts, MergeCompleted
Reactions ennio.reactions.{project_id}.{action}ReactionTriggered, ReactionEscalated
Lifecycle ennio.lifecycle.{action}AllComplete
Nodes ennio.node.{host}.{action}NodeConnected, NodeDisconnected, NodeLaunched, NodeHealthCheck
Commands ennio.commands.{command}Shutdown and other control commands
Metrics ennio.metrics.{action}Metric collection events
Dashboard ennio.dashboard.{action}Dashboard update events
External systems can subscribe to patterns:
ennio.sessions.my-project.* — all session events for a project
ennio.ci.my-project.* — all CI events for a project
ennio.node.build-server.* — all events from a remote node
ennio.lifecycle.* — all lifecycle events
Topic segments are validated: alphanumeric, underscore, and hyphen characters only. No spaces or dots within segments.
All events are persisted to the events table for history, debugging, and replay. Query via the REST API or directly from the database.