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)
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
Standalone mode
Advisory. The agent follows the nine-step methodology
by convention.
Pipeline mode
Gating. Incomplete models (missing GWT scenarios,
undefined automations) block slice decomposition.
Hard constraints:
Do not proceed with gaps in the model:
[RP]
Constraints
"MUST follow nine-steps.md"
Following the nine steps means executing
each step's specific activities and producing its specific outputs. It does
not mean reading the reference and claiming "I followed the spirit." Each
step has defined outputs -- produce them.
"Do not design multiple workflows simultaneously"
This includes
starting "discovery" for Workflow 2 while Workflow 1's steps are incomplete.
Discovery IS design. If you're gathering information about a future
workflow, you're designing it.
Facilitation vs. stenography
Facilitation means asking questions that
help the domain expert discover things they haven't articulated yet. It
does not mean asking leading questions that guide toward your preferred
answer. The test: could the expert's answer genuinely surprise you? If not,
you're leading, not facilitating.
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//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//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
Missing a dependency? Install with:
npx skills add jwilger/agent-skills --skill domain-modeling