# core/events — AGENTS.md ## Purpose Foundational event-sourcing infrastructure: all `EventPayload` definitions for every domain, the serialization registry, the `EventStore` interface, the `EventReplayer` contract, and shared identity/vocabulary types used across the entire `core/` layer. ## Ownership CORREX kernel team. This is the most cross-cutting module in the codebase — changes here can break every other module. Coordinate before adding or renaming event types. ## Local Contracts - `EventPayload` — sealed interface that every domain event implements. - `StoredEvent` / `EventEnvelope` / `EventMetadata` — envelope types wrapping payloads for storage and replay. - `EventStore` — interface for appending and querying events. Implementations in `infrastructure/`. - `EventReplayer` / `DefaultEventReplayer` — replays a filtered event stream through a `Projection` to rebuild state. - `Projection` — interface: `initial(): S` + `apply(state, event): S`. - `StateBuilder` / `DefaultStateBuilder` — convenience builder over `EventReplayer`. - `Serialization.kt` — the `eventModule` polymorphic block. **Every new `EventPayload` subclass must be registered here.** Missing registration = silent deserialization failure. - `JsonEventSerializer` / `EventSerializer` — serialize/deserialize `StoredEvent` to JSON. - `EventDispatcher` — broadcasts events to in-process listeners. - Domain event files: `ApprovalEvents`, `ArtifactEvents`, `ContextEvents`, `InferenceEvents`, `OrchestrationEvents`, `RouterEvents`, `SessionEvents`, `TaskEvents`, `ToolEvents`, `IntentEvents`, `RiskAssessedEvent`, `JournalCompactedEvent`, and many more — all payload definitions live here. - `FailureAttribution` / `FailureAttributor` — the terminal-failure taxonomy (`AGENT`, `HARNESS`, `WORKFLOW`, `ENVIRONMENT`, `PROVIDER`, `OPERATOR`, `UNKNOWN`) carried as `WorkflowFailedEvent.attribution`, plus the deterministic reason→layer mapping used both at emission and when classifying historical events. One primary attribution per terminal event; a multi-cause chain is the session's `FailureTicketOpenedEvent`s, not a second structure. - `LspDiagnosticsCompletedEvent` records pulled language-server diagnostics or a graceful skip reason; replay consumes this observation and never contacts the server. - `ToolCapability.CONTENT_FROM_SOURCE` — content-provenance claim: the bytes a call writes derive entirely from an existing source object it names, never from model output. Recorded on the invocation event like every other capability, so replay classifies the call by what it actually claimed. Only declare it on a tool whose output is a faithful reproduction of its source. - Shared vocabulary: `IdentityTypes` (SessionId, TaskId, etc.), `Tier`, `TokenUsage`, `ToolReceipt`, `ToolRequest`, `RiskLevel`, `RetryPolicy`, `GrantScope`, `GrantLedger`. ## Work Guidance - **SILENT FAILURE TRAP**: After adding any `EventPayload` subclass, immediately add it to `Serialization.kt` `eventModule` block. Run `./gradlew check` to verify. Tests may pass without it but runtime replay will fail silently. - `AnyMapSerializer` — custom serializer for `Map`; use it for dynamic payloads, don't roll another. - Event classes are `@Serializable data class` with no mutable state. No methods beyond data accessors. - `RunBranchPushedEvent` records an optional server Git transport push only after it succeeds; its branch/base/head SHAs are observations, not values replay recalculates. - `RepoMapEntry.descriptor` is a bounded source-purpose observation recorded with the repo map and used when constructing semantic L3 embeddings. - Do not add domain logic to events. They are records, not actors. `FailureAttributor` is the one exception by design: a pure reason→layer function that must be identical for live emission and for historical classification, so it lives beside the enum it returns. - `WorkflowFailedEvent.attribution` defaults to `UNKNOWN` so pre-field events replay unchanged. Classify those at READ time (see `FailureAttributionInspectionService`); never rewrite history to backfill them. - `EgressAllowlistProjection` — special projection kept in this module because it is used by both `core:toolintent` and `core:events` consumers; it is a shared cross-cutting projection. ## Verification ```bash ./gradlew :core:events:test --rerun-tasks ``` Tests in `testing/contracts/` (EventsTest, EventStoreContractTest) and `testing/replay/` (serialization round-trips, replay integration). ## Child DOX Index No child AGENTS.md (leaf module).