Event Sourcing

Event Sourcing

In One Sentence

Instead of directly storing the “current state”, repeatedly “append” one immutable event after another; any time you need state, recompute it from those events.

Compared with the Traditional Approach

Traditional (State Snapshot)Event Sourcing
What is storedThe “current shape” (e.g. turn=3), overwritten on every change“What happened” (one event appended at a time), never deleted
Crash / corrupted writeThe old state is unrecoverable after an overwriteThe event log survives and can be replayed back to any point in time
Audit / replayOnly the current value exists; history relies on external logsThe full history is the data itself, naturally replayable
Derived stateKept as a single snapshotFold one out on demand at any time

In Dsh-Go

1sl := session.NewSessionLog(brand.NewSessionID("demo"))
2sl.Append(session.UserMessageData{Content: "Hello"})
3sl.Append(session.AssistantMessageData{Content: "Hi, I'm Dsh-Go."})
4
5evs := sl.Events() // read out this "immutable fact log"

Key points:

  • append-only: only append; never modify or delete history
  • temporal invariants: paired turn open/close, tool callresult matching — violations are rejected immediately
  • single write entry point: Append(), with consistency guaranteed by the engine

Benefits and Costs

Benefits: auditable, replayable, forkable/compactable, crash-recoverable
⚠️
Costs: the log keeps growing, so you need compaction and projection to read state

Source Reference

  • pkg/session/session.go — the event log and 45+ event vocabulary
  • Runnable example: examples/tutorial step 1

Next Steps

Learn fold Projection: how state is “derived” from events