@eventmodelers/cli 1.0.37 → 1.0.38

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. package/package.json +1 -1
  2. package/shared/skills/learn-eventmodelers-api/SKILL.md +10 -3
  3. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-applying-conways-law/SKILL.md +3 -61
  4. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-brainstorming-events/SKILL.md +24 -93
  5. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-checking-completeness/SKILL.md +2 -0
  6. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-core-rules/SKILL.md +182 -0
  7. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-automation-chains/SKILL.md +23 -7
  8. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-event-models/SKILL.md +50 -223
  9. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-event-models/references/examples.md +30 -120
  10. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-elaborating-scenarios/SKILL.md +3 -78
  11. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-inputs/SKILL.md +3 -50
  12. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-outputs/SKILL.md +3 -54
  13. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-interview-protocol/SKILL.md +31 -0
  14. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/SKILL.md +27 -67
  15. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/references/domain-patterns.md +15 -15
  16. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/references/patterns.md +44 -52
  17. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-orchestrating-event-modeling/SKILL.md +14 -15
  18. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-plotting-events/SKILL.md +4 -0
  19. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/SKILL.md +3 -15
  20. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-storyboarding-events/SKILL.md +3 -50
  21. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-translating-external-events/SKILL.md +4 -56
  22. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models/SKILL.md +58 -97
  23. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models-checklist/SKILL.md +72 -127
  24. package/stacks/modeling-kit/templates/.claude/skills/place-element/SKILL.md +15 -1
  25. package/stacks/modeling-kit/templates/.claude/skills/place-element/references/api-fallback.md +11 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eventmodelers/cli",
3
- "version": "1.0.37",
3
+ "version": "1.0.38",
4
4
  "description": "Eventmodelers CLI — real-time Claude agent + skills for Claude Code, for any stack (Node, Supabase, Axon, Cratis, or modeling-only)",
5
5
  "type": "module",
6
6
  "bin": {
@@ -68,7 +68,7 @@ Server name: `eventmodelers`. Every tool takes `boardId` explicitly; none need `
68
68
 
69
69
  **Not exposed via MCP at all** — always use REST/curl for these: §7 Config Import, §10 Snapshots, §11–12 User Management, §13 Utility (`/api/user`, swagger), and the rest of §14 Prompts (submission, claiming, deletion, realtime-token) — only the status-update endpoint has an MCP tool (`update_prompt_status`, used by the `update-prompt-status` skill); everything else in Prompts is an intentionally separate lifecycle the board-content MCP server doesn't otherwise own.
70
70
 
71
- **Capabilities with no direct MCP filter** — e.g. REST's `GET .../nodes?cellId=<id>` (§3) has no `cellId` param on `get_nodes`. Get the same answer by calling `get_node` on the CHAPTER and reading `meta.timelineData.cells` (sparse array; a cell absent from it is empty) instead of asking the server to filter by cell.
71
+ **Capabilities with no direct MCP filter** — e.g. REST's `GET .../nodes?cellId=<id>&timelineId=<id>` and `?colId=<id>&timelineId=<id>` (§3) have no equivalent params on `get_nodes`. Either call the REST endpoint directly, or get the same answer by calling `get_node` on the CHAPTER and reading `meta.timelineData.cells` (sparse array; a cell absent from it is empty) instead of asking the server to filter by cell/column.
72
72
 
73
73
  ---
74
74
 
@@ -379,8 +379,15 @@ interface NodeChangeEvent {
379
379
  ### GET `/api/org/:orgId/boards/:boardId/nodes`
380
380
  List all nodes on a board.
381
381
 
382
- **Query params**: `type?: ElementType`
383
- **Response**: `200` — node record array
382
+ **Query params**:
383
+ - `type?: ElementType` — exact match.
384
+ - `cellId?: string` — return only the node occupying this timeline cell (format `<rowId>-<colId>`). Requires `timelineId`. Empty array if the cell is unoccupied.
385
+ - `colId?: string` — return every node occupying this column, across *all* rows of the timeline (e.g. to check for an existing COMMAND/READMODEL/SCREEN/AUTOMATION before placing one, since the server caps those at one per column even across separate lane rows). Requires `timelineId`. Combine with `type` to narrow to one element type.
386
+ - `timelineId?: string` — the CHAPTER node `cellId`/`colId` are resolved against. Required together with either of those two; `400` if omitted.
387
+
388
+ Cell/column occupancy lives only in the CHAPTER node's `meta.timelineData.cells`, never on the node rows themselves — this endpoint resolves `cellId`/`colId` against that timeline internally so callers don't have to fetch and parse the whole chapter node just to check occupancy.
389
+
390
+ **Response**: `200` — node record array. `400` — `cellId`/`colId` given without `timelineId`. `404` — `timelineId` doesn't reference an existing CHAPTER node with grid data.
384
391
 
385
392
  ---
386
393
 
@@ -11,16 +11,14 @@ allowed-tools:
11
11
 
12
12
  > **Before doing anything else**, invoke the `connect` skill — if not already connected — to resolve `TOKEN`, `BOARD_ID`, `ORG_ID`, and `BASE_URL`. Do not proceed until it has completed. Consult `learn-eventmodelers-api` only if you need to look up a specific endpoint or field this file doesn't cover — don't load it eagerly.
13
13
 
14
+ This step applies the shared element rules in **`eventmodeling-core-rules`** — read it once per session if you haven't already; it defines what a COMMAND/EVENT/READMODEL/SCREEN/AUTOMATION is, how each is named, and the anti-patterns to reject, so this step doesn't restate them.
15
+
14
16
  ## Interview Phase (Optional)
15
17
 
16
18
  **When to Interview**: Skip if the user has already specified: existing team structure, team responsibilities, and autonomous boundary preferences. Interview when team structure is unclear or organizational alignment hasn't been discussed.
17
19
 
18
- **Interview Strategy**: Understand team organization and decision-making to design system boundaries that teams can own independently. Misalignment here creates bottlenecks and tight coupling later.
19
-
20
20
  ### Critical Questions
21
21
 
22
- When team structure or boundaries are unclear:
23
-
24
22
  1. **Team Structure & Ownership** (Impact: Determines how many swimlanes/systems to create)
25
23
  - Question: "How is your organization structured? (A) Single team owns everything, (B) Separate teams by domain (payments, inventory, etc.), (C) Separate teams by function (backend, frontend, etc.)"
26
24
  - Why it matters: Team structure directly shapes system boundaries; aligning them reduces coordination overhead
@@ -36,63 +34,7 @@ When team structure or boundaries are unclear:
36
34
  - Why it matters: External systems often become separate swimlanes; knowing which ones matters for boundary design
37
35
  - Follow-up triggers: For each integration → ask "Who owns the integration—existing team or new team?"
38
36
 
39
- ### Interview Flow
40
-
41
- **Conditional Entry**:
42
- ```
43
- If user has provided:
44
- - Clear team structure (who owns what)
45
- - AND specified desired level of autonomy
46
- - AND identified external integrations
47
-
48
- Then: Skip interview, proceed directly to swimlanes
49
-
50
- Else: Conduct interview
51
- ```
52
-
53
- **Phase 1: Organization Assessment** (Questions 1-2)
54
- - Understand team structure
55
- - Determine autonomy expectations
56
- - Establish boundary philosophy
57
-
58
- **Phase 2: Integration Mapping** (Question 3)
59
- - Identify external systems
60
- - Plan integration boundaries
61
- - Finalize swimlane count
62
-
63
- ### Capturing Interview Findings
64
-
65
- Append findings to the project's event modeling file:
66
-
67
- **File**: `.trogonai/interviews/[project-name]/EVENTMODELING.md`
68
-
69
- Use Write tool to add/update this section:
70
-
71
- ```markdown
72
- ## 6. Conway's Law (eventmodeling-applying-conways-law)
73
-
74
- ### Team Structure
75
- - Team 1: [Name] - Owns [domain]
76
- - Team 2: [Name] - Owns [domain]
77
- - Team 3: [Name] - Owns [domain]
78
-
79
- ### Autonomy Goals
80
- [High / Moderate / Low]
81
-
82
- ### Swimlanes
83
- - [Swimlane 1]: [Team] owns [events]
84
- - [Swimlane 2]: [Team] owns [events]
85
- - [Swimlane 3]: [Team] owns [events]
86
-
87
- ### Cross-Team Communication
88
- - [Team A] → [Team B] via [event]
89
- - [Team B] → [Team C] via [event]
90
- ```
91
-
92
- Update Interview Trail:
93
- ```markdown
94
- | 6 | eventmodeling-applying-conways-law | [today] | Swimlanes defined, team boundaries confirmed |
95
- ```
37
+ Follow **`eventmodeling-interview-protocol`** to run this interview and record its findings — label this step "**6. Conway's Law** (`eventmodeling-applying-conways-law`)". Findings should cover: team structure and ownership, autonomy goals, the resulting swimlanes (which team owns which events), and cross-team communication paths.
96
38
 
97
39
  ---
98
40
 
@@ -11,18 +11,16 @@ allowed-tools:
11
11
 
12
12
  > **Before doing anything else**, invoke the `connect` skill — if not already connected — to resolve `TOKEN`, `BOARD_ID`, `ORG_ID`, and `BASE_URL`. Do not proceed until it has completed. Consult `learn-eventmodelers-api` only if you need to look up a specific endpoint or field this file doesn't cover — don't load it eagerly.
13
13
 
14
+ This step applies the shared element rules in **`eventmodeling-core-rules`** — read it once per session if you haven't already; it defines what a COMMAND/EVENT/READMODEL/SCREEN/AUTOMATION is, how each is named, and the anti-patterns to reject, so this step doesn't restate them.
15
+
14
16
  Prefer `mcp__eventmodelers__*` tools when available (registered by the `connect` skill) — the curl blocks below are the fallback for sessions without MCP connected.
15
17
 
16
18
  ## Interview Phase (Optional)
17
19
 
18
- **When to Interview**: Skip if the user has provided detailed, well-documented requirements (written user stories, feature specs, business rules). Interview when requirements are vague, incomplete, or when domain expertise is uncertain.
19
-
20
- **Interview Strategy**: Ensure requirements are complete and team understands domain well enough to brainstorm comprehensively. Identify hidden complexity areas upfront.
20
+ **When to Interview**: Skip if the user has provided detailed, well-documented requirements (written user stories, feature specs, business rules) and named who understands the domain. Interview when requirements are vague, incomplete, or domain expertise is uncertain.
21
21
 
22
22
  ### Critical Questions
23
23
 
24
- When requirements need clarification:
25
-
26
24
  1. **Requirements Completeness** (Impact: Determines if brainstorm is likely to be exhaustive)
27
25
  - Question: "How complete are your requirements? Do you have: (A) Written user stories/specs, (B) Documented business rules, (C) Rough list, (D) Just verbal descriptions?"
28
26
  - Why it matters: Incomplete requirements cause missed events; complete requirements enable comprehensive brainstorm
@@ -43,76 +41,7 @@ When requirements need clarification:
43
41
  - Why it matters: Business rules often generate specific events; documenting them prevents overlooking state changes
44
42
  - Follow-up triggers: For each rule → ask "When this rule is violated, what event signals that?"
45
43
 
46
- ### Interview Flow
47
-
48
- **Conditional Entry**:
49
- ```text
50
- If user has provided:
51
- - Written requirements or user stories (not just verbal)
52
- - AND documented business rules or constraints
53
- - AND named domain experts who will participate
54
-
55
- Then: Skip interview, proceed directly to brainstorming
56
-
57
- Else: Conduct interview
58
- ```
59
-
60
- **Phase 1: Requirements Assessment** (Questions 1-2)
61
- - Gauge requirements completeness
62
- - Confirm domain expertise available
63
- - Adjust brainstorm scope accordingly
64
-
65
- **Phase 2: Complexity Mapping** (Questions 3-4)
66
- - Identify areas needing deep exploration
67
- - Document rules that may generate events
68
- - Plan brainstorm focus areas
69
-
70
- ### Capturing Interview Findings
71
-
72
- Append findings to the project's event modeling file:
73
-
74
- **File**: `.trogonai/interviews/[project-name]/EVENTMODELING.md`
75
-
76
- Use Write tool to add/update this section:
77
-
78
- ```markdown
79
- ## 2. Brainstormed Events (eventmodeling-brainstorming-events)
80
-
81
- ### Requirements Assessment
82
- [From Q1: Written requirements? Documented rules?]
83
-
84
- ### Domain Expertise
85
- [From Q2: Who understands domain? Available for participation?]
86
-
87
- ### Role Catalog
88
- #### Human Roles
89
- - [Role 1]: [Description] → Actions: [list]
90
- - [Role 2]: [Description] → Actions: [list]
91
- #### System Actors
92
- - [Actor 1]: [Description] → Triggers: [list]
93
-
94
- ### Event Streams (Stream Roots)
95
- - Stream: [Name] (Identity: [id field])
96
- - Events: [Event1, Event2, Event3]
97
- - State changes: [State transitions]
98
-
99
- ### Business Rules & Constraints
100
- [From Q3 & Q4]
101
- - Rule 1: [Statement] → [Events it generates]
102
- - Rule 2: [Statement] → [Events it generates]
103
- - Constraint 1: [Limitation]
104
-
105
- ### Brainstorming Focus Areas
106
- - [Focus area 1]
107
- - [Focus area 2]
108
- ```
109
-
110
- Update Interview Trail:
111
- ```markdown
112
- | 2 | eventmodeling-brainstorming-events | [today] | Event streams, business rules, constraints |
113
- ```
114
-
115
- This section feeds into subsequent steps (plotting, storyboarding, etc.)
44
+ Follow **`eventmodeling-interview-protocol`** to run this interview and record its findings — label this step "**2. Brainstormed Events** (`eventmodeling-brainstorming-events`)". Findings should cover: requirements completeness, domain expertise available, the Role Catalog, entities/event timelines identified, business rules & constraints, and brainstorming focus areas — this feeds directly into plotting and storyboarding.
116
45
 
117
46
  ---
118
47
 
@@ -149,6 +78,13 @@ After completing the analysis, partition the full event list into groups where e
149
78
 
150
79
  If all events belong to a single flow, one timeline is correct — do not split artificially.
151
80
 
81
+ **Divergent journey vs. a decision point — do not confuse the two.** A group of events sometimes contains a branch, and the branch's nature decides whether it gets its own chapter or stays inside this one:
82
+
83
+ - **Divergent journey → its own chapter.** The actor makes a different choice *before* the process even starts, and everything downstream differs as a result (e.g. "Checkout with saved card" vs. "Checkout as guest" — different screens, different commands, arguably a different Role Catalog entry). Group these as separate workflows in Step 1, not as one group with a fork in it.
84
+ - **Decision point → stays in this one chapter.** A single trigger — one command's outcome, or one automation's rule — resolves to one of several mutually exclusive results, and the rest of the process is otherwise the same story (e.g. `PaymentAuthorized` succeeds or fails, `OrderConfirmed` vs. `OrderCancelled` after the same confirm action). Keep this as one group; `eventmodeling-plotting-events`'s "Identify Alternative Paths" step is exactly where this branch gets shown, as sibling paths within the same timeline — it never means a second chapter.
85
+
86
+ If unsure which one you're looking at, ask: "does this branch start a genuinely different story, or does it just decide how *this* story ends?" A different story is a new chapter; a different ending is a branch inside this one.
87
+
152
88
  ### 2. Create one chapter per group
153
89
 
154
90
  For each group, create a chapter on the board **before placing any events**. Reuse an existing chapter if one already matches the workflow name.
@@ -304,7 +240,7 @@ An event left without a chapter and cell reference will never appear in any time
304
240
 
305
241
  **Use swimlanes sparingly — a swimlane exists for exactly one purpose: marking where integration with another system happens. Nothing else justifies one.** Not a different actor, not a different role, not visual grouping, not "an explicit business rule" in the abstract. Every chapter starts with, and in the common case keeps, a single default swimlane holding all of this bounded context's own domain events. Before adding a lane, check whether an existing lane already covers the element's type. If yes, place the element in that lane.
306
242
 
307
- **The only valid reason to create a second `swimlane`-type lane: another system's own events cross into this chapter as integration triggers for a translation automation** (see `eventmodeling-designing-automation-chains`, Step 4b). Label it for that system and place its trigger events there — never fold them into this chapter's own event swimlane (they are not this bounded context's domain facts) and never treat them as an informal "signal" with no EVENT node at all. An external EVENT may only ever open the *translation* automation's todo list — never the todo list of the automation that does the actual domain work; that automation is triggered solely by the internal event the translation automation produces (Step 4b covers the full two-automation chain).
243
+ **The only valid reason to create a second `swimlane`-type lane: another system's own events cross into this chapter as integration triggers for a translation automation** (see `eventmodeling-designing-automation-chains`, Step 4b). Label it for that system and place its trigger events there — never fold them into this chapter's own event swimlane (they are not this bounded context's domain facts) and never treat them as an informal "signal" with no EVENT node at all. An external EVENT may only ever open the *translation* automation's todo list — never the todo list of the automation that does the actual domain work; that automation is triggered solely by the internal event the translation automation produces, and only exists at all when reacting to that internal event genuinely requires a new decision (Step 4b covers the full translation chain, and when a worker automation belongs after it).
308
244
 
309
245
  **Never** add a swimlane for any other reason — not a new actor, not a new role, not visual grouping. Human roles get their own **actor** lane during Step 3 (Storyboarding) — a different row type entirely — never a new swimlane here.
310
246
 
@@ -346,18 +282,18 @@ This catalog feeds directly into:
346
282
  - **Step 7 (Scenarios)**: Scenarios reference roles by name
347
283
  - **Step 8 (Completeness)**: Verify every role has at least one command path
348
284
 
349
- ### 2. Identify Event Streams (Stream Roots)
350
- Identify the main entities that will have event streams. These are NOT DDD aggregates—they're simply the logical roots of events:
285
+ ### 2. Identify Entities (Event Timelines)
286
+ Identify the main entities whose story will be told as a timeline of events:
351
287
  - User/Account
352
288
  - Order
353
289
  - Payment
354
290
  - Shipment
355
291
  - etc.
356
292
 
357
- For each stream root, note:
293
+ For each entity, note:
358
294
  - Name (use domain language, not technical terms)
359
295
  - Identity key (what uniquely identifies instances: orderId, paymentId, customerId, etc.)
360
- - What commands will affect it (we'll define state needs per command, not upfront)
296
+ - What commands will affect it
361
297
 
362
298
  ### 3. Identify Business Processes
363
299
  Map out critical workflows:
@@ -410,13 +346,13 @@ Present findings in this structure (include facilitation notes for future worksh
410
346
  - Triggers: [What events/commands it initiates]
411
347
  - Communication: [Webhooks / Event-driven / API]
412
348
 
413
- ## Event Streams (Stream Roots)
414
- List each stream root and its identity:
415
- - **Stream**: Review (Identity: reviewId)
416
- - **Stream**: SellerResponse (Identity: responseId)
417
- - **Stream**: Seller (Identity: sellerId)
349
+ ## Entities (Event Timelines)
350
+ List each entity and its identity:
351
+ - **Entity**: Review (Identity: reviewId)
352
+ - **Entity**: SellerResponse (Identity: responseId)
353
+ - **Entity**: Seller (Identity: sellerId)
418
354
 
419
- Note: These are just the logical groupings of events. The STATE needed for each command will be determined later—not all stream attributes are needed for all commands.
355
+ Note: These are just the logical groupings of events the story each entity's timeline tells.
420
356
 
421
357
  ## Business Processes
422
358
  1. **Process Name**: Description
@@ -439,10 +375,6 @@ Note: These are just the logical groupings of events. The STATE needed for each
439
375
  ## Output Format
440
376
  Present analysis in a clear markdown structure that can be directly used by the eventmodeling-designing-event-models skill.
441
377
 
442
- ## Core Architectural Rule
443
-
444
- **NEVER use a DDD Aggregate pattern for state design** — every command handler must have its own minimal state projection derived from events. This is non-negotiable. See `eventmodeling-designing-event-models`'s "Core Architectural Rule" for the full anti-pattern/correct-pattern worked example (`OrderAggregate` vs. per-command state) — the rule applies from this very first step, not just once design begins.
445
-
446
378
  ## Key Principles
447
379
  - Use **domain language**, not technical terms
448
380
  - Focus on **what** happens, not **how** it's implemented
@@ -452,9 +384,8 @@ Present analysis in a clear markdown structure that can be directly used by the
452
384
  - **Collaborative Process**: This is a group brainstorm, not a solo analysis
453
385
  - **Rapid Iteration**: Capture quickly, refine later
454
386
  - **Gentle Filtering**: Introduce "state-changing events" concept conversationally, not as rigid rule
455
- - **Event Sourcing Mindset**: Think in terms of immutable events and stream roots, NOT DDD aggregates. The stream root is just a logical grouping of events; state is minimal and command-specific.
456
- - **Defer State Design**: Don't list all entity attributes upfront. In the model designer step, we'll define minimal state projections needed for each specific command.
457
- - **Command State Isolation**: Each command handler has its own state shape. Different commands = different state interfaces.
387
+ - **Event Sourcing Mindset**: Think in terms of immutable events grouped by entity, not upfront attribute lists
388
+ - **Defer Detail**: Don't list all entity attributes upfront commands, preconditions, and read models get worked out in the design step
458
389
 
459
390
  ## Best Practices for Requirements Analysis
460
391
 
@@ -10,6 +10,8 @@ allowed-tools:
10
10
 
11
11
  > **Before doing anything else**, invoke the `connect` skill — if not already connected — to resolve `TOKEN`, `BOARD_ID`, `ORG_ID`, and `BASE_URL`. Do not proceed until it has completed. Consult `learn-eventmodelers-api` only if you need to look up a specific endpoint or field this file doesn't cover — don't load it eagerly.
12
12
 
13
+ This step applies the shared element rules in **`eventmodeling-core-rules`** — read it once per session if you haven't already; it defines what a COMMAND/EVENT/READMODEL/SCREEN/AUTOMATION is, how each is named, and the anti-patterns to reject, so this step doesn't restate them.
14
+
13
15
  Prefer `mcp__eventmodelers__*` tools when available (registered by the `connect` skill) — the curl blocks below are the fallback for sessions without MCP connected.
14
16
 
15
17
  ## Board Context
@@ -0,0 +1,182 @@
1
+ ---
2
+ name: eventmodeling-core-rules
3
+ description: Shared, foundational rules for every event-modeling step — what a COMMAND/EVENT/READMODEL/SCREEN/AUTOMATION is, how each is named, and the anti-patterns to reject. Not a step of its own — referenced upfront by every other eventmodeling-* skill instead of each restating its own copy. Do not use standalone.
4
+ ---
5
+
6
+ # Event Modeling — Core Rules
7
+
8
+ These rules apply to every step of event modeling, regardless of which step's SKILL.md you're currently following. Read this once per session — a step's own file only states what's specific to that step, not these fundamentals.
9
+
10
+ ## Modes
11
+
12
+ Which step you're in sets the posture — don't mix them.
13
+
14
+ - **Modeling Mode** — `brainstorming-events`, `plotting-events`, `storyboarding-events`, `identifying-inputs`, `identifying-outputs`, `designing-automation-chains`, `elaborating-scenarios`, `translating-external-events`: explore and build. Capture the process as completely as you can. A naming slip or an incomplete precondition is something to flag and move past, not a reason to stall the whole step — don't over-correct early.
15
+ - **Critic Mode** — `validating-event-models`, `validating-event-models-checklist`, `checking-completeness`, `wdyt`, `optimizing-stream-design`: review what's already there. Apply every rule in this file strictly. Surface every violation, gap, and inconsistency — don't soften a finding because the model "mostly works." Post findings as comments (`handle-comment`) rather than silently fixing them, unless the step explicitly says to fix.
16
+
17
+ Don't mix them in one pass: a modeling step is not the place to run a full rules audit, and a critic step is not the place to quietly add missing structure on the model's behalf instead of flagging it.
18
+
19
+ ## Lanes — What Lives Where
20
+
21
+ Every column on a timeline has (at most) four rows, and each element type belongs in exactly one:
22
+
23
+ | Lane type | Elements allowed | What it represents |
24
+ |---|---|---|
25
+ | `actor` | SCREEN, AUTOMATION | Who or what initiates — a human via a screen, or a system via an automation |
26
+ | `interaction` | COMMAND, READMODEL | The business intent going in (COMMAND), or the query result coming out (READMODEL) |
27
+ | `swimlane` | EVENT | The business fact recorded — which system/entity's own story this event belongs to |
28
+ | `spec` | SCENARIO | The Given/When/Then behavior spec for this column's COMMAND or READMODEL |
29
+
30
+ An EVENT never shares a column with another EVENT even across different swimlane rows — one column is one moment in time. See `place-element` for the full placement mechanics; this table is only "what belongs where," not "how to place it."
31
+
32
+ ## Slices
33
+
34
+ A **slice** is the thinnest possible vertical cut through the model — exactly one COMMAND, one READMODEL, or one AUTOMATION's command, never combined:
35
+
36
+ ```
37
+ state-change slice = SCREEN/AUTOMATION → COMMAND → EVENT(s)
38
+ state-view slice = EVENT(s) → READMODEL → SCREEN/AUTOMATION
39
+ automation slice = EVENT(s) → AUTOMATION → COMMAND → EVENT(s)
40
+ ```
41
+
42
+ A slice never mixes a COMMAND and a READMODEL — those are two different slice types (`state-change` and `state-view`), even when they belong to the same feature. Slices are independently deployable and only communicate with each other via events.
43
+
44
+ Slices are not placed directly — they're **derived** from a completed model. Every COMMAND on the board implies a `state-change` slice, every READMODEL implies a `state-view` slice, every AUTOMATION implies an `automation` slice. `eventmodeling-slicing-event-models` makes that implicit structure explicit on the board once modeling is done; it never invents a slice that isn't already implied by an element that's there.
45
+
46
+ ## Elements
47
+
48
+ ### EVENT
49
+ - Represents a business fact that already happened.
50
+ - Naming: past tense, business language.
51
+ - Valid: `OrderPlaced`, `PaymentAuthorized`, `UserRegistered`
52
+ - Invalid: `SidebarOpened`, `RequestCompleted`, `ApiCalled` — these describe machinery or UI state, not business facts
53
+ - Immutable — never modify or delete an event once created; a correction is a new event, not an edit.
54
+ - Contains only captured facts. No computed or derived values — those belong in a READMODEL.
55
+
56
+ ### COMMAND
57
+ - Represents business intent — what an actor wants to do.
58
+ - Can be rejected; only succeeds if its documented preconditions hold.
59
+ - Naming: imperative, business language.
60
+ - Valid: `PlaceOrder`, `ConfirmPayment`, `CancelSubscription`
61
+ - Invalid: `LoadOrders`, `FetchData`, `OpenDialog` — these are queries or UI-only actions, not business intent
62
+ - Issued by exactly one SCREEN or AUTOMATION — never two. See `place-element`'s Step 7c for the mechanical check/fix; this rule is stated here, the fix lives there.
63
+ - Produces one or more EVENTs on success, or is rejected with no event.
64
+
65
+ ### READMODEL
66
+ - A projection built from events, shaped for a specific query.
67
+ - Naming: noun phrase, business language, named for the data — not the machinery that produces it.
68
+ - Valid: `OrderSummary`, `InvoiceList`
69
+ - Invalid: `OrderSummaryProjector`, `InvoiceListRepository` — implementation detail leaking into the model
70
+ - Optional — nothing requires a READMODEL to exist for a COMMAND or a downstream consumer.
71
+ - Never drives COMMAND validation directly — a COMMAND is checked against its own documented preconditions, not a read model.
72
+
73
+ ### SCREEN
74
+ - Represents what a user sees and can act on.
75
+ - Naming: what a user would call it, not its internals.
76
+ - Valid: `Dashboard`, `OrderOverviewPage`
77
+ - Invalid: `OrderOverviewComponent`, `ProjectorView`
78
+
79
+ ### AUTOMATION
80
+ - Represents an automated actor — a processor, scheduler, or system reacting to events.
81
+ - Naming: what it does, in business language.
82
+ - Valid: `BillingScheduler`, `InventoryReserver`
83
+ - Invalid: `OrderServiceHandler` — implementation-flavored, not a business actor's name
84
+
85
+ ## Causality
86
+
87
+ - Every EVENT traces to the COMMAND that produced it.
88
+ - Every COMMAND traces to the SCREEN or AUTOMATION that issued it — exactly one.
89
+ - A process starts with a read (SCREEN + READMODEL) or an AUTOMATION reacting to an existing EVENT — never with an unmotivated COMMAND.
90
+
91
+ ## Role Catalog
92
+
93
+ Every event model needs one, established before brainstorming events (it's the first mandatory step) — without it, downstream steps have no way to say *who* does what:
94
+
95
+ - **Human roles** (Customer, Seller, Admin...) and **system actors** (Payment Gateway, Scheduler...), each with: a name in domain language, a one-line description, its key actions, and what it explicitly cannot do.
96
+ - No COMMAND may be attributed to a generic "User" — it must name a specific role or actor from the catalog.
97
+ - Every COMMAND is issued by exactly one role/actor (this is the same rule as the COMMAND single-issuer rule above, stated from the Role Catalog's side).
98
+ - Every human role needs at least one COMMAND and one READMODEL — a role in the catalog that never acts and never sees anything is decorative, not modeled.
99
+
100
+ See `eventmodeling-brainstorming-events` for how the catalog is built, `eventmodeling-identifying-inputs` for attributing commands to it, and `eventmodeling-validating-event-models` for re-checking it holds once the model is complete.
101
+
102
+ ## Field Lineage
103
+
104
+ Every field on a COMMAND or READMODEL must carry a `mapping` that traces it back to where its value actually comes from — user input, the session, a prior event's field, a derived/computed value, or an external webhook payload. **A field with no mapping is a gap, not a detail to fill in later.**
105
+
106
+ See `eventmodeling-identifying-inputs` for the full COMMAND mapping vocabulary and `eventmodeling-identifying-outputs` for the READMODEL equivalent — this rule only states that every field must have one, not the mapping syntax itself.
107
+
108
+ ## Connections Read Forward
109
+
110
+ A connection either goes **downward within the same column** (actor → interaction → swimlane → spec) or **forward to a later column** — never backward (right-to-left). This is why elements that belong together — a SCREEN and the READMODEL it queries, a SCREEN/AUTOMATION and the COMMAND it issues, a COMMAND and the EVENT it produces — should share a column whenever possible: the moment they don't, a backward arrow becomes a real risk.
111
+
112
+ When an element's natural column is already occupied by something else, insert a new column immediately before or after (whichever keeps every connection forward) rather than wiring across the gap. See `place-element` for the mechanical insertion rules and each step's own placement section for where "before" vs. "after" applies.
113
+
114
+ ## Translation Chain
115
+
116
+ An AUTOMATION reacting to an event from another system — external (a webhook/API) or second-swimlane (another team's own timeline) — needs a two-stage shape, never a direct reaction:
117
+
118
+ ```
119
+ external EVENT → todo-list READMODEL → translation AUTOMATION + COMMAND → internal EVENT → worker automation's own todo list
120
+ ```
121
+
122
+ - The external/second-swimlane EVENT opens only a *translation* automation's todo list — never a *worker* automation's todo list directly.
123
+ - A translation automation's own todo list is opened by that external event and is never closed — it doesn't track "done," it only relays.
124
+ - Its resulting COMMAND produces the internal EVENT the domain actually works with — that's the moment external data becomes a business fact in this domain's own language, ready for a worker automation (or anything else) to react to.
125
+
126
+ Every AUTOMATION, translation or worker, needs its own todo-list READMODEL (opened by triggering events, closed by completion events) — no "pure relay" exemption. See `eventmodeling-designing-automation-chains` for the todo-list pattern and board placement mechanics, and `eventmodeling-translating-external-events` for mapping the external payload's raw fields to the internal EVENT's domain fields (correlation, idempotency, duplicate handling).
127
+
128
+ ## Open Questions vs. Decided Failures
129
+
130
+ Two different things are easy to conflate, and conflating them corrupts completeness checking:
131
+
132
+ - **Open question** — something genuinely undecided. Post it as a `QUESTION`-type comment (`handle-comment`) on the relevant node. It stays open until someone actually answers it — resolving means answering, not deleting the comment.
133
+ - **Decided failure** — a rejection or error case whose behavior is already decided (e.g. "payment fails → reject, no event"). Model it as a SCENARIO with `expectError: true` and an `errorDescription` (see `eventmodeling-elaborating-scenarios`), never as a comment. It's permanent, specified behavior, not something waiting on an answer.
134
+
135
+ A decided failure left as a lingering `QUESTION` comment looks unresolved when it isn't. When counting completeness (`eventmodeling-checking-completeness`), only a genuinely unanswered `QUESTION` counts as a gap — a decided failure path needs its `expectError` scenario, not a comment standing in for one.
136
+
137
+ ## Offline-First Thinking
138
+
139
+ Model the business process as it would work without any software first, then translate to elements:
140
+
141
+ - How would this work manually, with people, on paper?
142
+ - Who acts, and what triggers each action?
143
+ - What information do they need before they can act?
144
+
145
+ Question any step that exists only because of the system — a loading spinner, a cache refresh, a session check is not a business step and does not belong on the timeline. This is the discipline behind the Anti-Patterns below; the anti-patterns are what it looks like when this principle is skipped.
146
+
147
+ ## Anti-Patterns
148
+
149
+ - **Data-loading commands**: `LoadOrders`/`FetchData` are queries, not business intent — model as a READMODEL, not a COMMAND.
150
+ - **UI-interaction events**: `SidebarOpened`/`ButtonClicked` are UI state, not business facts — don't model them unless the business genuinely cares.
151
+ - **Technical events**: `ApiCalled`/`ResponseReceived` describe machinery, not an outcome — find the business fact underneath.
152
+ - **Calculated events**: an event whose value is recomputed as source data changes (a running total, an average) is a READMODEL, not an EVENT.
153
+
154
+ ## Flow & Causality
155
+
156
+ Model causality, not strict sequence:
157
+
158
+ - A timeline starts with a **state-view** (READMODEL feeding a SCREEN) or an **automation** reacting to an EVENT already on the board — never with an unmotivated COMMAND.
159
+ - Every COMMAND must be traceable to a trigger: a SCREEN (a user decision) or an AUTOMATION (a system reaction).
160
+ - A `state-change` slice must not follow another `state-change` slice without a trigger in between (a new SCREEN or AUTOMATION) — two COMMANDs in a row with nothing issuing the second one is a gap, not a shortcut.
161
+
162
+ Valid transitions between slices:
163
+ - state-view → state-change
164
+ - state-change → state-view
165
+ - state-change → automation
166
+ - automation → state-change
167
+ - automation → state-view
168
+
169
+ ## Quick Self-Check
170
+
171
+ Before treating a model as done, verify:
172
+
173
+ - [ ] Every EVENT is past tense and describes a business fact, not machinery or UI state
174
+ - [ ] Every COMMAND is imperative business intent, not a data-loading query
175
+ - [ ] Every READMODEL is named for its data, not its implementation
176
+ - [ ] No EVENT holds a computed/aggregated value — that belongs in a READMODEL
177
+ - [ ] Every COMMAND has exactly one issuer (one inbound SCREEN or AUTOMATION edge)
178
+ - [ ] Every COMMAND traces back to a SCREEN (user decision) or AUTOMATION (system reaction)
179
+ - [ ] The timeline starts with a state-view or an automation reacting to an event — not a bare COMMAND
180
+ - [ ] No two `state-change`/`state-change` slices are chained without a new trigger between them
181
+
182
+ This is the fast pass — the full, deeper check is `eventmodeling-validating-event-models-checklist`.
@@ -11,6 +11,8 @@ allowed-tools:
11
11
 
12
12
  > **Before doing anything else**, invoke the `connect` skill — if not already connected — to resolve `TOKEN`, `BOARD_ID`, `ORG_ID`, and `BASE_URL`. Do not proceed until it has completed. Consult `learn-eventmodelers-api` only if you need to look up a specific endpoint or field this file doesn't cover — don't load it eagerly.
13
13
 
14
+ This step applies the shared element rules in **`eventmodeling-core-rules`** — read it once per session if you haven't already; it defines what a COMMAND/EVENT/READMODEL/SCREEN/AUTOMATION is, how each is named, and the anti-patterns to reject, so this step doesn't restate them.
15
+
14
16
  Prefer `mcp__eventmodelers__*` tools when available (registered by the `connect` skill) — the curl blocks below are the fallback for sessions without MCP connected.
15
17
 
16
18
  This is **Step 4b**. It runs immediately after `eventmodeling-identifying-inputs` (Step 4) places an AUTOMATION and its COMMAND, and before `eventmodeling-identifying-outputs` (Step 5) designs any screen-facing read model. Designing an automation's todo list — and, when it applies, its translation chain — while the automation is still fresh from Step 4 is what prevents the alternative: discovering the gap only once Step 5's own verification pass runs, after commands and connections already built on top of the incomplete shape.
@@ -39,15 +41,27 @@ Even an automation that looks like a "pure signal relay" still has a todo list
39
41
 
40
42
  **There is no such thing as an invisible or informal "signal" — a trigger is always a real EVENT node**, placed in a second swimlane when it belongs to another system (see `eventmodeling-brainstorming-events`'s swimlane rule).
41
43
 
42
- **An automation can only ever be directly triggered by an internal event — never by another system's event.** A "trigger" arriving from a second swimlane is not itself the thing that drives your domain's work; it first has to be *translated* into an internal event. Do not model this as one automation whose todo list is opened by the external EVENT and that also does the real work (e.g. an automation reading a todo list opened by `ReservationRequested` from another system's swimlane and directly issuing `ReserveCopy`) — that lets an external system trigger domain work with no translation step, which this model doesn't allow. **Apply this now, in Step 4b** — Conway's Law (Step 6) only confirms the boundary, it doesn't introduce the chain. When an integration trigger comes from another team's system, model it as **two chained automations**, never one:
44
+ **An automation can only ever be directly triggered by an internal event — never by another system's event.** A "trigger" arriving from a second swimlane is not itself the thing that drives your domain's work; it first has to be *translated* into an internal event. Do not model this as one automation whose todo list is opened by the external EVENT and that also does the real work (e.g. an automation reading a todo list opened by `ReservationRequested` from another system's swimlane and directly issuing `ReserveCopy`) — that lets an external system trigger domain work with no translation step, which this model doesn't allow. **Apply this now, in Step 4b** — Conway's Law (Step 6) only confirms the boundary, it doesn't introduce the chain. Every integration trigger from another team's system needs a **translation automation** that part is never optional:
43
45
 
44
46
  1. **Translation automation** — converts the external fact into an internal one; the other system's own decision logic is out of scope. Its todo list is opened by the external EVENT — the one and only place an external EVENT may open a todo list. **It is not closed by the internal EVENT its own command produces, and gets no backward arrow.** A translation automation's job is an instantaneous, always-succeeding relay: there is no real work-in-progress window between "signal arrived" and "internal fact recorded" worth modeling as an open/close lifecycle, unlike a worker automation that can genuinely have pending items. This read model exists only to satisfy "every automation reads from a todo list," not to accumulate and drain a queue — so it stays open-ended: fed by the external EVENT, read by the automation, never closed.
45
47
  - **Three separate columns**, left to right: `[external EVENT] → [todo-list READMODEL] → [AUTOMATION + COMMAND + internal EVENT]`. Never crammed into one or two — the "one EVENT per column" rule applies here too.
46
48
  - **Name the internal EVENT for its business meaning, not the transport** — usually the same name as the external EVENT (e.g. external `CopyReserved` → internal `CopyReserved`; the swimlane already shows which is which), never a mechanical `<X>SignalReceived`/`<X>RequestReceived` suffix. Same for the automation/command: `Record Reservation`/`RecordReservation`, not `Record Reservation Signal`/`RecordReservationSignal`.
47
- - Its command and event carry no business decision — they only exist to produce the internal fact the next automation needs.
48
- 2. **Worker automation** — the one that does the actual work (the domain reaction the process is really about, e.g. `ReserveCopy`). Its todo list is opened **only** by the internal EVENT the translation automation produced (this chapter's own swimlane) — never by the external EVENT directly — and closed by whatever event marks that work done. Unlike the translation stage, the worker's todo list keeps its normal open/close accumulator shape, because real pending work can sit there (it's the point where actual domain decisions happen).
49
+ - Its command and event carry no business decision — they only exist to produce the internal fact a worker automation would need, *if one is even needed* (see below).
50
+
51
+ ### Does a worker automation come after it, or does the chain stop there?
52
+
53
+ The translation automation never decides anything — it only records a fact. Whether something needs to happen *after* that fact depends on whether there is still a decision left to make:
54
+
55
+ - **Build a worker automation only when reacting to the internal EVENT requires a genuinely new decision on this side** — an invariant to check, a choice to make, data to compute that the internal EVENT doesn't already carry. That decision is what earns its own COMMAND, which is what earns the automation that issues it (see item 2 below for its shape).
56
+ - **Do not build one when the internal EVENT already *is* the business-relevant fact.** If the external system already made every decision involved, and the "next" EVENT you were about to model would just restate data the internal EVENT already carries under a different name (same identity, no new field, no invariant checked, no choice made) — stop after the translation automation. That is not a second stage of the same chain; it is no chain at all, just a fact recorded once. Anything else that needs this fact reads the internal EVENT directly through a state-view READMODEL projection — it does not get an automated command reaction bolted on solely to keep a fixed "two automations" shape.
57
+
58
+ *Example*: an external `ReservationPlaced` opens a translation chain and already carries `reservationId`, `copyId`, and `memberId` — the copy to reserve was chosen upstream, by the other system. Translating it into an internal `ReservationPlaced` is still required (per the rule above — an automation may never react to the external event directly). But adding a second `ReservationsToApply` todo list + `Reserve Copy` automation + `CopyReserved` event on top of it is redundant: `CopyReserved` doesn't decide anything `ReservationPlaced` didn't already decide, it's the same fact under a different name. A read model showing "reserved copies" should project directly off the internal `ReservationPlaced` event, not off a manufactured second automation stage.
59
+
60
+ 2. **Worker automation** (only when the check above says one is needed) — the one that does the actual work (a real domain decision the process is about, e.g. checking copy availability before issuing `ReserveCopy`). Its todo list is opened **only** by the internal EVENT the translation automation produced (this chapter's own swimlane) — never by the external EVENT directly — and closed by whatever event marks that work done. Unlike the translation stage, the worker's todo list keeps its normal open/close accumulator shape, because real pending work can sit there (it's the point where actual domain decisions happen).
61
+
62
+ **Two chained automations only when there genuinely are two decisions** — the translation (none, by definition) and the worker (a real one). Whether a worker stage exists at all is a judgment call driven by whether that second decision actually exists, not a fixed shape to stamp onto every cross-swimlane trigger.
49
63
 
50
- Wire the todo lists differently for each automation in the chain: for the translation automation, the external EVENT (second swimlane) **opens** the row and nothing closes it; for the worker automation, the internal EVENT **opens** its row and its own resulting EVENT **closes** it (backward arrow, per the exemption below). `EVENT → READMODEL` connections from both swimlanes are unaffected by which swimlane the event sits in.
64
+ When a worker automation *is* warranted, wire the todo lists differently for each automation in the chain: for the translation automation, the external EVENT (second swimlane) **opens** the row and nothing closes it; for the worker automation, the internal EVENT **opens** its row and its own resulting EVENT **closes** it (backward arrow, per the exemption below). `EVENT → READMODEL` connections from both swimlanes are unaffected by which swimlane the event sits in.
51
65
 
52
66
  ## Fields on a todo-list read model
53
67
 
@@ -116,8 +130,9 @@ Run `validate_model` (`{boardId, chapterId}`) first — with the chain placed `a
116
130
  1. Does it have an incoming `READMODEL → AUTOMATION` connection to a todo-list read model? An AUTOMATION is **never** exempt — if not, design and wire it now.
117
131
  2. Is its todo list opened by an internal event only, **unless it is itself a translation automation** (which is the one case a second-swimlane event may open a todo list)? If a worker automation's todo list is opened directly by another system's event, that automation is missing its translation chain — split it into translation + worker automations per the rule above.
118
132
  3. If it's a **translation** automation, does its todo list have no closing edge — i.e. no connection from its own resulting internal EVENT back to its own todo-list read model? If one exists, remove it: a translation automation's todo list is never closed.
119
- 4. If it's a **worker** automation, does its todo list have a proper closing edge from its own resulting event? If not, add it.
120
- 5. Does the todo-list read model's field set avoid a `status` flag (membership in the list is the state)?
133
+ 4. If it's a **worker** automation sitting right after a translation automation, does its own COMMAND make a genuinely new decision the internal EVENT didn't already carry? If its fields and logic just restate the internal EVENT's own data under a new name, it's a redundant stage — remove the worker automation, its todo list, and its resulting event, and have downstream consumers project a state-view READMODEL directly off the internal EVENT instead.
134
+ 5. If it's a real worker automation, does its todo list have a proper closing edge from its own resulting event? If not, add it.
135
+ 6. Does the todo-list read model's field set avoid a `status` flag (membership in the list is the state)?
121
136
 
122
137
  List the result (connected / chain-resolved) for every automation checked — this is the evidence that `eventmodeling-identifying-outputs`'s later per-node verification pass (which re-checks automations defensively) finds nothing left to do here.
123
138
 
@@ -125,7 +140,8 @@ List the result (connected / chain-resolved) for every automation checked — th
125
140
 
126
141
  - [ ] Every AUTOMATION has an incoming `READMODEL → AUTOMATION` connection to a todo-list read model — no exemption, even for a simple relay
127
142
  - [ ] No automation's todo list is opened directly by another system's (second-swimlane) EVENT unless that automation is itself the translation automation
128
- - [ ] Every externally-triggered automation is modeled as two chained automations (translation + worker), never one
143
+ - [ ] Every externally-triggered automation has a translation automation ahead of it never triggered by the external EVENT directly
144
+ - [ ] A worker automation exists after the translation stage only when it makes a genuinely new decision — not merely to keep a fixed "two automations" shape when the internal EVENT already is the business-relevant fact
129
145
  - [ ] Every **worker**-stage todo-list read model's opening and closing events are identified, including the automation's own resulting event as a closing event
130
146
  - [ ] Every **translation**-stage todo-list read model has an opening event (the external EVENT) and **no closing event at all** — no backward arrow from its own internal EVENT back to its own todo list
131
147
  - [ ] No todo-list read model uses a `status` field instead of list membership