Welcome. This first module establishes the central idea behind Event Sourcing: a system can preserve what happened as an ordered history of facts, then calculate the state it needs from that history.
For your client-information workflow, this matters because an AI-generated update, a gate’s decision, and a resulting canonical-data change are not the same fact. Event Sourcing gives us a way to retain each fact without letting an unapproved proposal silently become canonical data. In this lesson, you will learn the basic mechanism: append events, then use a projector to derive state.
From a scoreboard to a history
A conventional database often feels like a scoreboard: it tells you the current score, but not how the game unfolded. If a client record now says its legal name is “Northwind Health Ltd.,” the record alone may not tell you:
- what the previous value was,
- who or what proposed the change,
- whether an automated gate approved it,
- when it became authoritative.
Event Sourcing begins from the opposite direction. Rather than treating today’s record as the fundamental truth, it treats the sequence of meaningful facts that produced it as the truth.
Event Sourcing Explained Using Football
Watch “Event Sourcing Explained Using Football” from Metaphorically Speaking. The scoreboard-and-logbook analogy provides a compact mental model for the difference between stored current state and an event history from which state can be calculated.
Watch the scoreboard analogy. Focus on why a final score cannot reveal the sequence of goals, while a logbook can derive the score at any moment. Then watch projections and rebuilding. Notice that the scoreboard is useful and fast, but it is not the authority: it can be rebuilt from the persisted history.
The analogy has three direct counterparts in a software system:
| Football example | Event-sourced system |
|---|---|
| Logbook of goals, cards, and substitutions | Event store containing persisted domain events |
| One game’s timeline | Event stream for one business entity or boundary |
| Scoreboard | Projection or read model derived from events |
An event is a statement that a meaningful thing already happened. It is normally named in the past tense:
ClientRegisteredClientInformationProposedProposalAcceptedClientDataChangeApproved
These are facts, not requests. “Change the client’s name” is a request; “Client name changed” asserts that a change has occurred. We will distinguish requests, proposals, decisions, and events carefully in the next module. For now, hold onto the basic rule:
An event describes a completed domain fact, with enough context to understand and apply that fact later.
For example, a simplified approved change event might record the client, the approved field value, the decision that authorized it, and when it occurred. It should not merely say “the client is now updated,” because that loses the meaningful business story.
Append-only event streams
In Event Sourcing, events are placed into an append-only store. “Append-only” means that new facts are added to the end of the history; prior facts are not edited in place to make the history look different.
Event Sourcing pattern - Azure Architecture Center
Read Microsoft Azure Architecture Center’s “Event Sourcing pattern.” It establishes the core distinction between recording logical changes as events and reconstructing an entity’s state by replaying its ordered event history.
In the “Solution” section, read the core definition. Focus on the idea that each stored event represents one logical change, rather than a replacement of an entire record. In the following explanation of event streams, read the rehydration explanation. Then continue from “Materialized views are read-only projections of the event store” through the customer-order example: the read model passage. Distinguish on-demand replay for reconstructing an entity from a persisted view optimized for many queries.
An event stream is an ordered sequence of related events. A stream might represent the history of one client, one proposal, or another carefully chosen business boundary. We will decide those boundaries later; the key point today is that order is essential.
Consider a simplified stream about a client’s canonical contact information:
| Position | Event | Relevant fact |
|---|---|---|
| 1 | ClientRegistered | Client C-204 was created with email contact@northwind.example |
| 2 | ClientEmailChangeApproved | The approved email became data@northwind.example |
| 3 | ClientPhoneChangeApproved | The approved phone became +1 555 0100 |
The current canonical contact state is not stored inside the third event. It is calculated by starting from an initial state and applying the events in recorded order.
Formally, if is the initial state and is the event at position , then:
For the example:
- Begin with no client contact data.
- Apply
ClientRegistered; the email becomescontact@northwind.example. - Apply
ClientEmailChangeApproved; replace the email withdata@northwind.example. - Apply
ClientPhoneChangeApproved; add the approved phone number.
The result is the current contact record. This act of reading events from the beginning and applying them in order is often called replay or rehydration.
Append-only does not mean “nothing can ever change”
Real information changes, and systems make mistakes. Append-only means that the history itself is preserved. If an approved phone number later proves wrong, the system records a new fact that corrects it. It does not rewrite the old event as though it never happened.
That distinction is important for your use case. A history may truthfully show that:
- an agent proposed a value,
- the value passed a gate,
- it was promoted,
- a later review found it incorrect,
- a corrected value was approved.
The current canonical value may be only the fifth event’s result, but the prior decisions remain explainable.
What a projector does
A projector is a component that consumes events and builds a useful representation of state. Its job is not to invent business history. Its job is to interpret already-stored history into a shape that a particular consumer needs.
A projector follows a simple conceptual routine:
- Start from an empty initial state, or from a previously stored projection state.
- Read events in their recorded order.
- Ignore events irrelevant to its purpose.
- Apply a transformation for each relevant event.
- Store the resulting state in a read model, dashboard, search index, or another query-oriented store.
For the canonical contact view above, a projector might have rules like:
| Event type | Projection action |
|---|---|
ClientRegistered | Create the client’s initial display record |
ClientEmailChangeApproved | Set the displayed canonical email |
ClientPhoneChangeApproved | Set the displayed canonical phone |
ClientInformationProposed | Ignore it for the canonical-contact view |
That final row is crucial. A proposal is evidence that someone or something suggested a change. It is not, by itself, evidence that the canonical client record should change.
The same underlying events can produce several projections. For example:
| Projection | Purpose | Events it cares about |
|---|---|---|
| Canonical client profile | Show approved client information | Registration and approved data-change events |
| Proposal review queue | Show work awaiting acceptance | Proposal and review-decision events |
| Governance timeline | Explain what happened and why | Most events, including provenance and decisions |
These views may contain different fields, use different storage technologies, and answer different questions. What binds them together is that they are all derived from the same durable facts.

The diagram includes Command Query Responsibility Segregation, often abbreviated CQRS. You do not need to master CQRS yet. For this lesson, read it simply as a separation between:
- the part of a system that evaluates a requested change and records facts, and
- the part that serves data efficiently from projections.
The important relationship is that the event store supplies the projector, and the projector supplies the read model. The read model is valuable because it avoids replaying a lengthy event history every time an application needs to display one client record or a list of pending proposals.
Two forms of deriving state
“Derive state from events” can mean two closely related activities. They use the same underlying logic but serve different purposes.
| Activity | What happens | Typical purpose |
|---|---|---|
| Rehydration | Load one entity’s stream and replay it into memory | Understand current state before evaluating a new requested action |
| Projection | Continuously or periodically process events into stored views | Serve fast queries, reports, dashboards, and downstream consumers |
Suppose a system receives a request to change a client’s canonical email. Before accepting that request, it may need to know the client’s present canonical status and current email. It can rehydrate that state from the client’s event history.
Separately, a web interface may need to show thousands of clients quickly. Replaying every client’s full history for every page load would be wasteful. A projector maintains a query-friendly client-profile view, so the interface can retrieve the already-derived result.
Both should agree because both are based on the same ordered history and the same interpretation rules. If a projection is deleted, corrupted, or replaced with a better design, it can be rebuilt by replaying the event store. That is why a projection is a derived artifact, not the source of truth.
A good projector is therefore as deterministic as practical: given the same events in the same order, it should compute the same result. It should rely on the recorded event data, rather than quietly consulting changing external information such as “today’s current rules” or a live third-party profile.
Applying the idea to proposed client-data updates
Now connect the foundation to your target architecture: AI agents propose changes to client information, but acceptance gates control whether those changes become canonical.
Imagine this high-level history:
| Position | Event | Effect on proposal view | Effect on canonical client view |
|---|---|---|---|
| 1 | ClientRegistered | No proposal yet | Creates the client |
| 2 | ClientInformationProposed | Shows a proposed address change | No canonical change |
| 3 | ProposalValidationCompleted | Shows validation outcome | No canonical change |
| 4 | ClientAddressChangeApproved | Shows approved proposal | Updates canonical address |
A proposal projector can interpret positions 2 and 3 to show reviewers what was suggested, by which agent, with what supporting evidence, and what the gates found.
A canonical-client projector has a narrower authority rule: it updates the canonical address only when it receives the accepted change event at position 4. It does not treat “a proposal exists” as “the canonical address changed.”
This is the architectural principle to retain:
Facts about proposed changes and facts about canonical changes may share a history, but a canonical-state projection must apply only the event types that carry the required authority.
The exact event names, identifiers, stream boundaries, and gate events will be designed in the next modules. At this stage, the central insight is simply that a projector makes authority visible in its transformation rules. It is not enough to store events; you must decide which events are allowed to affect which derived states.
A few boundaries to keep clear
Several ideas are easy to blur together at first.
The event store is not merely a transient notification channel. A message can be delivered and forgotten. An event store must durably preserve the ordered history needed to reconstruct state later.
A projection is not an independent source of truth. It can be optimized, indexed, reformatted, deleted, and rebuilt. If the projection disagrees with the event history, the event history is authoritative in a true event-sourced design.
An event is not a command. A command asks for an action; an event records the fact that resulted after the action was evaluated. This distinction becomes particularly important when an AI agent proposes an update that might be rejected.
Appending is not overwriting. New facts modify the calculated current state without erasing earlier facts. Correction normally means recording a later correction, not mutating old history.
For large histories, systems may use a snapshot: a stored state at a known event position. Rebuilding can then start from that snapshot and apply only later events. This is a performance optimization; the event stream remains the fundamental record.
Key takeaways
Event Sourcing stores an ordered, append-only history of domain facts. A current state is then calculated by replaying those facts from an initial state.
A projector is the component that performs this calculation for a specific purpose and often saves the result as a query-friendly read model. Different projectors can derive different useful views from the same event history.
For the AI-proposal workflow, the central design constraint is that a proposal event must not alter canonical client state merely because it exists. The canonical projection should react only to events that represent properly authorized, approved changes.
Next, you will compare Event Sourcing with CRUD persistence, audit logs, and record versioning. That comparison will make the meaning of “source of truth” and the update semantics of each approach much sharper.
Can't find a good explanation? Sign up and we'll make it for you
Sign up