@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,67 @@
1
+ # Identifying Outputs — 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
+ ## Step 5f — Placing a READMODEL node (full manual sequence)
6
+
7
+ 1. Find the column where the consumer SCREEN or AUTOMATION lives. For an AUTOMATION, the read model's target column is always the one immediately **before** it (skip straight to inserting that column — its interaction row is guaranteed occupied by the automation's own COMMAND). For a SCREEN, target the screen's own column. Fetch the timeline to get the interaction row ID:
8
+ ```bash
9
+ curl -s -H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" \
10
+ "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/$CHAPTER_ID"
11
+ # → timelineData.rows — find the row where type === "interaction"
12
+ ```
13
+ 2. Check if the target interaction cell is already occupied (existing COMMAND):
14
+ ```bash
15
+ curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?cellId=<interactionRowId>-<columnId>" \
16
+ -H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID"
17
+ ```
18
+ If a COMMAND occupies that cell, insert a new column immediately **before** it (`{"index": currentIndex}` — this shifts the consumer's column, and everything after it, one to the right) and use that new column's ID instead. The read model must end up upstream of (to the left of) its consumer, never downstream of it.
19
+ 3. `cellId = interactionRow.id + "-" + columnId`
20
+ 4. Create the READMODEL:
21
+ ```bash
22
+ curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/events" \
23
+ -H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" -H "x-user-id: identifying-outputs" \
24
+ -H "Content-Type: application/json" \
25
+ -d '[{
26
+ "id": "<event-uuid>",
27
+ "eventType": "node:created",
28
+ "nodeId": "<node-uuid>",
29
+ "boardId": "<BOARD_ID>",
30
+ "timestamp": 1234567890,
31
+ "chapterId": "<CHAPTER_ID>",
32
+ "cellId": "<interactionRowId>-<columnId>",
33
+ "meta": {"type": "READMODEL", "title": "ActiveReservationView", "fields": [...]}
34
+ }]'
35
+ ```
36
+
37
+ ## Step 5h.1 — Wire EVENT → READMODEL
38
+
39
+ ```bash
40
+ curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?cellId=<swimlaneRowId>-<columnId>" \
41
+ -H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" -H "x-user-id: eventmodeling-identifying-outputs"
42
+ ```
43
+ Connect it:
44
+ ```bash
45
+ curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/connections" \
46
+ -H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" -H "x-user-id: eventmodeling-identifying-outputs" \
47
+ -H "Content-Type: application/json" \
48
+ -d '{"source":"<eventNodeId>","target":"<readmodelNodeId>"}'
49
+ ```
50
+
51
+ ## Step 5h.2 — Wire READMODEL → SCREEN
52
+
53
+ ```bash
54
+ curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/connections" \
55
+ -H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" -H "x-user-id: eventmodeling-identifying-outputs" \
56
+ -H "Content-Type: application/json" \
57
+ -d '{"source":"<readmodelNodeId>","target":"<screenNodeId>"}'
58
+ ```
59
+
60
+ ## Step 5h.3 — Wire READMODEL → AUTOMATION
61
+
62
+ ```bash
63
+ curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/connections" \
64
+ -H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" -H "x-user-id: eventmodeling-identifying-outputs" \
65
+ -H "Content-Type: application/json" \
66
+ -d '{"source":"<readmodelNodeId>","target":"<automationNodeId>"}'
67
+ ```
@@ -0,0 +1,273 @@
1
+ # Identifying Outputs — Worked Examples
2
+
3
+ These are conceptual worked examples of the read-model design thinking this step applies — useful for understanding the reasoning, but the actual mechanics live in the numbered Step 5a–5i sections of the main SKILL.md (placing nodes on the board via the API), not in writing a document like this.
4
+
5
+ ## Conceptual walkthrough — mapping events to a read model (Order domain)
6
+
7
+ ### 1. Map Event Data to UI Screens
8
+
9
+ ```
10
+ Screen: Order Status View
11
+ Displays data from events:
12
+ orderId ← OrderCreated event
13
+ customerId ← OrderCreated event
14
+ items ← OrderCreated event
15
+ total ← OrderCreated event
16
+ status ← OrderConfirmed event (or OrderCancelled)
17
+ confirmedAt ← OrderConfirmed event
18
+ paymentId ← PaymentAuthorized event
19
+ shipmentId ← OrderShipped event
20
+ shippedAt ← OrderShipped event
21
+
22
+ This screen is a projection of these events:
23
+ - OrderCreated
24
+ - OrderConfirmed
25
+ - PaymentAuthorized
26
+ - OrderShipped
27
+ ```
28
+
29
+ ### 2. Define Read Models
30
+
31
+ ```
32
+ ReadModel: OrderStatusView
33
+ Purpose: UI displays current order status
34
+ Events subscribed: OrderCreated, OrderConfirmed, PaymentAuthorized, OrderShipped, OrderCancelled
35
+ Data:
36
+ {
37
+ orderId: string (from OrderCreated)
38
+ customerId: string (from OrderCreated)
39
+ status: enum (from events: Draft → Confirmed → Authorized → Shipped → Delivered)
40
+ createdAt: Date (from OrderCreated)
41
+ confirmedAt: Date (from OrderConfirmed)
42
+ paymentId: string (from PaymentAuthorized)
43
+ shipmentId: string (from OrderShipped)
44
+ shippedAt: Date (from OrderShipped)
45
+ }
46
+ ```
47
+
48
+ ### 3. Document Event → Data Mapping
49
+
50
+ ```
51
+ Event: OrderCreated
52
+ Provides to UI/Processors:
53
+ orderId
54
+ customerId
55
+ items[]
56
+ total
57
+ shippingAddress
58
+ createdAt
59
+
60
+ Event: OrderConfirmed
61
+ Provides to UI/Processors:
62
+ orderId (link to stream)
63
+ paymentMethod (user selected method)
64
+ confirmedAt (timestamp)
65
+ paymentId (payment system reference)
66
+
67
+ Event: PaymentAuthorized
68
+ Provides to UI/Processors:
69
+ orderId (link to stream)
70
+ paymentId
71
+ authCode
72
+ authorizedAt (timestamp)
73
+ amount (verified amount)
74
+
75
+ Event: OrderShipped
76
+ Provides to UI/Processors:
77
+ orderId (link to stream)
78
+ shipmentId
79
+ shippedAt (timestamp)
80
+ carrier (shipping company)
81
+ trackingNumber (for delivery tracking)
82
+ ```
83
+
84
+ ### 4. Create Output Catalog
85
+
86
+ ```
87
+ ReadModel Catalog: Order System
88
+
89
+ 1. OrderStatusReadModel
90
+ Purpose: UI shows current order status
91
+ Events: OrderCreated, OrderConfirmed, PaymentAuthorized, OrderShipped, OrderCancelled
92
+ Data: orderId, status, createdAt, confirmedAt, paymentId, shipmentId
93
+ Consumed by:
94
+ - Order Status screen (UI)
95
+ - Customer Dashboard (UI)
96
+ - Order Processing Processor (decides if can ship)
97
+
98
+ 2. OrderListReadModel
99
+ Purpose: UI lists all orders for a customer
100
+ Events: OrderCreated, OrderConfirmed, OrderCancelled
101
+ Data: orderId, customerId, total, status, createdAt
102
+ Consumed by:
103
+ - Customer Order History (UI)
104
+ - Order Search/Filter (UI)
105
+
106
+ 3. PaymentStatusReadModel
107
+ Purpose: UI shows payment status
108
+ Events: OrderConfirmed, PaymentAuthorized, PaymentFailed
109
+ Data: orderId, paymentId, status, authCode, failureReason, timestamp
110
+ Consumed by:
111
+ - Payment Status screen (UI)
112
+ - Accounting Processor (reconciliation)
113
+
114
+ 4. ShipmentTrackingReadModel
115
+ Purpose: UI shows tracking information
116
+ Events: OrderShipped, DeliveryConfirmed
117
+ Data: orderId, shipmentId, trackingNumber, carrier, shippedAt, estimatedDelivery
118
+ Consumed by:
119
+ - Order Tracking screen (UI)
120
+ - Customer notifications (Processor)
121
+ ```
122
+
123
+ ### 5. Identify Missing Data
124
+
125
+ ```
126
+ Question: What if UI needs "estimated delivery date"?
127
+ Event: OrderShipped has carrier + trackingNumber
128
+ Action needed: Add estimatedDelivery to OrderShipped event
129
+ (or compute from carrier info)
130
+
131
+ Question: What if UI needs to show "payment method" on status?
132
+ Event: OrderConfirmed has paymentMethod
133
+ Action needed: Include paymentMethod in relevant read models
134
+
135
+ Question: What if UI needs "item descriptions"?
136
+ Event: OrderCreated has items[]
137
+ But: items[] only has productId
138
+ Action needed: Enrich with product descriptions from catalog
139
+ (via join with product service)
140
+ ```
141
+
142
+ ### 6. Processor Outputs
143
+
144
+ ```
145
+ Processor: Inventory System
146
+ Consumes from read models:
147
+ - Orders in "PaymentAuthorized" status
148
+ - Items and quantities needed
149
+ Produces commands:
150
+ - ReserveInventory
151
+
152
+ Processor: Fulfillment System
153
+ Consumes from read models:
154
+ - Orders in "InventoryReserved" status
155
+ - Items and quantities
156
+ - Shipping address
157
+ Produces commands:
158
+ - CreateShipment
159
+
160
+ Processor: Notification System
161
+ Consumes from read models:
162
+ - OrderCreated (sends confirmation)
163
+ - OrderConfirmed (sends receipt)
164
+ - OrderShipped (sends tracking)
165
+ - DeliveryConfirmed (sends thank you)
166
+ Does not produce commands (info-only)
167
+ ```
168
+
169
+ ## Legacy markdown-document format (superseded — kept for reference only)
170
+
171
+ Older versions of this skill wrote the read model catalog as a markdown document instead of placing nodes on the board. The actual mechanism today is the board API (Step 5a–5i in the main SKILL.md) — this template is kept only so the shape of the information (what a complete read-model catalog covers) stays documented somewhere.
172
+
173
+ ```markdown
174
+ # Outputs: [Domain Name]
175
+
176
+ ## Read Models Summary
177
+
178
+ | ReadModel | Purpose | Events | Consumed By |
179
+ |-----------|---------|--------|-------------|
180
+ | OrderStatus | Show order state | OrderCreated, OrderConfirmed | UI, Processor |
181
+ | OrderList | List orders | OrderCreated, OrderCancelled | UI |
182
+ | PaymentStatus | Payment info | OrderConfirmed, PaymentAuthorized | UI, Accounting |
183
+ | Shipment Tracking | Track delivery | OrderShipped, DeliveryConfirmed | UI, Notifications |
184
+
185
+ ---
186
+
187
+ ## Detailed Read Models
188
+
189
+ ### ReadModel: OrderStatusView
190
+
191
+ **Purpose**: Order Status screen displays current order state
192
+
193
+ **Events subscribed**:
194
+ - OrderCreated
195
+ - OrderConfirmed
196
+ - PaymentAuthorized
197
+ - OrderShipped
198
+ - OrderCancelled
199
+ - DeliveryConfirmed
200
+
201
+ **Data**:
202
+ ```
203
+ {
204
+ orderId: string
205
+ customerId: string
206
+ status: 'Draft' | 'Confirmed' | 'Authorized' | 'Shipped' | 'Delivered' | 'Cancelled'
207
+ items: Array<{productId, quantity, unitPrice}>
208
+ total: number
209
+ shippingAddress: Address
210
+
211
+ createdAt: Date
212
+ confirmedAt: Date
213
+ paymentId: string
214
+ paymentMethod: 'card' | 'transfer'
215
+ authorizedAt: Date
216
+
217
+ shipmentId: string
218
+ carrier: string
219
+ trackingNumber: string
220
+ shippedAt: Date
221
+ estimatedDelivery: Date
222
+ }
223
+ ```
224
+
225
+ **Update Logic**:
226
+ - OrderCreated: Insert with status='Draft'
227
+ - OrderConfirmed: Update status='Confirmed'
228
+ - PaymentAuthorized: Update status='Authorized', set paymentId
229
+ - OrderShipped: Update status='Shipped', set shipmentId, carrier, trackingNumber
230
+ - DeliveryConfirmed: Update status='Delivered'
231
+ - OrderCancelled: Update status='Cancelled'
232
+
233
+ **Consumed By**:
234
+ - Order Status Screen (displays)
235
+ - Order Processing Processor (checks status)
236
+ - Notification System (sends updates)
237
+
238
+ --- [Repeat for each read model]
239
+
240
+ ---
241
+
242
+ ## Data Completeness Check
243
+
244
+ ### Events → UI Needs
245
+
246
+ Verify all UI needs have event sources:
247
+
248
+ | UI Need | Event Source | Status |
249
+ |---------|-------------|--------|
250
+ | Order status | OrderConfirmed, OrderShipped | |
251
+ | Tracking number | OrderShipped | |
252
+ | Order items | OrderCreated | |
253
+ | Estimated delivery | OrderShipped | |
254
+ | Cancellation reason | OrderCancelled | |
255
+
256
+ ### Missing Data
257
+
258
+ Identify UI needs without event sources:
259
+ - None identified
260
+
261
+ ---
262
+
263
+ ## Processor Consumption
264
+
265
+ ### Processors and their reads:
266
+
267
+ | Processor | Reads From | Writes Commands |
268
+ |-----------|-----------|-----------------|
269
+ | Inventory | OrderStatusView (Authorized) | ReserveInventory |
270
+ | Fulfillment | OrderStatusView (InventoryReserved) | CreateShipment |
271
+ | Notification | OrderStatusView (all) | None (info-only) |
272
+ | Accounting | PaymentStatusView | None (reporting) |
273
+ ```
@@ -0,0 +1,31 @@
1
+ ---
2
+ name: eventmodeling-interview-protocol
3
+ description: Shared procedure for deciding whether to ask the user clarifying questions before an event-modeling step proceeds, and how to record what was decided. Not a step of its own — referenced by other eventmodeling-* skills' Interview Phase section. Do not use standalone.
4
+ ---
5
+
6
+ # Interview Protocol
7
+
8
+ Shared by every event-modeling step that has an "Interview Phase" section. A step's own SKILL.md defines only what's specific to it — when to interview and its Critical Questions. Everything below is common to all of them.
9
+
10
+ ## When to ask
11
+
12
+ Missing information, or something ambiguous that this step needs? Ask the user — using the step's own Critical Questions as a guide, via `AskUserQuestion` where appropriate. Follow any listed follow-up trigger based on the answer.
13
+
14
+ Already have everything the step needs? Skip straight to the step's own workflow — don't ask questions whose answers you already have.
15
+
16
+ **Unless told not to ask** (an autonomous/unattended run, or the user has said not to stop for questions): don't block. Proceed with the most reasonable assumption for anything missing, and say so plainly in this step's findings below — visibly, so it can be corrected later. Never silently guess.
17
+
18
+ ## Recording the outcome
19
+
20
+ Append to the project's event modeling file: `.trogonai/interviews/[project-name]/EVENTMODELING.md`, under a section for this step:
21
+
22
+ ```markdown
23
+ ## <Step Number>. <Step Name> (<skill-name>)
24
+ [What was asked and decided — or, if nothing was asked, what was assumed and why]
25
+ ```
26
+
27
+ Then add or update this step's row in the `## Interview Trail` table (create it if this is the first step to run):
28
+
29
+ ```markdown
30
+ | <Step Number> | <skill-name> | Done | <one-line summary of key outputs> |
31
+ ```
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: eventmodeling-optimizing-stream-design
3
- description: "Design event streams with proper stream identity to keep streams appropriately sized, avoid unnecessary snapshotting, and balance performance with simplicity. Use when concerned about stream length, planning performance, or validating stream design before implementation. Do not use for: designing the initial event model structure (use eventmodeling-designing-event-models) or general architectural validation (use eventmodeling-validating-event-models)."
3
+ description: "Validate and fix an entity's event timeline boundary is it anchored on a single business identity, or is it secretly a collection/log that will grow unbounded? Use when concerned about a timeline mixing concerns, reviewing timeline boundaries, or when a timeline feels like it's absorbing unrelated events. Do not use for: designing the initial event model structure (use eventmodeling-designing-event-models) or general model validation (use eventmodeling-validating-event-models)."
4
4
  allowed-tools:
5
5
  - AskUserQuestion
6
6
  - Write
@@ -8,224 +8,77 @@ allowed-tools:
8
8
 
9
9
  # Optimizing Stream Design
10
10
 
11
- ## Interview Phase (Optional)
11
+ 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.
12
12
 
13
- **When to Interview**: Skip if the user has specified: expected event frequency, stream lifetime, and growth patterns. Interview when stream length concerns exist but growth estimates are unclear.
13
+ ## Timeline Boundary Optimization
14
14
 
15
- **Interview Strategy**: Establish growth expectations and performance requirements before recommending snapshotting. Most snapshotting proposals stem from poor stream boundary design, not genuine volume surface the estimates first to distinguish real performance concerns from design problems.
15
+ **Purpose**: Validate timeline boundaries confirm each entity's event timeline is anchored on a single business entity's own lifecycle, and catch the two common anti-patterns (an unbounded collection, or an unrelated event log) before they get modeled further.
16
16
 
17
- ### Critical Questions
18
-
19
- 1. **Growth Estimates** (Impact: Determines if snapshotting is needed or if stream design should change)
20
- - Question: "Estimate events: (A) Per entity per day, (B) Lifetime total, (C) Growth over years. Example: 5-10 events/order, 1-10 million orders/year?"
21
- - Why it matters: Growth estimates reveal if streams will genuinely be too long or if design is wrong
22
- - Follow-up triggers: If estimates exceed 300 events per stream lifetime → ask "Is the stream identity correct? Could this stream be split by a narrower business entity?"
23
-
24
- 2. **Performance SLAs** (Impact: Determines acceptable latency and snapshotting decisions)
25
- - Question: "Performance requirements? (A) <100ms read latency, (B) <1s acceptable, (C) Eventual consistency OK?"
26
- - Why it matters: Strict SLAs might need snapshotting; loose SLAs often don't
27
- - Follow-up triggers: If (A) → ask "Which commands specifically need sub-100ms replay? Are those commands reading from a read model or replaying the stream directly?"
28
-
29
- ### Interview Flow
30
-
31
- **Conditional Entry**:
32
- ```
33
- If user has provided:
34
- - Event frequency estimate (per entity per day or per transaction)
35
- - AND stream lifetime estimate (months or years)
36
- - AND read latency SLA (or confirmation that eventual consistency is acceptable)
37
-
38
- Then: Skip interview, proceed directly to stream analysis
39
-
40
- Else: Conduct interview
41
- ```
42
-
43
- **Phase 1: Growth Estimation** (Question 1)
44
- - Establish per-entity event volume
45
- - Project lifetime stream length using the estimation formula
46
- - Determine whether redesign or snapshotting analysis is warranted
47
-
48
- **Phase 2: SLA Requirements** (Question 2)
49
- - Identify read latency requirements per command
50
- - Determine whether read models or direct stream replay satisfies the SLA
51
- - Establish whether snapshotting is justified by SLA alone
52
-
53
- ### Capturing Interview Findings
54
-
55
- Append findings to the project's event modeling file:
56
-
57
- **File**: `.trogonai/interviews/[project-name]/EVENTMODELING.md`
58
-
59
- Use Write tool to add/update this section:
60
-
61
- ```markdown
62
- ## Optimizing Stream Design (eventmodeling-optimizing-stream-design)
63
-
64
- ### Growth Estimates
65
- [From Q1: Events per entity per day, lifetime total, annual growth]
66
-
67
- ### Performance SLAs
68
- [From Q2: Latency requirements per command or view]
69
-
70
- ### Optimization Decisions
71
- - Streams requiring redesign: [list or "None"]
72
- - Streams where snapshotting is justified: [list or "None"]
73
- - Streams within acceptable bounds: [list]
74
- ```
75
-
76
- Update Interview Trail:
77
- ```markdown
78
- | Optimization | eventmodeling-optimizing-stream-design | Done | Stream growth estimates, SLA review, snapshotting decisions |
79
- ```
80
-
81
- ---
82
-
83
- ## Stream Design Optimization
84
-
85
- **Purpose**: Optimize event stream design by validating stream boundaries, estimating growth, and making snapshotting decisions based on design quality—not just size.
86
-
87
- **Applies To**: Any domain - e-commerce, banking, SaaS, marketplace, healthcare, etc.
17
+ **Applies To**: Any domain — e-commerce, banking, SaaS, marketplace, healthcare, etc.
88
18
 
89
19
  **When to Use**:
90
- - After defining event streams in domain analysis
91
- - When concerned about stream length or performance
92
- - Before implementing to validate stream design
93
- - During performance planning to determine snapshotting strategy
94
- - When redesigning streams for scalability
20
+ - After defining events in domain analysis
21
+ - When a timeline feels like it's growing for reasons unrelated to one entity's own story
22
+ - When redesigning a timeline whose boundary turned out to be wrong
95
23
 
96
24
  **What It Does**:
97
- 1. Analyzes event stream design for proper event organization
98
- 2. Estimates stream growth over time
99
- 3. Identifies when snapshotting is genuinely needed vs. design issue
100
- 4. Recommends optimal stream identity boundaries
101
- 5. Balances performance optimization against complexity
102
- 6. Provides snapshotting strategy without over-engineering
25
+ 1. Checks that each timeline has a single, natural business identity
26
+ 2. Identifies timelines that are actually collections or logs in disguise
27
+ 3. Recommends the correct boundary when one is wrong
28
+ 4. Distinguishes "this timeline is long because the entity has a long history" (fine) from "this timeline is long because it's absorbing events that don't belong to it" (a boundary bug)
103
29
 
104
30
  ---
105
31
 
106
- ## Core Principle: Design First, Snapshot Second
32
+ ## Core Principle: Get the Identity Right
107
33
 
108
34
  **Golden Rule**:
109
- > If you find yourself needing to snapshot because the stream is too long, first ask: "Is my stream identity wrong?" Usually, the answer is yes.
35
+ > If a timeline feels like it's growing for the wrong reasons, first ask: "Does this timeline actually have one business identity, or is it a collection/log wearing an entity's name?"
110
36
 
111
- Snapshotting is a **performance optimization**, not a design problem. Good stream design (proper identity boundaries) often eliminates the need for snapshotting entirely.
37
+ A long timeline is not, by itself, evidence of a design problem — an account open for thirty years is correctly one long timeline. What *is* always a design problem is a timeline whose events don't all belong to the same entity's own lifecycle.
112
38
 
113
39
  ---
114
40
 
115
- ## Stream Design Analysis Framework
41
+ ## Timeline Boundary Review
116
42
 
117
- ### 1. Estimate Stream Growth
43
+ For each entity's timeline in scope, work through:
118
44
 
119
- **Formula**:
120
- ```
121
- Estimated Stream Length (total events/instance) =
122
- Events Per Aggregate Instance Per Year (events/instance/year)
123
- × Lifetime of Instance (years)
124
- × Annual Growth Factor (dimensionless year-over-year multiplier ≥ 1.0)
125
- ```
45
+ ### 1. Name the identity
126
46
 
127
- **Quick Examples**:
47
+ What single business entity does this timeline represent the history of? Write it down explicitly (e.g. `orderId`, not "orders").
128
48
 
129
- **E-commerce Order**: 8 events/year × 1.5 year lifetime = 8-16 events → NOT NEEDED
49
+ ### 2. Check every event against that identity
130
50
 
131
- **Banking Account**: 100-200 events/year × 10 years = 1000-2000 events CONSIDER AT 1000+
51
+ Does each event on the timeline describe something that happened to *this* entity — not to a category of entities, not to the system in general? If any event fails this test, the boundary is wrong (see `references/patterns.md`'s Red Flags).
132
52
 
133
- **Order Processing**: 100+ events/year × 5 years = 300-500+ events → PROBABLY NEEDED
53
+ ### 3. Classify the result
134
54
 
135
- **SaaS User**: 12-60 events/year × 5 years = 60-300 events → RARELY NEEDED
136
-
137
- ### 2. Identify Stream Length Categories
138
-
139
- | Length | Status | Action | Snapshotting |
140
- |--------|--------|--------|--------------|
141
- | < 50 events | IDEAL | Keep as-is | NOT NEEDED |
142
- | 50-100 events | GOOD | Monitor growth | NOT NEEDED |
143
- | 100-300 events | ACCEPTABLE | Review boundary | CONSIDER if replayed |
144
- | 300-1000 events | LONG | REDESIGN first | Only last resort |
145
- | 1000+ events | CRITICAL | REDESIGN required | Won't help |
146
-
147
- ---
148
-
149
- ## Quick Decision Matrix
150
-
151
- | Stream Length | Read Pattern | Frequency | Action |
152
- |---|---|---|---|
153
- | < 50 | Any | Any | IDEAL - Keep as-is |
154
- | 50-100 | Any | Any | Good - Monitor |
155
- | 100-300 | From Model | Any | OK - No snapshot |
156
- | 100-300 | Stream Replay | Low | OK - Monitor |
157
- | 100-300 | Stream Replay | High | REDESIGN |
158
- | 300-1000 | From Model | Any | OK - No snapshot |
159
- | 300-1000 | Stream Replay | Any | REDESIGN |
160
- | 1000+ | Any | Any | CRITICAL - REDESIGN |
55
+ | Result | Meaning | Action |
56
+ |---|---|---|
57
+ | Every event belongs to one clear entity | Boundary is correct | Keep as-is, regardless of how long the history gets |
58
+ | Events span a category or "all X" | Pattern 3 (Collection) anti-pattern | Re-scope to the real per-entity identity; the category becomes a read model/query, not an event timeline |
59
+ | Events span unrelated concerns (users, orders, payments mixed) | Pattern 4 (Event Log) anti-pattern | Split into one timeline per concern |
60
+ | Timeline conflates an entity's active life with its historical record | Missing the Pattern 5 split | Separate active vs. archived/historical timelines |
161
61
 
162
62
  ---
163
63
 
164
64
  ## Reference Files
165
65
 
166
- **Aggregate Boundary Design**: See [patterns.md](references/patterns.md) for:
167
- - 5 aggregate patterns (single entity, composite, collections, event logs, historical)
168
- - Stream size decision tree
169
- - Red flags that indicate redesign needed
170
- - Tips for optimal stream design
171
-
172
- **Snapshotting Strategy**: See [snapshotting.md](references/snapshotting.md) for:
173
- - Criteria for when snapshotting is truly needed
174
- - Context-based decision thresholds
175
- - Snapshot frequency, versioning, and cleanup strategies
176
- - Cost-benefit analysis
66
+ **Timeline Boundary Design**: See [patterns.md](references/patterns.md) for:
67
+ - 5 boundary patterns (single entity, composite, collection anti-pattern, event-log anti-pattern, historical)
68
+ - The timeline boundary decision tree
69
+ - Red flags that indicate the boundary — not the volume — is wrong
70
+ - Tips for finding the right boundary
177
71
 
178
72
  **Domain-Specific Guidance**: See [domain-patterns.md](references/domain-patterns.md) for:
179
73
  - E-commerce patterns (orders, carts, accounts)
180
74
  - Banking patterns (accounts, transactions, loans)
181
75
  - SaaS patterns (subscriptions, workspaces, data collections)
182
- - Implementation checklist
183
-
184
- ---
185
-
186
- ## Key Insights
187
-
188
- ### Why Snapshotting Usually Isn't the Answer
189
-
190
- ```
191
- Before implementing snapshotting, ask:
192
-
193
- 1. Can I split this aggregate into smaller ones?
194
- → YES: Do that instead. Simpler, better design.
195
-
196
- 2. Can I reduce event granularity?
197
- → YES: Batch events or create coarser state changes.
198
-
199
- 3. Am I using a read model for this aggregate?
200
- → NO: Create a read model (cached projection).
201
- Stream size becomes irrelevant.
202
-
203
- 4. Have I measured actual replay latency?
204
- → NO: Measure first. Most systems exceed expectations.
205
-
206
- If ANY of these is YES, do that before snapshotting.
207
- Only after exhausting design improvements, consider snapshots.
208
- ```
209
-
210
- ### The Snapshotting Trade-off
211
-
212
- ```
213
- Snapshotting Complexity ≈ 2-3x Complexity of Better Design
214
-
215
- Before snapshot: 50 lines of code, simple, testable
216
- With snapshots: 150+ lines, versioning, recovery logic, testing matrix
217
-
218
- Better to redesign and keep streams < 300 events.
219
- ```
220
76
 
221
77
  ---
222
78
 
223
79
  ## Quality Checklist
224
80
 
225
- - [ ] Each stream is identified by a business entity identity (e.g., `orderId`), not a category or type
226
- - [ ] No stream grows unboundedly without a design reasonevent frequency and stream lifetime estimated
227
- - [ ] Streams under 1000 events require no snapshotting justification
228
- - [ ] If snapshotting is proposed, all simpler alternatives (split stream, shorter lifetime) have been eliminated first
229
- - [ ] Command handler state is reconstructed from stream events — no persistent state stored outside the stream
230
- - [ ] Each stream can be independently versioned and replayed without affecting other streams
231
-
81
+ - [ ] Each timeline is identified by a business entity identity (e.g., `orderId`), not a category or type
82
+ - [ ] Every event on a timeline belongs to that one entity's own lifecycle none of them describe a different entity or an unrelated system concern
83
+ - [ ] No timeline is secretly a collection ("all X") or a log ("everything that happened") wearing an entity's name
84
+ - [ ] A timeline that conflates an entity's active life with its historical record has been split (active vs. archived)