Event modeling facilitation for discovering and designing event-sourced systems. Four phases: domain discovery, workflow design (9-step process), GWT scenario generation, and model validation. Activate when starting a new project, designing features, modeling domains, writing Given/When/Then scenarios, or discussing event sourcing and domain-driven design.
Value: Communication -- event modeling is a structured conversation that
surfaces hidden domain knowledge and creates shared understanding between
humans and agents before any code is written.
Purpose
Teaches the agent to facilitate event modeling sessions following Martin
Dilger's "Understanding Eventsourcing" methodology. Produces a complete
event model (actors, events, commands, read models, automations, slices)
that drives all downstream implementation. The model lives in
docs/event_model/
.
Practices
Two-Phase Process: Discovery Then Design
Never jump into detailed workflow design without broad domain understanding
first. Phase 1 maps the territory; Phase 2 explores each region.
Phase 1 -- Domain Discovery. Identify what the business does, who the
actors are, what major processes exist, what external systems integrate, and
which workflows to model. Ask these questions of the user; do not assume
answers. Output:
docs/event_model/domain/overview.md
.
Phase 2 -- Workflow Design. For each workflow, follow the 9-step
process. You MUST follow
references/nine-steps.md
for the full methodology. Design
one workflow at a time. Complete all 9 steps before starting the next
workflow. Output:
docs/event_model/workflows/<name>/overview.md
plus
individual slice files in
slices/
.
The Prime Directive: Not Losing Information
Store what happened (events), not just current state. Events are immutable
past-tense facts in business language. Every read model field must trace
back to an event. If a field has no source event, something is missing from
the model.
Event Design Rules
Name events in past tense using business language:
OrderPlaced
, not
PlaceOrder
or
CreateOrderDTO
Events are immutable facts -- never modify or delete
Include relevant data: what happened, when, who/what caused it
Find the right granularity -- not
DataUpdated
(too broad) and not
FieldXChanged
(too narrow)
Commands depend on user inputs and the event stream, not read models.
Read models serve views and automations only.
Events record domain facts (true on any machine). Runtime context
(file paths, hostnames, PIDs, working directories) does not belong
in event data.
The Four Patterns
Every event-sourced system uses these patterns. Each pattern maps to one
vertical slice.
State Change: Command -> Event. The only way to modify state. A
command may produce multiple events as part of a single operation.
State View: Events -> Read Model. How the system answers queries.
When the domain supports concurrent instances, use collection types
in read model fields, not singular values.
Commands derive their inputs from user-provided data and the event
stream — never from read models. No
ReadModel → Command
edges
should appear in diagrams. If a command needs to check whether
something already happened (e.g., idempotency), it checks the event
stream, not a read model.
Read models represent meaningful domain projections. Infrastructure
preconditions ("does directory exist?", "is service running?") that
are implicit in the command's execution context do not need their own
read model.
Automation: Event -> Read Model (todo list) -> Process -> Command
-> Event. Background work triggered by events. Requires all four
components: triggering event, read model consulted, conditional
process logic, and resulting command. If there is no read model and
no conditional logic, it is NOT an automation — it is a command
producing multiple events. Must have clear termination conditions.
Translation: External Data -> Internal Event. Anti-corruption layer
for workflow-specific external integrations. Generic infrastructure
shared by all workflows (event persistence, message transport) is NOT
a Translation — it is cross-cutting infrastructure that belongs
outside the event model.
Required Layers Per Slice Pattern
Each slice pattern implies a minimum set of architectural layers. A slice is not complete until all required layers are implemented and wired together.
State View: infrastructure (read events/data from store) + domain (projection/query logic) + presentation (render or return result to caller) + application wiring (connect layers end-to-end)
State Change: presentation (accept user input or external request) + domain (command validation and business rules) + infrastructure (persist resulting events/data) + application wiring (connect layers end-to-end)
Translation: infrastructure (receive from external system) + domain (mapping/transformation logic) + infrastructure (deliver to target system) + application wiring (connect inbound adapter to mapper to outbound adapter)
When decomposing a slice, verify that your acceptance criteria and task breakdown cover every required layer. A slice that only implements domain logic without presentation or infrastructure is incomplete — it is a component, not a vertical slice.
GWT Scenarios
After workflow design, generate Given/When/Then scenarios for each slice.
These become acceptance criteria for implementation.
Command scenarios: Given = prior events establishing state. When = the
command with concrete data. Then = events produced OR an error (never both).
View scenarios: Given = current projection state. When = one new event.
Then = resulting projection state. Views cannot reject events.
Critical distinction: GWT scenarios test business rules (state-dependent
policies), not data validation (format/structure checks that belong in the
type system). If the type system can make the invalid state unrepresentable,
it is not a GWT scenario.
You MUST use
references/gwt-template.md
for the full scenario format and examples.
Application-Boundary Acceptance Scenarios
Every vertical slice MUST include at least one GWT scenario defined at the application boundary:
Given: The system is in a known state (prior events, seed data, configuration)
When: A user (or external caller) interacts through the application's external interface — the specific interface depends on the project (HTTP endpoint, CLI command, message queue consumer, UI action, etc.)
Then: The result is observable at that same boundary — a response, output, rendered state change, emitted event, etc.
A GWT scenario that can be satisfied entirely by calling an internal function in a unit test describes a unit-level specification, not a slice acceptance criterion. Slice acceptance criteria must exercise the path from external input to observable output.
Acceptance Test Strategy
Where the application boundary is programmatically testable — HTTP endpoints, CLI output parsing, headless browser automation, message queue assertions, API contract tests, etc. — write automated acceptance tests that exercise the full GWT scenario from external input to observable output. These tests provide fast feedback and serve as living documentation of slice behavior.
Where automated boundary testing is not feasible (complex GUI interactions, hardware-dependent behavior, visual/aesthetic verification), document what the human should manually verify: the specific steps to perform and the expected observable result. This manual verification checklist becomes part of the slice's definition of done.
Slice Independence
Slices sharing an event schema are independent. The event schema is the
shared contract. Command slices test by asserting on produced events; view
slices test with synthetic event fixtures. Neither needs the other to be
implemented first. No artificial dependency chains between slices.
Model Validation
After GWT scenarios are written, validate the model for completeness:
Every read model field traces to an event
Every event has a triggering command, automation, or translation
Every command has documented rejection conditions (business rules)
Every automation has a termination condition
GWT Given/When/Then clauses do not reference undefined elements
When gaps are found, ask the user to clarify, create the missing element,
and re-validate. Do not proceed with gaps remaining.
Facilitation Mindset
You are a facilitator, not a stenographer. Ask probing questions. Challenge
assumptions. Keep asking "And then what happens?" after every event, every
command, every answer. Use business language, not technical jargon. Do not
discuss databases, APIs, frameworks, or implementation during event modeling.
The only exception: note mandatory third-party integrations by name and
purpose.
Do:
Follow all steps in order -- the process reveals understanding
Ask "And then what happens?" relentlessly
Use concrete, realistic data in all examples and scenarios
Design one workflow at a time
Ensure information completeness before proceeding
Ask "Can there be more than one of these at the same time?" for read model fields
Verify automations have all four components before labeling them as such
Do not:
Skip steps because you think you know enough
Make architecture or implementation decisions during modeling
Write GWT scenarios for data validation (use the type system)
Design multiple workflows simultaneously
Proceed with gaps in the model
Enforcement Note
This skill provides advisory guidance. It instructs the agent on the event
modeling methodology but cannot mechanically prevent skipping steps or
producing incomplete models. When used with the
tdd
skill, GWT scenarios
from event modeling become acceptance tests that enforce the model. Without
it, the agent follows these practices by convention. If you observe steps
being skipped, point it out.
Verification
After completing event modeling work, verify:
Domain overview exists at
docs/event_model/domain/overview.md
with
actors, workflows, external integrations, and recommended starting
workflow
Each designed workflow has
docs/event_model/workflows/<name>/overview.md
with all 9 steps completed
All events are past tense, business language, immutable facts
Every read model field traces to a source event
Every event has a trigger (command, automation, or translation)
Automations have all four components (event, read model, conditional logic, command)
Read model fields use collection types when domain supports concurrent instances
No cross-cutting infrastructure modeled as Translation slices
GWT scenarios exist for each slice (inline in
docs/event_model/workflows/<name>/slices/*.md
) with concrete data
GWT error scenarios test business rules only, not data validation
Slices sharing an event schema are independently testable (no
artificial dependency chains)
No gaps remain in the model after validation
If any criterion is not met, revisit the relevant practice before proceeding.
Dependencies
This skill works standalone. For enhanced workflows, it integrates with:
domain-modeling: Events reveal domain types (Email, Money, OrderStatus)
that the domain modeling skill refines
tdd: Each vertical slice maps to one TDD cycle
architecture-decisions: Event model informs architecture; ADRs should
not be written during event modeling itself
task-management: Workflows map to epics, slices map to tasks