event-modeling
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseEvent Modeling
Event Modeling
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.
价值: 沟通——Event Modeling是一种结构化的对话,在编写任何代码之前,它就能挖掘出隐藏的领域知识,让人类和Agent达成共识。
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/指导Agent遵循Martin Dilger的《Understanding Eventsourcing》方法论来主持Event Modeling会议。产出完整的事件模型(参与者、事件、命令、查询模型、自动化流程、垂直切片),为所有下游实现提供指导。模型存储在目录下。
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.mdPhase 2 -- Workflow Design. For each workflow, follow the 9-step
process. You MUST follow for the full methodology. Design
one workflow at a time. Complete all 9 steps before starting the next
workflow. Output: plus
individual slice files in .
references/nine-steps.mddocs/event_model/workflows/<name>/overview.mdslices/绝不要在没有全面了解领域的情况下就跳入详细的工作流设计。第一阶段是绘制领域版图;第二阶段是深入探索每个区域。
第一阶段——领域发现:明确业务内容、参与者、主要流程、集成的外部系统,以及需要建模的工作流。向用户询问这些问题,不要自行假设答案。输出文件:。
docs/event_model/domain/overview.md第二阶段——工作流设计:针对每个工作流,遵循9步流程。你必须参考中的完整方法论。一次只设计一个工作流,完成全部9个步骤后再开始下一个工作流。输出文件:,以及目录下的各个切片文件。
references/nine-steps.mddocs/event_model/workflows/<name>/overview.mdslices/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),而不仅仅是当前状态。Event是不可变的、采用过去式的业务语言事实。每个查询模型的字段都必须能追溯到某个Event。如果某个字段没有对应的源Event,说明模型存在缺失。
Event Design Rules
Event设计规则
- Name events in past tense using business language: , not
OrderPlacedorPlaceOrderCreateOrderDTO - Events are immutable facts -- never modify or delete
- Include relevant data: what happened, when, who/what caused it
- Find the right granularity -- not (too broad) and not
DataUpdated(too narrow)FieldXChanged - 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.
- 使用业务语言以过去式命名Event:例如,而非
OrderPlaced或PlaceOrderCreateOrderDTO - Event是不可变的事实——绝不能修改或删除
- 包含相关数据:发生了什么、何时发生、由谁/什么触发
- 选择合适的粒度——既不能像那样宽泛,也不能像
DataUpdated那样过于细碎FieldXChanged - Command依赖于用户输入和Event流,而非查询模型。查询模型仅用于视图展示和自动化流程。
- Event记录的是领域事实(在任何机器上都成立)。运行时上下文(文件路径、主机名、PID、工作目录)不属于Event数据的范畴。
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 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.
ReadModel → Command - 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.
每个事件溯源系统都会用到以下四种模式,每种模式对应一个垂直切片。
- 状态变更:Command → Event。这是修改状态的唯一方式。一个Command在单次操作中可能产生多个Event。
- 状态视图:Events → Read Model。系统通过这种模式响应用户查询。当领域支持并发实例时,查询模型的字段应使用集合类型,而非单一值。
Command的输入来自用户提供的数据和Event流——绝不能来自查询模型。在流程图中不应出现的关联。如果Command需要检查某件事是否已经发生(比如幂等性),它应该检查Event流,而非查询模型。 查询模型代表有意义的领域投影。命令执行上下文中隐含的基础设施前置条件(如“目录是否存在?”“服务是否运行?”)不需要单独的查询模型。
ReadModel → Command - 自动化流程:Event → Read Model(待办列表)→ 流程 → Command → Event。由Event触发的后台任务。必须包含四个组件:触发Event、参考的查询模型、条件流程逻辑、生成的Command。如果没有查询模型和条件逻辑,那就不是自动化流程——而是一个产生多个Event的Command。必须有明确的终止条件。
- 转换适配:外部数据 → 内部Event。针对特定工作流外部集成的防腐层。所有工作流共享的通用基础设施(Event持久化、消息传输)不属于转换适配——它们是跨领域基础设施,应放在事件模型之外。
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)
- Automation: infrastructure (detect triggering condition — timer, external event, threshold) + domain (policy/decision logic) + infrastructure (execute resulting action — send message, write data, call service) + application wiring (connect trigger to policy to action)
- 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.
每种切片模式都对应一组最低要求的架构层。只有实现并连接所有必需的层,切片才算完整。
- 状态视图:基础设施层(从存储中读取Event/数据)+ 领域层(投影/查询逻辑)+ 表示层(渲染结果或返回给调用方)+ 应用层(连接各层)
- 状态变更:表示层(接收用户输入或外部请求)+ 领域层(Command验证和业务规则)+ 基础设施层(持久化生成的Event/数据)+ 应用层(连接各层)
- 自动化流程:基础设施层(检测触发条件——定时器、外部Event、阈值)+ 领域层(策略/决策逻辑)+ 基础设施层(执行结果动作——发送消息、写入数据、调用服务)+ 应用层(连接触发器、策略和动作)
- 转换适配:基础设施层(接收外部系统数据)+ 领域层(映射/转换逻辑)+ 基础设施层(传递到目标系统)+ 应用层(连接入站适配器、映射器和出站适配器)
在拆分切片时,要确保你的验收标准和任务分解覆盖了所有必需的层。只实现了领域逻辑而没有表示层或基础设施层的切片是不完整的——它只是一个组件,而非垂直切片。
GWT Scenarios
GWT场景
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 for the full scenario format and examples.
references/gwt-template.md工作流设计完成后,为每个切片生成Given/When/Then(GWT)场景。这些场景将成为实现阶段的验收标准。
Command场景:Given = 用于建立状态的历史Event。When = 带有具体数据的Command。Then = 生成的Event 或 错误(二者只能出现一个)。
视图场景:Given = 当前投影状态。When = 一个新的Event。Then = 生成的投影状态。视图不能拒绝Event。
关键区别:GWT场景测试的是业务规则(依赖状态的策略),而非数据验证(格式/结构检查属于类型系统的范畴)。如果类型系统可以避免无效状态的出现,那就不需要编写对应的GWT场景。
你必须参考中的完整场景格式和示例。
references/gwt-template.mdApplication-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.
每个垂直切片都必须包含至少一个定义在应用边界的GWT场景:
- Given:系统处于已知状态(历史Event、种子数据、配置)
- When:用户(或外部调用方)通过应用的外部接口进行交互——具体接口取决于项目(HTTP端点、CLI命令、消息队列消费者、UI操作等)
- Then:在同一边界可以观察到结果——响应、输出、渲染的状态变化、发出的Event等。
完全通过调用内部函数就能满足的GWT场景描述的是单元级规范,而非切片的验收标准。切片的验收标准必须覆盖从外部输入到可观察输出的完整路径。
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.
当应用边界支持程序化测试时——比如HTTP端点、CLI输出解析、无头浏览器自动化、消息队列断言、API契约测试等——编写自动化验收测试,覆盖从外部输入到可观察输出的完整GWT场景。这些测试能提供快速反馈,同时作为切片行为的活文档。
当无法进行自动化边界测试时(比如复杂的GUI交互、依赖硬件的行为、视觉/美学验证),记录人工验证的内容:具体的操作步骤和预期的可观察结果。这份人工验证清单将成为切片完成标准的一部分。
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.
共享Event schema的切片是相互独立的。Event schema是它们的共享契约。Command切片通过断言生成的Event来进行测试;视图切片使用合成的Event测试数据。二者都不需要等待对方实现。切片之间不应存在人为的依赖链。
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.
编写完GWT场景后,验证模型的完整性:
- 每个查询模型的字段都能追溯到某个Event
- 每个Event都有对应的触发源(Command、自动化流程或转换适配)
- 每个Command都有文档化的拒绝条件(业务规则)
- 每个自动化流程都有终止条件
- GWT场景的Given/When/Then子句没有引用未定义的元素
当发现缺口时,询问用户以明确信息,补充缺失的元素,然后重新验证。不要带着缺口继续推进。
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
你是引导者,而非速记员。提出有深度的问题,挑战假设。在每个Event、每个Command、每个回答之后,不断追问“然后会发生什么?”。使用业务语言,而非技术术语。在Event Modeling过程中,不要讨论数据库、API、框架或实现细节。唯一的例外:记录必须集成的第三方系统的名称和用途。
应该做:
- 按顺序遵循所有步骤——流程本身能帮助加深理解
- 持续追问“然后会发生什么?”
- 在所有示例和场景中使用具体、真实的数据
- 一次只设计一个工作流
- 在推进前确保信息完整
- 针对查询模型的字段,询问“是否可以同时存在多个这样的实例?”
- 在标记为自动化流程之前,验证它是否包含所有四个组件
不应该做:
- 因为自认为已经了解足够信息而跳过步骤
- 在建模过程中做出架构或实现决策
- 为数据验证编写GWT场景(交给类型系统处理)
- 同时设计多个工作流
- 带着模型缺口继续推进
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 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.
tdd本技能提供指导性建议。它指导Agent遵循Event Modeling方法论,但无法机械地阻止跳过步骤或生成不完整的模型。当与技能结合使用时,Event Modeling生成的GWT场景将成为强制执行模型的验收测试。如果没有技能,Agent将通过惯例遵循这些实践。如果你发现步骤被跳过,请指出来。
tddtddVerification
验证清单
After completing event modeling work, verify:
- Domain overview exists at with actors, workflows, external integrations, and recommended starting workflow
docs/event_model/domain/overview.md - Each designed workflow has with all 9 steps completed
docs/event_model/workflows/<name>/overview.md - 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 ) with concrete data
docs/event_model/workflows/<name>/slices/*.md - 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.
完成Event Modeling工作后,验证以下内容:
- 领域概览文件已存在,包含参与者、工作流、外部集成以及推荐的起始工作流
docs/event_model/domain/overview.md - 每个已设计的工作流都有文件,且已完成全部9个步骤
docs/event_model/workflows/<name>/overview.md - 所有Event都采用过去式的业务语言命名,是不可变的事实
- 每个查询模型的字段都能追溯到源Event
- 每个Event都有触发源(Command、自动化流程或转换适配)
- 自动化流程包含所有四个组件(Event、查询模型、条件逻辑、Command)
- 当领域支持并发实例时,查询模型的字段使用集合类型
- 跨领域基础设施未被建模为转换适配切片
- 每个切片都有GWT场景(内联在中),且使用了具体数据
docs/event_model/workflows/<name>/slices/*.md - GWT错误场景仅测试业务规则,而非数据验证
- 共享Event schema的切片可独立测试(无人工依赖链)
- 模型验证后没有剩余缺口
如果任何一项标准未满足,重新审视相关实践后再继续推进。
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本技能可独立使用。为了增强工作流,它可以与以下技能集成:
- domain-modeling:Event会揭示领域类型(Email、Money、OrderStatus),domain-modeling技能可对这些类型进行细化
- tdd:每个垂直切片对应一个TDD周期
- architecture-decisions:事件模型为架构提供参考;但不应在Event Modeling过程中编写ADR
- task-management:工作流对应史诗(Epic),切片对应任务
缺少依赖?使用以下命令安装:
npx skills add jwilger/agent-skills --skill domain-modeling