@eventmodelers/cli 1.0.36 → 1.0.37

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 (69) hide show
  1. package/package.json +1 -1
  2. package/shared/skills/learn-eventmodelers-api/SKILL.md +12 -10
  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 +9 -319
  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 +23 -199
  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 +13 -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-designing-automation-chains/SKILL.md +132 -0
  20. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-automation-chains/references/api-fallback.md +21 -0
  21. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-event-models/SKILL.md +9 -236
  22. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-event-models/references/examples.md +257 -0
  23. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-elaborating-scenarios/SKILL.md +28 -302
  24. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-elaborating-scenarios/references/api-fallback.md +31 -0
  25. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-elaborating-scenarios/references/examples.md +216 -0
  26. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-inputs/SKILL.md +30 -343
  27. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-inputs/references/api-fallback.md +79 -0
  28. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-inputs/references/examples.md +282 -0
  29. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-outputs/SKILL.md +51 -400
  30. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-outputs/references/api-fallback.md +67 -0
  31. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-outputs/references/examples.md +273 -0
  32. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/SKILL.md +45 -152
  33. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/references/domain-patterns.md +49 -90
  34. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/references/patterns.md +64 -137
  35. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-orchestrating-event-modeling/SKILL.md +74 -65
  36. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-orchestrating-event-modeling/references/api-fallback.md +51 -0
  37. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-plotting-events/SKILL.md +1 -5
  38. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-plotting-events/references/api-fallback.md +10 -0
  39. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/SKILL.md +19 -36
  40. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/references/api-fallback.md +41 -0
  41. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/references/examples.md +12 -9
  42. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/references/patterns.md +1 -10
  43. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-storyboarding-events/SKILL.md +26 -332
  44. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-storyboarding-events/references/api-fallback.md +77 -0
  45. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-storyboarding-events/references/examples.md +271 -0
  46. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-translating-external-events/SKILL.md +9 -294
  47. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-translating-external-events/references/examples.md +306 -0
  48. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models/SKILL.md +12 -11
  49. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models/references/api-fallback.md +14 -0
  50. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models-checklist/SKILL.md +6 -36
  51. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models-checklist/references/api-fallback.md +14 -0
  52. package/stacks/modeling-kit/templates/.claude/skills/examples/SKILL.md +3 -110
  53. package/stacks/modeling-kit/templates/.claude/skills/examples/references/api-fallback.md +118 -0
  54. package/stacks/modeling-kit/templates/.claude/skills/handle-comment/SKILL.md +5 -25
  55. package/stacks/modeling-kit/templates/.claude/skills/handle-comment/references/api-fallback.md +35 -0
  56. package/stacks/modeling-kit/templates/.claude/skills/html-screen/SKILL.md +9 -44
  57. package/stacks/modeling-kit/templates/.claude/skills/html-screen/references/api-fallback.md +51 -0
  58. package/stacks/modeling-kit/templates/.claude/skills/place-element/SKILL.md +23 -183
  59. package/stacks/modeling-kit/templates/.claude/skills/place-element/references/api-fallback.md +193 -0
  60. package/stacks/modeling-kit/templates/.claude/skills/storyboard/SKILL.md +14 -81
  61. package/stacks/modeling-kit/templates/.claude/skills/storyboard/references/api-fallback.md +74 -0
  62. package/stacks/modeling-kit/templates/.claude/skills/storyboard-screen/SKILL.md +4 -45
  63. package/stacks/modeling-kit/templates/.claude/skills/storyboard-screen/references/api-fallback.md +44 -0
  64. package/stacks/modeling-kit/templates/.claude/skills/timeline/SKILL.md +19 -88
  65. package/stacks/modeling-kit/templates/.claude/skills/timeline/references/api-fallback.md +91 -0
  66. package/stacks/modeling-kit/templates/.claude/skills/update-prompt-status/SKILL.md +1 -9
  67. package/stacks/modeling-kit/templates/.claude/skills/update-prompt-status/references/api-fallback.md +14 -0
  68. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-integrating-legacy-systems/SKILL.md +0 -674
  69. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/references/snapshotting.md +0 -204
@@ -0,0 +1,397 @@
1
+ # Checking Completeness — Worked Examples
2
+
3
+ These are conceptual worked examples (Order/Payment domain) illustrating the completeness-check reasoning this skill applies — useful for understanding the reasoning, but the actual mechanics live in the numbered Workflow sections of the main SKILL.md (reading board state and posting `TASK`/`QUESTION` comments via `handle-comment`), not in writing a document like this.
4
+
5
+ ## 1. Field Origin & Destination Matrix
6
+
7
+ ```text
8
+ Event: OrderCreated
9
+
10
+ Field: orderId
11
+ Origin: Generated by system (UUID)
12
+ Destinations:
13
+ OrderConfirmed event (references)
14
+ OrderStatusView (displays)
15
+ OrderListView (displays)
16
+ OrderShipped event (references)
17
+ Status: Complete
18
+
19
+ Field: customerId
20
+ Origin: CreateOrder command (from UI)
21
+ Destinations:
22
+ OrderStatusView (displays)
23
+ OrderListView (displays)
24
+ Inventory System (knows who ordered)
25
+ Status: Complete
26
+
27
+ Field: items[]
28
+ Origin: CreateOrder command (user selects)
29
+ Destinations:
30
+ OrderStatusView (displays)
31
+ Inventory System (what to reserve)
32
+ Fulfillment System (what to ship)
33
+ Status: Complete
34
+
35
+ Field: total
36
+ Origin: Calculated from items[] and unit prices
37
+ Destinations:
38
+ OrderStatusView (displays)
39
+ OrderListView (displays)
40
+ PaymentSystem (amount to charge)
41
+ Accounting (for reconciliation)
42
+ Status: Complete
43
+
44
+ Field: shippingAddress
45
+ Origin: CreateOrder command (user enters)
46
+ Destinations:
47
+ OrderStatusView (displays)
48
+ Fulfillment System (where to ship)
49
+ Carrier (delivery address)
50
+ Status: Complete
51
+
52
+ Field: createdAt
53
+ Origin: System timestamp when event created
54
+ Destinations:
55
+ OrderStatusView (displays)
56
+ OrderListView (displays)
57
+ Metrics (average order age)
58
+ Status: Complete
59
+ ```
60
+
61
+ ## 2. Check All Commands
62
+
63
+ ```text
64
+ Command: CreateOrder
65
+ Input: customerId, items[], shippingAddress
66
+ customerId → OrderCreated.customerId
67
+ items[] → OrderCreated.items
68
+ shippingAddress → OrderCreated.shippingAddress
69
+ Status: All inputs captured
70
+
71
+ Command: ConfirmOrder
72
+ Input: orderId, paymentMethod
73
+ orderId → OrderConfirmed.orderId (implicit)
74
+ paymentMethod → OrderConfirmed.paymentMethod
75
+ Status: All inputs captured
76
+
77
+ Command: AuthorizePayment
78
+ Input: orderId, paymentId, authCode
79
+ orderId → PaymentAuthorized.orderId (implicit)
80
+ paymentId → PaymentAuthorized.paymentId
81
+ authCode → PaymentAuthorized.authCode
82
+ Status: All inputs captured
83
+ ```
84
+
85
+ ## 3. Check All Read Models
86
+
87
+ ```text
88
+ ReadModel: OrderStatusView
89
+ Needs to display:
90
+ orderId ← OrderCreated
91
+ customerId ← OrderCreated
92
+ status ← OrderConfirmed, PaymentAuthorized, etc.
93
+ items ← OrderCreated
94
+ total ← OrderCreated
95
+ createdAt ← OrderCreated
96
+ confirmedAt ← OrderConfirmed
97
+ paymentId ← PaymentAuthorized
98
+ paymentMethod ← OrderConfirmed
99
+ shipmentId ← OrderShipped
100
+ trackingNumber ← OrderShipped
101
+ Status: All fields sourced
102
+
103
+ ReadModel: OrderListView
104
+ Needs to display:
105
+ orderId ← OrderCreated
106
+ customerId ← OrderCreated
107
+ total ← OrderCreated
108
+ status ← OrderConfirmed, OrderCancelled, etc.
109
+ createdAt ← OrderCreated
110
+ Status: All fields sourced
111
+ ```
112
+
113
+ ## 4. Check Slice Coverage
114
+
115
+ ```text
116
+ Column: CreateOrder (COMMAND)
117
+ Slice defined? Yes — "Place Order"
118
+ Status: Covered
119
+
120
+ Column: OrderStatusView (READMODEL)
121
+ Slice defined? No
122
+ Status: Missing slice — flag as gap
123
+
124
+ Column: ConfirmOrder (COMMAND, linkedTo set — copy of the original in another column)
125
+ Slice defined? N/A — linked copy, exempt
126
+ Status: Skip
127
+ ```
128
+
129
+ ## 5. Check Event Stream Completeness
130
+
131
+ ```text
132
+ Scenario: Order from creation to delivery
133
+
134
+ Timeline:
135
+ 1. OrderCreated (from CreateOrder command)
136
+ 2. OrderConfirmed (from ConfirmOrder command)
137
+ 3. PaymentAuthorized (from AuthorizePayment processor command)
138
+ 4. InventoryReserved (from ReserveInventory processor command)
139
+ 5. OrderShipped (from CreateShipment processor command)
140
+ 6. DeliveryConfirmed (from MarkDelivered processor command)
141
+
142
+ Missing events? None identified
143
+
144
+ Alternative paths:
145
+ - OrderCancelled (can happen after OrderCreated or OrderConfirmed)
146
+ - PaymentFailed (can happen during PaymentAuthorized)
147
+ - RefundInitiated (can happen after PaymentFailed or OrderCancelled)
148
+
149
+ Status: All paths covered
150
+ ```
151
+
152
+ ## 6. Check System Boundaries
153
+
154
+ ```text
155
+ Order System
156
+ Events: OrderCreated, OrderConfirmed, OrderCancelled
157
+ Processor: None (triggers other systems)
158
+ Status: Clean ownership
159
+
160
+ Payment System
161
+ Events: PaymentAuthorized, PaymentFailed, PaymentRefunded
162
+ Processor: PaymentAuthorizer (listens to OrderConfirmed)
163
+ Status: Clean ownership
164
+
165
+ Inventory System
166
+ Events: InventoryReserved, InventoryReleased
167
+ Processor: InventoryReserver (listens to PaymentAuthorized)
168
+ Status: Clean ownership
169
+
170
+ Fulfillment System
171
+ Events: OrderShipped, DeliveryConfirmed
172
+ Processor: ShipmentCreator (listens to InventoryReserved)
173
+ Status: Clean ownership
174
+
175
+ Notification System
176
+ Events: None (no persistence, info-only)
177
+ Processor: Notifier (listens to all events)
178
+ Status: Cross-cutting concern
179
+ ```
180
+
181
+ ## 7. Define Workflow Step Contracts
182
+
183
+ ```text
184
+ Workflow Step 1: CreateOrder (Step Owns: Order Creation)
185
+
186
+ Preconditions (what must exist before this step):
187
+ - Customer must exist
188
+ - Products must exist in catalog
189
+ - User must be authenticated
190
+
191
+ Postconditions (what exists after this step):
192
+ - OrderCreated event exists
193
+ - Event contains: orderId, customerId, items, total, shippingAddress, createdAt
194
+
195
+ Contract: Any system can assume if these postconditions are true,
196
+ the order has been properly created through this step.
197
+
198
+ --- Workflow Step 2: ConfirmOrder (Step Owns: Order Confirmation)
199
+
200
+ Preconditions (depends on Step 1 postcondition):
201
+ - OrderCreated event must exist ( from Step 1 contract)
202
+ - Customer must select payment method
203
+
204
+ Postconditions (what exists after this step):
205
+ - OrderConfirmed event exists
206
+ - Event contains: orderId, paymentMethod, confirmedAt
207
+
208
+ Contract: Any system can assume if these postconditions are true,
209
+ the order has been properly confirmed.
210
+
211
+ --- Workflow Step 3: AuthorizePayment (Step Owns: Payment Authorization)
212
+
213
+ Preconditions (depends on Step 2 postcondition):
214
+ - OrderConfirmed event must exist ( from Step 2 contract)
215
+ - Payment method must be valid
216
+
217
+ Postconditions (what exists after this step):
218
+ - PaymentAuthorized event exists
219
+ - Event contains: paymentId, authCode, amount
220
+
221
+ Contract: Once this postcondition is true, next steps can proceed
222
+ without re-checking payment (trust the contract).
223
+ ```
224
+
225
+ ## 8. Check Field Traceability
226
+
227
+ ```markdown
228
+ | Field | Event | Command | Read Model | Processor |
229
+ |-------|-------|---------|-----------|-----------|
230
+ | orderId | OrderCreated | - | All views | All |
231
+ | customerId | OrderCreated | CreateOrder | OrderStatusView | - |
232
+ | items | OrderCreated | CreateOrder | List/Status views | Inventory |
233
+ | total | OrderCreated | - | List/Status views | - |
234
+ | paymentId | PaymentAuthorized | AuthorizePayment | StatusView | Inventory |
235
+ | shipmentId | OrderShipped | CreateShipment | StatusView | Notification |
236
+ | trackingNumber | OrderShipped | - | TrackingView | Notification |
237
+
238
+ Status: All fields traceable
239
+ ```
240
+
241
+ ## 9. Identify Gaps
242
+
243
+ ```text
244
+ Analysis: Are there any missing fields?
245
+ - Estimated delivery date?
246
+ → Need to add to OrderShipped event
247
+ → Can be calculated from carrier
248
+ → Add to ShipmentTrackingView
249
+
250
+ - Cancellation reason?
251
+ → Already in OrderCancelled event
252
+
253
+ - Payment failure reason?
254
+ → Already in PaymentFailed event
255
+
256
+ - Refund status?
257
+ → Need to track in RefundInitiated event
258
+ → Add to PaymentStatusView
259
+
260
+ Actions taken:
261
+ Add estimatedDelivery to OrderShipped
262
+ Add refundStatus to PaymentStatusView
263
+ Add refundInitiatedAt to OrderStatusView
264
+ ```
265
+
266
+ ## Legacy markdown-document format (superseded — kept for reference only)
267
+
268
+ Older versions of this skill wrote the completeness check as a markdown report. The actual mechanism today is reading board state and posting `TASK`/`QUESTION` comments via `handle-comment` (see "Board Context" in the main SKILL.md) — this template is kept only so the shape of the information (what a complete completeness report covers) stays documented somewhere.
269
+
270
+ ```markdown
271
+ # Completeness Check: [Domain Name]
272
+
273
+ ## Workflow Step Contracts
274
+
275
+ ### Step 1: CreateOrder
276
+
277
+ **Preconditions**:
278
+ - Customer exists in system
279
+ - Products exist in catalog
280
+
281
+ **Postconditions**:
282
+ - OrderCreated event exists with fields: [list]
283
+
284
+ **Teams that depend on this contract**: [All downstream teams]
285
+
286
+ ---
287
+
288
+ ### Step 2: ConfirmOrder
289
+
290
+ **Preconditions** (depends on Step 1):
291
+ - OrderCreated event exists
292
+
293
+ **Postconditions**:
294
+ - OrderConfirmed event exists with fields: [list]
295
+
296
+ --- [Continue for each workflow step]
297
+
298
+ ---
299
+
300
+ ## Field Traceability Matrix
301
+
302
+ ### Events
303
+
304
+ | Event | Field | Origin | Destinations | Status |
305
+ |-------|-------|--------|-------------|--------|
306
+ | OrderCreated | orderId | System | ConfirmOrder, Views | |
307
+ | OrderCreated | customerId | CreateOrder | All views | |
308
+ | OrderCreated | items | CreateOrder | Inventory, Views | |
309
+ | OrderCreated | total | Calculated | Views, Payment | |
310
+ | OrderConfirmed | paymentId | AuthorizePayment | Views, Accounting | |
311
+ | OrderShipped | trackingNumber | Carrier | TrackingView | |
312
+
313
+ ---
314
+
315
+ ## System Ownership Verification
316
+
317
+ ### Order System
318
+ - Events owned: OrderCreated, OrderConfirmed, OrderCancelled
319
+ - Completeness: All order lifecycle events present
320
+
321
+ ### Payment System
322
+ - Events owned: PaymentAuthorized, PaymentFailed, PaymentRefunded
323
+ - Completeness: All payment states covered
324
+
325
+ ---
326
+
327
+ ## Command → Event Verification
328
+
329
+ | Command | Input | Event | Captured |
330
+ |---------|-------|-------|----------|
331
+ | CreateOrder | customerId, items, address | OrderCreated | |
332
+ | ConfirmOrder | paymentMethod | OrderConfirmed | |
333
+ | AuthorizePayment | paymentId, authCode | PaymentAuthorized | |
334
+
335
+ ---
336
+
337
+ ## Slice Coverage
338
+
339
+ | Column | Node | Has Slice? | Status |
340
+ |--------|------|-----------|--------|
341
+ | 1 | CreateOrder (COMMAND) | Yes — "Place Order" | |
342
+ | 2 | OrderStatusView (READMODEL) | No | Missing slice |
343
+ | 3 | ConfirmOrder (COMMAND, linked copy) | N/A | Exempt (linkedTo set) |
344
+
345
+ ---
346
+
347
+ ## Read Model Coverage
348
+
349
+ ### OrderStatusView
350
+ - All relevant event data included
351
+ - All user display needs met
352
+ - All processor decision fields present
353
+
354
+ ### OrderListView
355
+ - Summary fields captured
356
+ - Filtering/sorting fields present
357
+ - Linked to OrderStatusView for details
358
+
359
+ ---
360
+
361
+ ## Gap Analysis
362
+
363
+ ### Issues Found
364
+ 1. Estimated delivery date missing
365
+ - Fix: Add to OrderShipped event
366
+ - Type: DateTime (ISO 8601)
367
+ - Source: Calculated from carrier API
368
+ - Status: Will add in next iteration
369
+
370
+ 2. Refund tracking incomplete
371
+ - Fix: Add RefundInitiated event timestamp
372
+ - Fix: Add refund status to PaymentStatusView
373
+ - Status: Will add in next iteration
374
+
375
+ ### No Critical Gaps
376
+ - All events properly sourced
377
+ - All command inputs captured
378
+ - All read models have data
379
+ - Event flow complete
380
+ - System boundaries clear
381
+
382
+ ---
383
+
384
+ ## Readiness Assessment
385
+
386
+ **Overall Completeness**: 95%
387
+
388
+ **Blockers**: None
389
+
390
+ **Ready for Code Generation**: YES
391
+
392
+ **Minor Improvements**:
393
+ - Add estimated delivery date (non-blocking)
394
+ - Enhance refund tracking (non-blocking)
395
+
396
+ **Recommendation**: Proceed to code generation phase.
397
+ ```
@@ -0,0 +1,132 @@
1
+ ---
2
+ name: eventmodeling-designing-automation-chains
3
+ description: "Step 4b of Event Modeling - design every automation's todo-list read model and, for externally-triggered automations, its two-stage translation chain (external EVENT to internal EVENT). Runs immediately after eventmodeling-identifying-inputs places an AUTOMATION+COMMAND pair, before eventmodeling-identifying-outputs. Use right after Step 4 places any AUTOMATION. Do not use for: screen-facing read models (use eventmodeling-identifying-outputs), placing the automation's own COMMAND (use eventmodeling-identifying-inputs), or system/team boundary swimlanes (use eventmodeling-applying-conways-law)."
4
+ allowed-tools:
5
+ - AskUserQuestion
6
+ - Write
7
+ - Bash
8
+ ---
9
+
10
+ # Designing Automation Chains
11
+
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
+
14
+ Prefer `mcp__eventmodelers__*` tools when available (registered by the `connect` skill) — the curl blocks below are the fallback for sessions without MCP connected.
15
+
16
+ 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.
17
+
18
+ **Input**: Every AUTOMATION placed in Step 4, each already paired with its own COMMAND in the actor/interaction rows of one column (per `eventmodeling-orchestrating-event-modeling`'s Timeline Alignment Rules).
19
+ **Output to carry forward**: Every automation's todo-list READMODEL, placed and wired; every externally-triggered automation resolved into a two-stage translation chain (external EVENT → todo-list READMODEL → translation AUTOMATION+COMMAND+internal EVENT → worker automation's own todo list).
20
+ **Gate**: No AUTOMATION on the board lacks an incoming `READMODEL → AUTOMATION` connection to a todo-list read model, and no automation's todo list is opened directly by another system's (second-swimlane) event.
21
+
22
+ ---
23
+
24
+ ## Every automation needs a todo-list read model — no exemption
25
+
26
+ **Every AUTOMATION needs a todo-list read model — this is not optional, and there is no "pure relay" exemption.** An automation is a processor: it reacts to events, decides what work is outstanding, and issues commands to get that work done. The read model that tells it what's outstanding is its **todo list** — a queue of pending work items, not a snapshot of current entity state.
27
+
28
+ **The pattern**: one or more events *open* an item on the todo list (something now needs doing); one or more events *close* it (the work is done — remove the item). A todo list can be opened and closed by more than one event type on either side, and the set of opening events doesn't need to match the set of closing events in count or shape — whatever the domain calls for.
29
+
30
+ **Worked example**: an automation that reacts to `CustomerRegistered` by sending a welcome notification.
31
+ - Todo list: **NotificationsToSend** — one row per pending notification.
32
+ - `CustomerRegistered` **opens** a row (a notification now needs sending).
33
+ - `NotificationSent` (the event this automation's own resulting command produces) **closes** that row (removes it — the list only ever shows outstanding work).
34
+ - The automation (`Send Welcome Notification`) reads `NotificationsToSend`, and for every open row issues `SendNotification`.
35
+
36
+ Even an automation that looks like a "pure signal relay" still has a todo list — model it anyway: it documents that the automation is idempotent/complete once its own event fires, and keeps every automation consistent with the same `READMODEL → AUTOMATION → COMMAND → EVENT` pattern instead of silently exempting some as "too simple to need one."
37
+
38
+ ## The translation-chain rule for external triggers
39
+
40
+ **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
+
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:
43
+
44
+ 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
+ - **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
+ - **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
+
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.
51
+
52
+ ## Fields on a todo-list read model
53
+
54
+ A todo-list read model's fields describe the pending item — the identity it's about (e.g. `customerId`) plus enough context to act on it (e.g. `email`, `notificationType`). Do not add a `status` field to mark items done — a todo list's "open" state is *membership in the list itself* (the row exists at all), not a status flag on a row that never leaves. If the same underlying data is also useful with an explicit status column for a different consumer, that is a different read model, not this one.
55
+
56
+ Every field must set a `mapping` per `eventmodeling-identifying-outputs`'s field data lineage rules (`"<EventTitle>.<fieldName>"`, `"latest:..."`, `"aggregate:..."`, `"derived:..."`), and `"cardinality"` (`"Single"` unless the field genuinely holds a list).
57
+
58
+ ## Placement — todo-list READMODEL, one column before its automation
59
+
60
+ The todo-list read model goes in the interaction lane, **one column before** its automation (actor lane) — the automation's own column already holds the COMMAND it issues, so the read model can never share that column.
61
+
62
+ **Every `node:created` call MUST include `cellId`.** Without it the node has no cell reference and will appear stranded at position 0,0 — not in any timeline column.
63
+
64
+ **Prefer MCP** — `place_element` finds/creates the empty interaction cell one column before the automation and creates the node in one call:
65
+ ```
66
+ mcp__eventmodelers__place_element {
67
+ "boardId": "<BOARD_ID>",
68
+ "timelineId": "<CHAPTER_ID>",
69
+ "elementType": "READMODEL",
70
+ "title": "NotificationsToSend",
71
+ "columnIndex": <automationColumnIndex - 1>
72
+ }
73
+ ```
74
+ Then set `meta.fields` on the returned node id:
75
+ ```
76
+ mcp__eventmodelers__submit_node_events {
77
+ "boardId": "<BOARD_ID>",
78
+ "events": [{
79
+ "id": "<event-uuid>", "eventType": "node:changed", "nodeId": "<returned-node-id>",
80
+ "boardId": "<BOARD_ID>", "timestamp": 1234567890,
81
+ "meta": {"type": "READMODEL", "title": "NotificationsToSend", "fields": [...]}
82
+ }]
83
+ }
84
+ ```
85
+
86
+ **Fallback (no MCP):** see `references/api-fallback.md` — "Placement — todo-list READMODEL, one column before its automation".
87
+
88
+ **Place every node in a translation chain with `autoConnect: false`** (`place_element` / `create_screen` / `submit_node_events` all take the flag). A chain's columns are inserted into the middle of an existing timeline, so the default nearest-left auto-connect will wire the new todo-list READMODEL or internal EVENT to whatever unrelated event sits in the column before it — the recurring "spurious auto-connect edge near an automation chain" cleanup. Suppress it and build the chain's edges yourself in the `set_connections` batch below, then confirm with `validate_model`.
89
+
90
+ > **Never call `drop` after using `cellId` in `node:created`.** The drop endpoint adds a second cell reference without removing the first.
91
+
92
+ For a **translation-chain automation**, place its three columns left to right in the same pass: `[external EVENT]`, `[todo-list READMODEL]`, `[AUTOMATION + COMMAND + internal EVENT]` — the external EVENT normally already exists (placed in Step 1/brainstorming, second swimlane); if it doesn't, place it there first.
93
+
94
+ ## Wiring connections
95
+
96
+ 1. **READMODEL → AUTOMATION first** — the automation reads its own todo list. The closing connection below is only accepted once this edge exists.
97
+ ```
98
+ mcp__eventmodelers__set_connection { "boardId": "<BOARD_ID>", "source": "<readmodelNodeId>", "target": "<automationNodeId>", "action": "connect" }
99
+ ```
100
+ 2. **Every opening EVENT → READMODEL.**
101
+ ```
102
+ mcp__eventmodelers__set_connection { "boardId": "<BOARD_ID>", "source": "<openingEventNodeId>", "target": "<readmodelNodeId>", "action": "connect" }
103
+ ```
104
+ 3. **Every closing EVENT → READMODEL — worker-stage todo lists only.** Including the automation's own resulting event, even though that event is produced by the command this same automation issues. This is not a backward arrow: `EVENT → READMODEL` connections are exempt from column ordering when the read model already has a `READMODEL → AUTOMATION` edge (see `learn-eventmodelers-api` §3) — this todo-list read model qualifies because of the edge from step 1 above. A read model in this shape is a live projection, not a frozen snapshot — a later event closing an earlier-opened item is the normal case, not an exception to reach for only when convenient. **Do not add this edge for a translation automation's todo list** — it has no closing event at all (see the translation-chain rule above); wiring one back is a modeling error, not a convenience.
105
+
106
+ **Fallback (no MCP)** — same three edges via `POST /connections` with `{"source":"...","target":"..."}`, in the same order.
107
+
108
+ Skip a connection silently if the target cell is empty (the element may not exist yet). Log each created arrow, e.g. `→ connected READMODEL→AUTOMATION "NotificationsToSend"→"Send Welcome Notification"`.
109
+
110
+ If this step is designing more than one automation's chain in the same pass, batch every connection from every automation into one `set_connections` call (with `compact: true`) instead of one `set_connection` per edge — `set_connections` still applies its entries **in order**, so keep each automation's own three-edge sequence intact (READMODEL→AUTOMATION before its closing EVENT→READMODEL) within the combined array; different automations' triples can be interleaved or concatenated freely since they don't depend on each other.
111
+
112
+ ## Verification (run before moving to Step 5)
113
+
114
+ Run `validate_model` (`{boardId, chapterId}`) first — with the chain placed `autoConnect: false`, its `backward-arrows` finding confirms no stray nearest-left edge was created and every real edge points the right way, and `command-issuers` confirms each chain's COMMAND is issued only by its own AUTOMATION. Then re-fetch every AUTOMATION on the board (`get_nodes`, `type: "AUTOMATION"`) and check each one:
115
+
116
+ 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
+ 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
+ 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)?
121
+
122
+ 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
+
124
+ ## Quality Checklist
125
+
126
+ - [ ] Every AUTOMATION has an incoming `READMODEL → AUTOMATION` connection to a todo-list read model — no exemption, even for a simple relay
127
+ - [ ] 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
129
+ - [ ] 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
+ - [ ] 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
+ - [ ] No todo-list read model uses a `status` field instead of list membership
132
+ - [ ] Every todo-list read model sits one column before its automation, never sharing its column
@@ -0,0 +1,21 @@
1
+ # Designing Automation Chains — 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
+ ## Placement — todo-list READMODEL, one column before its automation
6
+
7
+ 1. Fetch the chapter to find the interaction row ID (`timelineData.rows`, `type === "interaction"`) and confirm the cell one column before the automation is free.
8
+ 2. If that column doesn't exist yet or its interaction row is occupied, insert a new column immediately before the automation's column (`{"index": automationColumnIndex}`, shifting the automation right).
9
+ 3. `cellId = interactionRow.id + "-" + columnId`
10
+ 4. Create the node:
11
+ ```bash
12
+ curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/events" \
13
+ -H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" -H "x-user-id: designing-automation-chains" \
14
+ -H "Content-Type: application/json" \
15
+ -d '[{
16
+ "id":"<event-uuid>","eventType":"node:created","nodeId":"<node-uuid>",
17
+ "boardId":"<BOARD_ID>","timestamp":1234567890,
18
+ "chapterId":"<CHAPTER_ID>","cellId":"<interactionRowId>-<columnId>",
19
+ "meta":{"type":"READMODEL","title":"NotificationsToSend","fields":[...]}
20
+ }]'
21
+ ```