krply/docs/event-schema/event-schema.md

3.7 KiB

Event schema

Every journal record is an immutable entry. The wire format is api/event/v1. This document describes the fields, the record types, and how keys and hashes are derived.

Record fields

Field Purpose
cluster_id Separates resource version and UID domains; one per physical cluster
stream_id Identifies group, version, resource, namespace, and selector
event_id Deterministic deduplication key
ingest_sequence Local storage order (ascending); returned in this order
observed_at Collector observation time
watch_type Original event type (ADDED, MODIFIED, DELETED, BOOKMARK, ERROR)
synthetic True for baseline events
resource Group, version, kind, namespace, name, UID, resource version
object_hash Fast equality and deduplication
object Raw or faithfully preserved payload (JSON)
provenance Optional audit correlation

The raw watch payload is kept separate from normalized fields. This preserves unknown CRD fields. Never re-serialize the object into a lossy normalized shape.

Record types

The journal stores event records plus these special records:

Type Meaning
event A watch event (ADDED, MODIFIED, DELETED)
baseline A list result (initial or post-relist)
gap Continuity was lost (for example, a 410 Gone response)
coverage_change A resource became unavailable or was newly discovered
audit_correlation Optional request provenance matched from audit logs
snapshot A materialized set of stream boundaries
checkpoint Progress marker advanced by a bookmark

The corresponding record type constants in internal/event are: TypeEvent, TypeBaseline, TypeGap, TypeCoverageChange, TypeAuditCorrelation, TypeSnapshot, and TypeCheckpoint. The watch types are: WatchAdded, WatchModified, WatchDeleted, WatchBookmark, and WatchError.

event_id derivation

The field event_id is the deterministic deduplication key. The derivation is:

EventID(stream, resource, watchType, observedAt) -> string

The inputs are the stream identity, the resource reference, the watch type, and the observed time. The same key is recomputed for a redelivered event, for example after a reconnect or a crash before the checkpoint. Re-application is therefore idempotent. This makes at-least-once ingestion safe. See ../consistency/consistency.md for the ingestion guarantee.

object_hash

The function ObjectHash(objectJSON) returns a fast equality and deduplication hash over the raw object payload. It lets consumers detect that a MODIFIED event did not change the object. It lets the store collapse no-op writes. It is not a cryptographic commitment. Treat it as a performance and equality helper only.

Provenance

The field provenance is optional. When audit logs are available, an audit event is correlated to a stored event by cluster, namespace, name, UID, and resource version. It is recorded as a TypeAuditCorrelation record that references the field event_id. Audit identity is available only through this optional correlation. A watch event itself never contains the actor who made the change.

Versioning

The package api/event/v1 is the public wire format. Internal packages stay private until the schema and replay contract stabilize. The manifest used by the object-storage segment layout records a schema version alongside the redaction policy version. Do not change api/event/v1 without a coordinated schema bump. Consumers of the journal and replay contract depend on it.

See also

  • Ingestion and deduplication: ../consistency/consistency.md.
  • Storage layout and segment manifests: ../architecture/architecture.md.
  • Sanitization of the object payload before replay: ../replay-safety/replay-safety.md.