@eventmodelers/cli 1.0.36 → 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 (71) hide show
  1. package/package.json +1 -1
  2. package/shared/skills/learn-eventmodelers-api/SKILL.md +22 -13
  3. package/stacks/modeling-kit/templates/.claude/skills/add-next-slice/SKILL.md +2 -23
  4. package/stacks/modeling-kit/templates/.claude/skills/add-next-slice/references/api-fallback.md +11 -0
  5. package/stacks/modeling-kit/templates/.claude/skills/analyze-existing-model/SKILL.md +6 -57
  6. package/stacks/modeling-kit/templates/.claude/skills/analyze-existing-model/references/api-fallback.md +68 -0
  7. package/stacks/modeling-kit/templates/.claude/skills/attributes/SKILL.md +4 -61
  8. package/stacks/modeling-kit/templates/.claude/skills/attributes/references/api-fallback.md +39 -0
  9. package/stacks/modeling-kit/templates/.claude/skills/discover-storyboard/SKILL.md +9 -53
  10. package/stacks/modeling-kit/templates/.claude/skills/discover-storyboard/references/api-fallback.md +63 -0
  11. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-applying-conways-law/SKILL.md +12 -380
  12. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-applying-conways-law/references/examples.md +329 -0
  13. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-brainstorming-events/SKILL.md +45 -290
  14. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-brainstorming-events/references/api-fallback.md +97 -0
  15. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-brainstorming-events/references/examples.md +35 -0
  16. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-checking-completeness/SKILL.md +15 -410
  17. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-checking-completeness/references/api-fallback.md +22 -0
  18. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-checking-completeness/references/examples.md +397 -0
  19. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-core-rules/SKILL.md +182 -0
  20. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-automation-chains/SKILL.md +148 -0
  21. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-automation-chains/references/api-fallback.md +21 -0
  22. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-event-models/SKILL.md +48 -448
  23. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-event-models/references/examples.md +167 -0
  24. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-elaborating-scenarios/SKILL.md +31 -380
  25. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-elaborating-scenarios/references/api-fallback.md +31 -0
  26. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-elaborating-scenarios/references/examples.md +216 -0
  27. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-inputs/SKILL.md +33 -393
  28. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-inputs/references/api-fallback.md +79 -0
  29. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-inputs/references/examples.md +282 -0
  30. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-outputs/SKILL.md +54 -454
  31. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-outputs/references/api-fallback.md +67 -0
  32. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-outputs/references/examples.md +273 -0
  33. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-interview-protocol/SKILL.md +31 -0
  34. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/SKILL.md +37 -184
  35. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/references/domain-patterns.md +58 -99
  36. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/references/patterns.md +82 -163
  37. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-orchestrating-event-modeling/SKILL.md +86 -78
  38. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-orchestrating-event-modeling/references/api-fallback.md +51 -0
  39. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-plotting-events/SKILL.md +5 -5
  40. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-plotting-events/references/api-fallback.md +10 -0
  41. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/SKILL.md +22 -51
  42. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/references/api-fallback.md +41 -0
  43. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/references/examples.md +12 -9
  44. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/references/patterns.md +1 -10
  45. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-storyboarding-events/SKILL.md +29 -382
  46. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-storyboarding-events/references/api-fallback.md +77 -0
  47. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-storyboarding-events/references/examples.md +271 -0
  48. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-translating-external-events/SKILL.md +12 -349
  49. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-translating-external-events/references/examples.md +306 -0
  50. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models/SKILL.md +69 -107
  51. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models/references/api-fallback.md +14 -0
  52. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models-checklist/SKILL.md +75 -160
  53. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models-checklist/references/api-fallback.md +14 -0
  54. package/stacks/modeling-kit/templates/.claude/skills/examples/SKILL.md +3 -110
  55. package/stacks/modeling-kit/templates/.claude/skills/examples/references/api-fallback.md +118 -0
  56. package/stacks/modeling-kit/templates/.claude/skills/handle-comment/SKILL.md +5 -25
  57. package/stacks/modeling-kit/templates/.claude/skills/handle-comment/references/api-fallback.md +35 -0
  58. package/stacks/modeling-kit/templates/.claude/skills/html-screen/SKILL.md +9 -44
  59. package/stacks/modeling-kit/templates/.claude/skills/html-screen/references/api-fallback.md +51 -0
  60. package/stacks/modeling-kit/templates/.claude/skills/place-element/SKILL.md +34 -180
  61. package/stacks/modeling-kit/templates/.claude/skills/place-element/references/api-fallback.md +203 -0
  62. package/stacks/modeling-kit/templates/.claude/skills/storyboard/SKILL.md +14 -81
  63. package/stacks/modeling-kit/templates/.claude/skills/storyboard/references/api-fallback.md +74 -0
  64. package/stacks/modeling-kit/templates/.claude/skills/storyboard-screen/SKILL.md +4 -45
  65. package/stacks/modeling-kit/templates/.claude/skills/storyboard-screen/references/api-fallback.md +44 -0
  66. package/stacks/modeling-kit/templates/.claude/skills/timeline/SKILL.md +19 -88
  67. package/stacks/modeling-kit/templates/.claude/skills/timeline/references/api-fallback.md +91 -0
  68. package/stacks/modeling-kit/templates/.claude/skills/update-prompt-status/SKILL.md +1 -9
  69. package/stacks/modeling-kit/templates/.claude/skills/update-prompt-status/references/api-fallback.md +14 -0
  70. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-integrating-legacy-systems/SKILL.md +0 -674
  71. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/references/snapshotting.md +0 -204
@@ -0,0 +1,306 @@
1
+ # Translating External Events — Worked Examples
2
+
3
+ These are conceptual worked examples of the translation reasoning this skill applies — useful for understanding the reasoning, but the actual mechanics are the numbered Workflow steps in the main SKILL.md.
4
+
5
+ ## 1. Identify External Event Sources
6
+
7
+ ```
8
+ External System: Payment Gateway (Stripe)
9
+
10
+ Events received:
11
+ - charge.succeeded
12
+ - charge.failed
13
+ - charge.refunded
14
+ - charge.dispute.created
15
+
16
+ Example payload: charge.succeeded
17
+ {
18
+ "id": "ch_1234567890",
19
+ "amount": 15000,
20
+ "currency": "usd",
21
+ "customer": "cus_9876543210",
22
+ "status": "succeeded",
23
+ "created": 1640995200
24
+ }
25
+
26
+ External System: GPS Location Service (Google Maps)
27
+
28
+ Events received:
29
+ - location_update
30
+ - geofence_enter
31
+ - geofence_exit
32
+
33
+ Example payload: geofence_exit
34
+ {
35
+ "userId": "user-123",
36
+ "geoFenceId": "hotel-front-entrance",
37
+ "timestamp": 1640995200,
38
+ "latitude": 40.7128,
39
+ "longitude": -74.0060
40
+ }
41
+ ```
42
+
43
+ ## 2. Analyze Technical Representation
44
+
45
+ ```
46
+ External Event: charge.succeeded (Stripe)
47
+
48
+ Technical fields:
49
+ - id: UUID of charge in Stripe (not meaningful to us)
50
+ - amount: Integer cents (15000 = $150.00)
51
+ - currency: ISO code ("usd")
52
+ - customer: Stripe customer ID (not our customer ID)
53
+ - status: String indicating success
54
+ - created: Unix timestamp
55
+
56
+ Problems with using directly:
57
+ We don't use Stripe customer IDs (we have our own customer IDs)
58
+ Currency and amount require interpretation
59
+ Status is one field in their model, we care about the fact it succeeded
60
+ Stripe charge ID isn't the same as our order ID
61
+ We need to correlate back to our Order stream
62
+ ```
63
+
64
+ ## 3. Define Domain Translation Rules
65
+
66
+ ```
67
+ Translation: External charge.succeeded → Domain PaymentAuthorized
68
+
69
+ Mapping rules:
70
+ charge.id (Stripe) → paymentGatewayRef (store for reconciliation, don't use as primary)
71
+ charge.customer (Stripe) → Look up: Which of OUR customers has this Stripe ID?
72
+ charge.amount → paymentAmount (convert from cents)
73
+ charge.currency → paymentCurrency
74
+ created → timestamp
75
+ [NEED TO FIND] → orderId (Stripe doesn't tell us! This is critical—how do we know which order?)
76
+
77
+ Problem identified:
78
+ Stripe webhook comes with charge details but NOT our order ID.
79
+
80
+ Solutions:
81
+ A. Store Stripe charge ID in our Order when we initiate payment
82
+ When webhook arrives: charge.id → Look up in OrderPaymentReference
83
+ Find orderId → Create PaymentAuthorized event
84
+
85
+ B. Store custom metadata in Stripe charge
86
+ When creating charge: Include our orderId in metadata
87
+ When webhook arrives: Extract orderId from metadata
88
+
89
+ Choose A or B based on Stripe integration approach.
90
+ ```
91
+
92
+ ## 4. Handle Correlation
93
+
94
+ ```
95
+ Pattern: Correlation via Reference Tracking
96
+
97
+ Our system flow:
98
+ 1. Order created in our system: order-123
99
+ 2. We initiate payment with Stripe:
100
+ - Send amount, customer info
101
+ - Receive charge ID: ch_1234567890
102
+ - Store reference: OrderPaymentReference { orderId: order-123, stripeChargeId: ch_1234567890 }
103
+
104
+ When webhook arrives:
105
+ 1. Webhook: charge.succeeded { id: ch_1234567890, amount: 15000, ... }
106
+ 2. Look up: Find OrderPaymentReference where stripeChargeId = ch_1234567890
107
+ 3. Get orderId from reference
108
+ 4. Create PaymentAuthorized event: { orderId: order-123, amount: 150.00, ... }
109
+
110
+ Key insight: You must create the correlation bridge when initiating external action.
111
+ ```
112
+
113
+ ## 5. Define Translation Scenarios
114
+
115
+ ```
116
+ External Event: charge.succeeded
117
+ Trigger: Stripe webhook arrives with charge details
118
+ Precondition: OrderPaymentReference exists for this charge ID
119
+ Translation logic:
120
+ 1. Extract charge.id from webhook
121
+ 2. Look up OrderPaymentReference.orderId
122
+ 3. Validate order exists and is in Confirmed state
123
+ 4. Create domain event: PaymentAuthorized { orderId, amount, timestamp, ... }
124
+ Success: Domain event produced
125
+ Failure scenarios:
126
+ - Charge ID not found in references → Log error, don't produce event (manual review)
127
+ - Order not in Confirmed state → Log error, don't produce event
128
+ - Duplicate webhook → Idempotent handling (check if event already exists)
129
+
130
+ --- External Event: geofence_exit
131
+ Trigger: Guest leaves hotel area (GPS geofence)
132
+ Precondition: Guest has opted in to location tracking
133
+ Translation logic:
134
+ 1. Extract userId and geoFenceId from webhook
135
+ 2. Validate guest is currently in hotel
136
+ 3. Check geofence_exit is "hotel-front-entrance" (not just any geofence)
137
+ 4. Create domain event: GuestLeftHotel { guestId: userId, timestamp, ... }
138
+ Success: Domain event produced
139
+ Failure scenarios:
140
+ - Guest hasn't opted in → Don't produce event (respect privacy)
141
+ - Guest not checked in → Don't produce event (shouldn't be in geofence)
142
+ - Unknown geofence → Log error, don't produce event
143
+ ```
144
+
145
+ ## 6. Handle Duplicates and Ordering
146
+
147
+ ```
148
+ Problem: Stripe retries charge.succeeded webhook
149
+ Webhook 1: charge.succeeded { id: ch_123 } → Arrives at 10:00 AM
150
+ Webhook 2: charge.succeeded { id: ch_123 } → Arrives at 10:05 AM (retry)
151
+
152
+ Solution: Idempotent translation
153
+
154
+ Check before creating event:
155
+ 1. Extract external ID: ch_123
156
+ 2. Query: Does PaymentAuthorized event exist with paymentGatewayRef = ch_123?
157
+ 3. If yes: Do nothing (already processed)
158
+ 4. If no: Create event
159
+
160
+ This requires storing the external ID in the event:
161
+ PaymentAuthorized event {
162
+ orderId: order-123,
163
+ amount: 150.00,
164
+ paymentGatewayRef: ch_123, ← Store external ID for deduplication
165
+ ...
166
+ }
167
+ ```
168
+
169
+ ## 7. Handle Partial or Missing Information
170
+
171
+ ```
172
+ External Event: geofence_exit
173
+
174
+ Available data:
175
+ - userId
176
+ - geoFenceId
177
+ - timestamp
178
+ - latitude, longitude (raw GPS)
179
+
180
+ Missing data:
181
+ - Guest name (not in webhook payload)
182
+ - Reason for leaving (not tracked)
183
+ - Expected return time (not available)
184
+
185
+ Handling strategy:
186
+ A. Translation enriches from our system:
187
+ Domain event: GuestLeftHotel {
188
+ guestId: userId, ← From webhook
189
+ timestamp: ..., ← From webhook
190
+ guestName: "John Smith", ← Looked up from guest stream
191
+ roomNumber: "502", ← Looked up from guest stream
192
+ geoFenceId: "front-entrance" ← From webhook
193
+ }
194
+
195
+ B. Some data we don't need:
196
+ We ignore: latitude, longitude (we just care that guest left)
197
+
198
+ C. Some data we can infer:
199
+ We can assume: Guest is now outside hotel
200
+ Cleaning crew can visit room
201
+ ```
202
+
203
+ ## Legacy markdown structure (superseded — kept for reference only)
204
+
205
+ Older versions of this skill wrote the translation analysis as a standalone markdown document. The actual output mechanism today is placing each translated domain event on the board (see "Output Format" in the main SKILL.md) — this template is kept only so the shape of the information (what a complete translation write-up covers) stays documented somewhere.
206
+
207
+ ````markdown
208
+ # External Event Translation: [Domain Name]
209
+
210
+ ## External Systems & Events
211
+
212
+ ### System: [External System Name]
213
+
214
+ **Connection Type**: [Webhook/API polling/WebSocket/Streaming]
215
+
216
+ **Events Received**:
217
+ - event1_name
218
+ - event2_name
219
+ - event3_name
220
+
221
+ ---
222
+
223
+ ## Translation Rules
224
+
225
+ ### External Event: [Event Name]
226
+
227
+ **Source System**: [System name]
228
+
229
+ **Technical Representation**:
230
+ ```json
231
+ {
232
+ "field1": "value",
233
+ "field2": "value"
234
+ }
235
+ ```
236
+
237
+ **Domain Translation**:
238
+ | External Field | Our Field | Mapping | Notes |
239
+ |---|---|---|---|
240
+ | externalId | n/a | Stored for deduplication | Reference only |
241
+ | customer | [lookup] | Look up our customer ID | Must correlate |
242
+
243
+ **Correlation Method**:
244
+ [How do we link back to our domain entities?]
245
+
246
+ **Domain Event Produced**:
247
+ - Event Name: [EventName]
248
+ - Fields: [List with sources]
249
+
250
+ **Translation Logic**:
251
+ ```
252
+ 1. Extract from webhook
253
+ 2. Validate preconditions
254
+ 3. Enrich from our system
255
+ 4. Create domain event
256
+ ```
257
+
258
+ **Success Scenario**:
259
+ [What success looks like]
260
+
261
+ **Failure Scenarios**:
262
+ - Scenario 1: Consequence
263
+ - Scenario 2: Consequence
264
+
265
+ **Duplicate Handling**: [Idempotent strategy]
266
+
267
+ --- [Repeat for each external event]
268
+
269
+ ---
270
+
271
+ ## Correlation Reference
272
+
273
+ Track how external IDs map to our domain:
274
+
275
+ | Our Entity | External System | External ID Field | Storage | Lookup |
276
+ |---|---|---|---|---|
277
+ | Order | Stripe | charge.id | OrderPaymentReference | By charge ID |
278
+ | Guest | GPS Service | userId | Guest stream | By userId |
279
+
280
+ ---
281
+
282
+ ## Failure & Recovery
283
+
284
+ ### Webhook Arrives for Non-existent Order
285
+ **Symptom**: Stripe sends charge.succeeded for unknown order
286
+ **Cause**: Race condition or data inconsistency
287
+ **Detection**: OrderPaymentReference lookup returns nothing
288
+ **Recovery**: Log error, queue for manual review
289
+
290
+ ### Duplicate Webhooks
291
+ **Symptom**: Same webhook received multiple times
292
+ **Cause**: Stripe retry mechanism or network duplication
293
+ **Detection**: Domain event already exists with same externalRef
294
+ **Recovery**: Idempotent check prevents duplicate event creation
295
+
296
+ ---
297
+
298
+ ## Testing Recommendations
299
+
300
+ - [ ] Test happy path: External event → Correct domain event
301
+ - [ ] Test missing correlation: External event arrives before our order created
302
+ - [ ] Test duplicate: Same webhook processed twice
303
+ - [ ] Test invalid data: Webhook with missing required fields
304
+ - [ ] Test partial data: Webhook with some fields missing
305
+ - [ ] Test ordering: Multiple webhooks arrive out of order
306
+ ````
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: eventmodeling-validating-event-models
3
- description: "Step 9 of Event Modeling - Validate event-sourced models for completeness, consistency, and event sourcing principles. Ensures events are immutable facts, state projections are deterministic, and commands are pure. Identifies gaps and suggests improvements before code generation. Use when reviewing models before code generation. Do not use for: the structured 23-check production checklist (use eventmodeling-validating-event-models-checklist) or field-level completeness verification (use eventmodeling-checking-completeness)."
3
+ description: "Step 9 of Event Modeling - Validate the model for completeness and consistency. Ensures events are immutable facts, read models are deterministic projections, and commands are traceable decisions. Identifies gaps before the model is declared done. Use when reviewing a model before it's considered final. Do not use for: the structured 12-check checklist (use eventmodeling-validating-event-models-checklist) or field-level completeness verification (use eventmodeling-checking-completeness)."
4
4
  allowed-tools:
5
5
  - Write
6
6
  - Bash
@@ -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
  For validation you treat the Event Model as read only. The only thing you are allowed to change is comments.
@@ -33,32 +35,34 @@ mcp__eventmodelers__get_nodes { "boardId": "$BOARD_ID", "type": "COMMAND" }
33
35
  mcp__eventmodelers__get_nodes { "boardId": "$BOARD_ID", "type": "READMODEL" }
34
36
  ```
35
37
 
36
- **Fallback (no MCP):**
37
-
38
- ```bash
39
- curl -s -H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" \
40
- "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?type=EVENT"
41
- curl -s -H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" \
42
- "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?type=COMMAND"
43
- curl -s -H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" \
44
- "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?type=READMODEL"
45
- ```
38
+ **Fallback (no MCP):** see `references/api-fallback.md` — "Board Context".
46
39
 
47
40
  After validation, use the `handle-comment` skill to post findings on the relevant nodes — `TASK` for critical violations that must be fixed, `QUESTION` for warnings and recommendations. (That skill already handles the `add_comment` MCP-vs-curl choice internally — no separate rewrite needed here.)
48
41
 
49
42
  ## Purpose
50
- Ensures event-sourced models are complete, correct, and follow pure event sourcing principles (minimal per-command state).
43
+
44
+ Ensures the event model is complete, correct, and internally consistent.
51
45
 
52
46
  ## Workflow
53
47
 
54
48
  When given an event model, perform comprehensive validation:
55
49
 
56
- ### 1. Swimlane Completeness Check
50
+ ### 0. Automated structural pass — run `validate_model` first
51
+
52
+ Before the manual checks below, run the server-side checklist once per chapter:
57
53
 
58
- Verify each swimlane has:
54
+ ```
55
+ mcp__eventmodelers__validate_model { "boardId": "$BOARD_ID", "chapterId": "<chapterId>" }
56
+ ```
57
+
58
+ It returns a compact `findings` list (no node dumps) covering: unplaced nodes, backward arrows among the forward-only pairs (with the todo-list `EVENT → READMODEL` exception already applied), COMMANDs with zero or multiple issuers, READMODELs with no inbound EVENT, columns with more than one screen, and COMMAND/READMODEL columns with no SCENARIO. This replaces the per-type `get_nodes` scans and the `get_node` `projection: "edges"` spot-checks those manual checks would otherwise need — start from its `findings`, then use the sections below for the semantic checks it can't make (naming, immutability, field-source traceability, scenario coverage depth). A `verdict` of `PASS` on `validate_model` is necessary but not sufficient — still do the semantic pass.
59
+
60
+ ### 1. Entity/Timeline Completeness Check
61
+
62
+ Verify each entity's timeline has:
59
63
  - Clear name (identity)
60
64
  - At least one event type
61
- - Initial event (what creates the stream)
65
+ - An initial event (what starts the entity's story)
62
66
  - State transitions documented
63
67
 
64
68
  **For each event:**
@@ -67,142 +71,115 @@ Verify each swimlane has:
67
71
  - All data is **immutable**
68
72
  - Unique semantics (no duplicates)
69
73
 
70
- **For each state projection:**
71
- - Can be deterministically rebuilt from events
72
- - Replay logic is pure (no side effects)
74
+ **For each read model:**
75
+ - Can be deterministically derived from events
76
+ - No side effects in how it's built
73
77
 
74
78
  **For each command:**
75
79
  - Clear input parameters
76
- - Validation rules defined in scenarios (against state)
80
+ - Preconditions defined in scenarios
77
81
  - Resulting events specified (or rejection reason)
78
- - Pure logic (no side effects except event appending)
79
82
 
80
83
  ### 2. Consistency Checks
81
84
 
82
- - [ ] **Event-Stream Mapping**: Every event belongs to exactly one lane
85
+ - [ ] **Event-Entity Mapping**: Every event belongs to exactly one lane/entity
83
86
  - [ ] **Single Command Issuer**: Every command is issued by exactly one SCREEN or AUTOMATION — never two. Check each COMMAND node's inbound edges; more than one SCREEN/AUTOMATION wired into the same command is a CRITICAL violation (commonly an auto-connect artifact — see `place-element` Step 7c)
84
- - [ ] **Command Outcomes**: Every command produces events OR documents rejection
85
- - [ ] **Deterministic Projections**: State can only be derived one way from events
86
- - [ ] **No Side Effects in Projections**: Pure state reconstruction logic
87
+ - [ ] **Command Outcomes**: Every command produces events OR documents a rejection
88
+ - [ ] **Deterministic Read Models**: A read model can only be derived one way from its events
87
89
  - [ ] **Event Immutability**: No event data is ever modified
88
90
  - [ ] **Naming Consistency**: Are naming patterns consistent?
89
- - Commands: Verb present (CreateOrder, ConfirmPayment)
90
- - Events: Verb past tense (OrderCreated, PaymentConfirmed)
91
-
92
- ### 3. Event Sourcing Principles Compliance
91
+ - Commands: present-tense verb (CreateOrder, ConfirmPayment)
92
+ - Events: past-tense verb (OrderCreated, PaymentConfirmed)
93
93
 
94
- Check against event sourcing fundamentals:
94
+ ### 3. Event Modeling Principles Compliance
95
95
 
96
- - [ ] **Events are Facts**: Events describe what happened, not potential futures
96
+ - [ ] **Events are Facts**: describe what happened, not potential futures
97
97
  - "OrderMayBeConfirmed" → "OrderConfirmed"
98
- - "PaymentPending" (in events) → "PaymentInitiated", "PaymentAuthorized"
98
+ - "PaymentPending" (as an event) → "PaymentInitiated", "PaymentAuthorized"
99
99
 
100
- - [ ] **Events are Immutable**: No modification of event data
100
+ - [ ] **Events are Immutable**: no modification of event data
101
101
  - "Update OrderCreated event with new total" → "Append OrderTotalCorrected event"
102
102
 
103
- - [ ] **Complete Event Data**: Events contain all facts needed for state rebuild
104
- - Event: "OrderConfirmed" (missing paymentId) → Event includes paymentId
103
+ - [ ] **Complete Event Data**: events contain all facts a read model needs to project them
104
+ - Event "OrderConfirmed" missing paymentId → Event includes paymentId
105
105
 
106
- - [ ] **No Computed Fields in Events**: Only raw captured facts
107
- - OrderCreated includes "totalTax" (computed) → Includes items + amounts, tax computed in projection
106
+ - [ ] **No Computed Fields in Events**: only raw captured facts
107
+ - OrderCreated includes "totalTax" (computed) → Includes items + amounts; tax computed in the read model
108
108
 
109
- - [ ] **Deterministic Projections**: Replaying events always produces same state
110
- - Projection uses: for each event, do X
111
- - Projection uses: external API call during replay
112
-
113
- - [ ] **State is Derived**: Current state always comes from replaying events
114
- - "Load state: replay all events for Order:123"
115
- - "Load state: query database Orders table"
109
+ - [ ] **Deterministic Read Models**: replaying the same events always produces the same read model
116
110
 
117
111
  ### 4. Event Flow Validation
118
112
 
119
- - [ ] **Command → Event Mapping**: Clear what each command produces
120
- - [ ] **No Zombie Commands**: Commands that never produce events (read-only OK)
113
+ - [ ] **Command → Event Mapping**: clear what each command produces
114
+ - [ ] **No Zombie Commands**: commands that never produce events (read-only commands are fine if documented as such)
121
115
 
122
116
  ### 5. Role & Actor Attribution Validation
123
117
 
124
118
  Verify that every command has explicit actor attribution from the Role Catalog:
125
119
 
126
- - [ ] **Role Catalog exists**: A Role Catalog was defined in Step 1 (eventmodeling-brainstorming-events)
127
- - CRITICAL: No Role Catalog found — commands have no actor attribution
120
+ - [ ] **Role Catalog exists**: a Role Catalog was defined in Step 1 (eventmodeling-brainstorming-events)
121
+ - CRITICAL: no Role Catalog found — commands have no actor attribution
128
122
  - PASS: Role Catalog with human roles and system actors defined
129
123
 
130
- - [ ] **Every command has actor attribution**: No command uses generic "User"
124
+ - [ ] **Every command has actor attribution**: no command uses generic "User"
131
125
  - CRITICAL: `CreateOrder` attributed to "User" (which user? Customer? Admin? Seller?)
132
126
  - PASS: `CreateOrder` attributed to "Customer" (specific role from catalog)
133
127
 
134
- ### 6. Command State Read Models Validation (CRITICAL)
135
-
136
- **This is the PRIMARY validation gate. Violations are CRITICAL and must be fixed before approval.** Validate that **command state read models** are **minimal and command-specific**, not bundled like DDD aggregates.
137
-
138
- ### 7. Command & State Validation
128
+ ### 6. Command Validation
139
129
 
140
- - [ ] **State-Based Decisions**: Commands decide based on current state only
141
- - [ ] **Valid State Transitions**: Document what state changes are allowed
130
+ - [ ] **Preconditions Clear**: when can each command execute?
131
+ - "Can only confirm if state is Draft"
132
+ - "Can sometimes confirm"
133
+ - [ ] **Rejection Handling**: what happens if a precondition fails?
134
+ - "Reject, no events appended"
135
+ - "Append a rejection/failure event and continue" (if that's the modeled outcome)
136
+ - [ ] **Valid State Transitions**: document what state changes are allowed
142
137
  ```text
143
138
  Draft → Confirmed (ConfirmOrder)
144
139
  Draft → Cancelled (CancelOrder)
145
140
  Confirmed → Shipped (ShipOrder)
146
141
  Confirmed ↛ Draft (invalid)
147
142
  ```
148
- - [ ] **Preconditions Clear**: When can each command execute?
149
- - "Can only confirm if state is Draft"
150
- - "Can sometimes confirm"
151
- - [ ] **Error Handling**: What happens if validation fails?
152
- - "Reject with ValidationError, no events appended"
153
- - "Append ErrorEvent and continue"
154
143
 
155
- ### 8. Projection Validation
144
+ ### 7. Read Model Validation
156
145
 
157
- - [ ] **Read Models**: Read models are rich projections
158
- - [ ] **Read Models Optional**: Are they needed or just convenience?
159
- - [ ] **Regenerable**: Can be rebuilt from events at any time
146
+ - [ ] **Read Models**: are rich projections shaped for their query
147
+ - [ ] **Read Models Optional**: are they needed, or just convenience?
148
+ - [ ] **Regenerable**: could be rebuilt from events at any time
160
149
 
161
- ### 9. Issues & Recommendations Report
150
+ ### 8. Issues & Recommendations Report
162
151
 
163
152
  Format findings as comments:
164
153
 
165
154
  ```markdown
166
-
167
155
  ## Validation Summary
168
156
 
169
157
  **Overall Status**: Ready with recommendations
170
158
 
171
- **Blockers for Implementation**: 0 critical issues
159
+ **Blockers**: 0 critical issues
172
160
 
173
161
  **Recommended Fixes**:
174
162
  1. Add missing OrderCancelled event
175
- 2. Move PaymentMethod to its own minimal state projection
176
- 3. Document all implicit invariants explicitly
177
-
178
- **Ready for Code Generation**: Yes, after implementing recommendations
163
+ 2. Document all implicit preconditions explicitly
179
164
 
180
165
  ## Next Steps
181
166
  1. Review recommendations with domain expert
182
167
  2. Update model with critical fixes
183
- 3. Proceed to code generation
184
168
  ```
185
169
 
186
170
  ## Common Issues to Flag
187
171
 
188
172
  | Issue | Pattern | Fix |
189
173
  |-------|---------|-----|
190
- | Missing cancellation flows | No "Cancelled" events | Add compensation paths |
191
- | Implicit invariants | "Obviously can't do X" | Make invariants explicit |
192
- | Command state too broad | Shared state used by 2+ commands | Split into per-command minimal state projections |
193
- | Orphaned events | Events no one listens to | Link to projections or commands |
194
- | No read models | Commands reading query/read models for validation | Add separate query read models; keep command state minimal |
195
- | Circular dependencies | Projection A depends on B, B on A | Redesign stream boundaries |
174
+ | Missing cancellation flows | No "Cancelled" events | Add the missing outcome slices |
175
+ | Implicit preconditions | "Obviously can't do X" | Make preconditions explicit |
176
+ | Orphaned events | Events no one reads | Link to a read model or command |
177
+ | No read models | Commands validated against raw event replay with no documented read model | Add a read model documenting what the command actually reads |
196
178
  | Command issued by multiple things | COMMAND node has 2+ inbound SCREEN/AUTOMATION edges | Keep the deliberate same-column issuer, remove the rest via `set_connection` (`action: "remove"`) — see `place-element` Step 7c |
197
179
 
198
- ## Key Principles for Event Sourcing
180
+ ## Key Principles
199
181
 
200
- 1. **Events are the source of truth**: Everything else is derived from them
201
- 2. **Immutable event log**: Events never change, only appended
202
- 3. **State is a projection**: Current state is built by replaying events
203
- 4. **Commands are pure decisions**: Validate against state, produce events or reject
204
- 5. **Projections are optional**: Can be rebuilt at any time
205
- 6. **Stream per entity**: Each entity has one append-only event stream
182
+ See `eventmodeling-core-rules` for the element definitions this validation checks against (events as immutable facts, read models as optional projections, commands as decisions against documented preconditions).
206
183
 
207
184
  ## Success Criteria
208
185
 
@@ -210,39 +187,24 @@ Your event model validation is successful when:
210
187
 
211
188
  - All requirements are captured in events
212
189
  - Commands clearly trigger events
213
- - Stream roots have clear, minimal boundaries
214
- - Business rules are explicit invariants (not hidden assumptions)
215
- - Read models serve actual query needs (not used by commands)
216
- - Command state is minimal and command-specific (not shared across multiple commands)
190
+ - Business rules are explicit preconditions (not hidden assumptions)
191
+ - Read models serve actual query needs
217
192
  - Events are immutable facts (past tense, no computed fields)
218
- - State can be deterministically rebuilt from events
219
193
  - All command-to-event mappings are documented
220
194
  - Critical issues are resolved or documented as known limitations
221
-
222
- A model is **ready for code generation** if:
223
- - No critical issues remain
224
- - All command state follows naming convention (e.g., `[CommandName]State`)
225
- - No state is shared between different commands
226
- - All events are immutable facts
227
- - All business rules are explicit
228
- - A Role Catalog exists with all human roles and system actors
229
- - Every command has explicit actor attribution from the Role Catalog
195
+ - A Role Catalog exists with all human roles and system actors, and every command has explicit actor attribution
230
196
 
231
197
  ## Quality Checklist
232
198
 
233
199
  - [ ] All events are immutable facts (past tense)
234
200
  - [ ] No computed fields stored in events
235
- - [ ] State projection is deterministic from events
236
- - [ ] Commands validate against current state only
201
+ - [ ] Read models are derived deterministically from events
202
+ - [ ] Commands are checked against documented preconditions
237
203
  - [ ] Each command either produces events or rejects (no silent failures)
238
204
  - [ ] **No command has more than one inbound SCREEN/AUTOMATION edge (a command is never issued by more than one thing)**
239
205
  - [ ] Event causality/command-event mapping is clear
240
206
  - [ ] State transitions are documented
241
- - [ ] No direct references between lanes
242
- - [ ] Projections serve specific query needs (or are removed)
243
- - [ ] Everything can be rebuilt from the event stream
244
- - [ ] No state is shared between different commands
245
- - [ ] All command state is minimal (only fields needed for validation)
207
+ - [ ] Read models serve specific query needs (or are removed)
246
208
  - [ ] **Role Catalog exists with human roles and system actors**
247
209
  - [ ] **Every command attributed to a specific role/actor (no generic "User")**
248
210
  - [ ] **Every human role has at least one command and one read model**
@@ -0,0 +1,14 @@
1
+ # Validating Event Models — curl Fallback Calls
2
+
3
+ Only needed when MCP is not connected. Every call below has an MCP equivalent in the main SKILL.md — always prefer that.
4
+
5
+ ## Board Context
6
+
7
+ ```bash
8
+ curl -s -H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" \
9
+ "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?type=EVENT"
10
+ curl -s -H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" \
11
+ "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?type=COMMAND"
12
+ curl -s -H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" \
13
+ "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?type=READMODEL"
14
+ ```