Splendor
Reference

Trace Events

Trace event payloads and ordering rules.

Trace Events Reference

Trace events form the append-only audit log for each run. Events are ordered by sequence number within a RunId and must be emitted in strict tick order.

TraceEvent

Fields

  • trace_id (TraceId): deterministic identifier derived from RunId + sequence.
  • run_id (RunId): owning run.
  • sequence (u64): monotonic per-run sequence number.
  • timestamp (OffsetDateTime): capture time at emission.
  • kind (TraceEventKind): event payload.

Trace events are serialized into TraceRecord entries within a TraceStore. The store records additional integrity hashes for audit validation.

Ordering Rules

Events MUST be emitted in the following order for each tick:

  1. LoopTickStarted
  2. PerceptsReceived
  3. PolicyInvoked
  4. CandidatesProposed
  5. ConstraintsEvaluated
  6. ActionVerificationStarted
  7. ActionVerificationCompleted
  8. ActionExecuted or ActionDenied
  9. OutcomeRecorded
  10. StateCommitted
  11. LoopTickCompleted

If post-verification fails after an action executes, the kernel records ActionExecuted followed by ActionDenied with the post-verification result.

TraceEventKind Payloads

  • LoopTickStarted { tick_id }
  • PerceptsReceived { percepts: Vec<Percept> }
  • PolicyInvoked { policy: String }
  • CandidatesProposed { actions: Vec<Action> }
  • ConstraintsEvaluated { constraints: Vec<Constraint>, result: VerificationResult }
  • ActionVerificationStarted { action: Action }
  • ActionVerificationCompleted { action: Action, result: VerificationResult }
  • ActionExecuted { action: Action, outcome: serde_json::Value }
  • ActionDenied { action: Action, result: VerificationResult }
  • OutcomeRecorded { outcome: serde_json::Value, feedback: Option<Feedback>, reward: Option<Reward> }
  • StateCommitted { state_hash: ContentHash, snapshot_id: Option<SnapshotId> }
  • LoopTickCompleted { tick_id, integrity: Option<TraceIntegrity> }

TraceIntegrity

TraceIntegrity captures optional chain metadata emitted at the end of a tick:

  • prev_event_hash (Option<ContentHash>): hash of the previous event in the run.
  • event_hash (ContentHash): hash of the LoopTickCompleted event computed with integrity omitted from the payload.

Example

use splendor_types::{RunId, TraceEvent, TraceEventKind};
use time::OffsetDateTime;

let run_id = RunId::new();
let event = TraceEvent::new(
    run_id,
    0,
    OffsetDateTime::now_utc(),
    TraceEventKind::LoopTickStarted { tick_id: 1 },
);
assert_eq!(event.sequence, 0);

On this page