@eventmodelers/cli 1.0.38 → 1.0.40
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.
- package/package.json +1 -1
- package/stacks/modeling-kit/templates/.claude/skills/analyze-existing-model/SKILL.md +16 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-core-rules/SKILL.md +11 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-automation-chains/SKILL.md +5 -2
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-elaborating-scenarios/SKILL.md +1 -1
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-outputs/SKILL.md +3 -1
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models-checklist/SKILL.md +28 -7
- package/stacks/modeling-kit/templates/.claude/skills/wdyt/SKILL.md +8 -6
package/package.json
CHANGED
|
@@ -119,6 +119,15 @@ Do not flag gaps that are clearly intentional (e.g. a slice named "Internal" wit
|
|
|
119
119
|
|
|
120
120
|
Check whether any EVENT, COMMAND, or READMODEL appears in zero slices (present on the board but not wired into any slice boundary). If the slicedata API does not expose this directly, skip this check and note it.
|
|
121
121
|
|
|
122
|
+
### 5f — Structural shapes
|
|
123
|
+
|
|
124
|
+
Check the element graph gathered in Step 4 against the four shapes defined in `eventmodeling-core-rules`'s **Structural Shapes** section (the bed, left chair, right chair, shelf) — read that section for the full definitions and thresholds; this step only covers how to report them here.
|
|
125
|
+
|
|
126
|
+
- **The bed** is a real anti-pattern — always report every instance found (a SCREEN wired to more than one COMMAND), by slice/screen name.
|
|
127
|
+
- **The left chair, right chair, and shelf** are candidates — only report an instance if, after reasoning about the actual events/fields/scenarios involved, the count still looks like it's doing more than one job in this domain. Don't report a raw count crossing the threshold on its own.
|
|
128
|
+
|
|
129
|
+
This is a read-only structural read like the rest of Step 5 — report findings, never fix them here.
|
|
130
|
+
|
|
122
131
|
---
|
|
123
132
|
|
|
124
133
|
## Step 6 — Report to the user
|
|
@@ -172,6 +181,13 @@ Total: <n> slices
|
|
|
172
181
|
|
|
173
182
|
---
|
|
174
183
|
|
|
184
|
+
### Structural Shapes
|
|
185
|
+
<always list every "the bed" instance found — screen name + the commands it fans into>
|
|
186
|
+
<list a left chair/right chair/shelf instance only if it held up after reasoning about the domain>
|
|
187
|
+
(none) if nothing found
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
175
191
|
### Summary
|
|
176
192
|
<2–4 sentences: overall model maturity, the most important gap or risk, one concrete suggestion>
|
|
177
193
|
```
|
|
@@ -69,6 +69,7 @@ Slices are not placed directly — they're **derived** from a completed model. E
|
|
|
69
69
|
- Invalid: `OrderSummaryProjector`, `InvoiceListRepository` — implementation detail leaking into the model
|
|
70
70
|
- Optional — nothing requires a READMODEL to exist for a COMMAND or a downstream consumer.
|
|
71
71
|
- Never drives COMMAND validation directly — a COMMAND is checked against its own documented preconditions, not a read model.
|
|
72
|
+
- **List-shaped read models**: when the whole READMODEL represents multiple rows (each row shaped by its defined fields), not a single projected record, set `meta.listElement: true` on the node itself — this is a node-level flag, distinct from a field's own `cardinality: "List"` (a single field holding multiple values). Every todo-list read model (see `eventmodeling-designing-automation-chains`) is list-shaped and always gets `listElement: true`; the same applies to any other READMODEL whose query naturally returns a set of rows (e.g. `ProductList`, `InvoiceList`). `eventmodeling-elaborating-scenarios` reads this flag to decide whether a scenario needs row-level `examples`/`expectEmptyList` instead of a single accumulated result.
|
|
72
73
|
|
|
73
74
|
### SCREEN
|
|
74
75
|
- Represents what a user sees and can act on.
|
|
@@ -151,6 +152,15 @@ Question any step that exists only because of the system — a loading spinner,
|
|
|
151
152
|
- **Technical events**: `ApiCalled`/`ResponseReceived` describe machinery, not an outcome — find the business fact underneath.
|
|
152
153
|
- **Calculated events**: an event whose value is recomputed as source data changes (a running total, an average) is a READMODEL, not an EVENT.
|
|
153
154
|
|
|
155
|
+
## Structural Shapes
|
|
156
|
+
|
|
157
|
+
Beyond the local anti-patterns above, four recurring **connection shapes** are worth checking whenever the model's wiring is visible — a fan-out or fan-in count crossing a rough threshold. Only one is a real anti-pattern regardless of context; the other three are **candidates** — worth checking against the business context, not automatically wrong. Reason about the actual events/fields/scenarios involved before flagging a candidate; if the domain justifies the count, it's not a violation. These are internal shorthand names for spotting the shape — never surface "bed", "left chair", "right chair", or "shelf" in anything shown to a business stakeholder (a board comment, a report); describe the concern in plain terms instead.
|
|
158
|
+
|
|
159
|
+
- **The bed (real anti-pattern — always flag)** — one SCREEN wired to more than one COMMAND. A screen is where the user has already committed to one decision, so it should trigger exactly one command; wiring several to it means the choice is being made somewhere invisible to the model.
|
|
160
|
+
- **The left chair (candidate)** — one COMMAND resulting in more than two EVENTs. May mean the command is doing more than one job, or it may be a single business outcome that legitimately fans out. Check whether the outcomes always happen together or could happen independently before treating it as a concern.
|
|
161
|
+
- **The right chair (candidate)** — one READMODEL built from more than three EVENTs. May mean the view is answering more than one question at once, or it may be one coherent picture that genuinely needs that many sources. Check whether the fields shown belong to a single thing the user is checking before treating it as a concern.
|
|
162
|
+
- **The shelf (candidate)** — one slice with noticeably more SCENARIOs than the others on the same timeline (a rough outlier, not a fixed threshold — compare against the typical count for that timeline). May mean the step is quietly covering ground that belongs to a separate step, or it may just be genuinely more complex. Check what the extra scenarios actually cover before treating it as a concern.
|
|
163
|
+
|
|
154
164
|
## Flow & Causality
|
|
155
165
|
|
|
156
166
|
Model causality, not strict sequence:
|
|
@@ -178,5 +188,6 @@ Before treating a model as done, verify:
|
|
|
178
188
|
- [ ] Every COMMAND traces back to a SCREEN (user decision) or AUTOMATION (system reaction)
|
|
179
189
|
- [ ] The timeline starts with a state-view or an automation reacting to an event — not a bare COMMAND
|
|
180
190
|
- [ ] No two `state-change`/`state-change` slices are chained without a new trigger between them
|
|
191
|
+
- [ ] No SCREEN is wired to more than one COMMAND (the bed — see Structural Shapes)
|
|
181
192
|
|
|
182
193
|
This is the fast pass — the full, deeper check is `eventmodeling-validating-event-models-checklist`.
|
|
@@ -69,6 +69,8 @@ A todo-list read model's fields describe the pending item — the identity it's
|
|
|
69
69
|
|
|
70
70
|
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).
|
|
71
71
|
|
|
72
|
+
A todo-list read model is always list-shaped — it's a queue of pending items, never a single record — so it always gets **`meta.listElement: true`** on the node itself (see `eventmodeling-core-rules`'s READMODEL section). This is a node-level flag separate from any field's own `cardinality`.
|
|
73
|
+
|
|
72
74
|
## Placement — todo-list READMODEL, one column before its automation
|
|
73
75
|
|
|
74
76
|
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.
|
|
@@ -85,14 +87,14 @@ mcp__eventmodelers__place_element {
|
|
|
85
87
|
"columnIndex": <automationColumnIndex - 1>
|
|
86
88
|
}
|
|
87
89
|
```
|
|
88
|
-
Then set `meta.fields` on the returned node id:
|
|
90
|
+
Then set `meta.fields` and `meta.listElement: true` on the returned node id:
|
|
89
91
|
```
|
|
90
92
|
mcp__eventmodelers__submit_node_events {
|
|
91
93
|
"boardId": "<BOARD_ID>",
|
|
92
94
|
"events": [{
|
|
93
95
|
"id": "<event-uuid>", "eventType": "node:changed", "nodeId": "<returned-node-id>",
|
|
94
96
|
"boardId": "<BOARD_ID>", "timestamp": 1234567890,
|
|
95
|
-
"meta": {"type": "READMODEL", "title": "NotificationsToSend", "fields": [...]}
|
|
97
|
+
"meta": {"type": "READMODEL", "title": "NotificationsToSend", "fields": [...], "listElement": true}
|
|
96
98
|
}]
|
|
97
99
|
}
|
|
98
100
|
```
|
|
@@ -145,4 +147,5 @@ List the result (connected / chain-resolved) for every automation checked — th
|
|
|
145
147
|
- [ ] 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
|
|
146
148
|
- [ ] 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
|
|
147
149
|
- [ ] No todo-list read model uses a `status` field instead of list membership
|
|
150
|
+
- [ ] Every todo-list read model has `meta.listElement: true` set on the node
|
|
148
151
|
- [ ] Every todo-list read model sits one column before its automation, never sharing its column
|
package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-elaborating-scenarios/SKILL.md
CHANGED
|
@@ -386,7 +386,7 @@ Pass `compact: true` — you already hold every scenario object you sent, so the
|
|
|
386
386
|
|
|
387
387
|
### Step 4b — List-type readmodel scenario fields
|
|
388
388
|
|
|
389
|
-
When `then` contains a READMODEL whose `listElement` property is `true
|
|
389
|
+
When `then` contains a READMODEL whose `listElement` property is `true` — set on the node when it was created, per `eventmodeling-core-rules`'s READMODEL section and `eventmodeling-identifying-outputs`/`eventmodeling-designing-automation-chains` — add two fields **at the scenario level** (not inside `then`):
|
|
390
390
|
|
|
391
391
|
**`examples`** — one object per expected row, keyed by the readmodel's snake_case field names. Without this the spec node renders with no expected output and the scenario is unverifiable.
|
|
392
392
|
|
package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-outputs/SKILL.md
CHANGED
|
@@ -222,6 +222,8 @@ Set the field's `generated` property according to this table. Fields projected d
|
|
|
222
222
|
|
|
223
223
|
Every field must also set `"cardinality"` — use `"Single"` unless the field genuinely holds a list of values (e.g. line items, a collection projected from multiple events), in which case use `"List"`. Default to `"Single"` when unsure. Include only the fields the consuming SCREEN or AUTOMATION actually displays or needs — do not add speculative fields; enrich later via `/attributes`.
|
|
224
224
|
|
|
225
|
+
If the READMODEL itself represents a set of rows rather than a single record — e.g. `InvoiceList`, `ProductList` — also set `meta.listElement: true` on the node (see `eventmodeling-core-rules`'s READMODEL section). This is separate from a field's `cardinality`: `listElement` says the whole read model is a list of elements shaped by its defined fields, `cardinality: "List"` says one field on an otherwise-single-record read model holds multiple values.
|
|
226
|
+
|
|
225
227
|
```json
|
|
226
228
|
{
|
|
227
229
|
"type": "READMODEL",
|
|
@@ -259,7 +261,7 @@ mcp__eventmodelers__place_element {
|
|
|
259
261
|
"columnIndex": <consumerScreenColumnIndex> // or <automationColumnIndex - 1> for an AUTOMATION consumer
|
|
260
262
|
}
|
|
261
263
|
```
|
|
262
|
-
Then set `meta.fields` (with `mapping`/`generated`/`cardinality`) on the returned node id:
|
|
264
|
+
Then set `meta.fields` (with `mapping`/`generated`/`cardinality`) — and `meta.listElement: true` if this read model is list-shaped — on the returned node id:
|
|
263
265
|
```
|
|
264
266
|
mcp__eventmodelers__submit_node_events {
|
|
265
267
|
"boardId": "<BOARD_ID>",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: eventmodeling-validating-event-models-checklist
|
|
3
|
-
description: "Validate an event model against
|
|
3
|
+
description: "Validate an event model against 13 structural checks across 7 phases. Identifies notation anti-patterns and confirms the model is internally consistent. Use when reviewing an event model for readiness or after completing event modeling steps. Do not use for: reviewing incomplete or in-progress models (use eventmodeling-validating-event-models), or for elaborating new scenarios (use eventmodeling-elaborating-scenarios)."
|
|
4
4
|
allowed-tools:
|
|
5
5
|
- Write
|
|
6
6
|
- Bash
|
|
@@ -14,7 +14,7 @@ This step applies the shared element rules in **`eventmodeling-core-rules`** —
|
|
|
14
14
|
|
|
15
15
|
Prefer `mcp__eventmodelers__*` tools when available (registered by the `connect` skill) — the curl blocks below are the fallback for sessions without MCP connected.
|
|
16
16
|
|
|
17
|
-
**Purpose**: Validate any event model against
|
|
17
|
+
**Purpose**: Validate any event model against 13 structural checks across 7 phases. Identifies notation anti-patterns and confirms the model is internally consistent.
|
|
18
18
|
|
|
19
19
|
**Applies To**: Any domain - e-commerce, banking, SaaS, marketplace, healthcare, etc.
|
|
20
20
|
|
|
@@ -26,7 +26,7 @@ Prefer `mcp__eventmodelers__*` tools when available (registered by the `connect`
|
|
|
26
26
|
|
|
27
27
|
**What It Does**:
|
|
28
28
|
1. Reads current board state (EVENT, COMMAND, READMODEL nodes) as input
|
|
29
|
-
2. Systematically applies
|
|
29
|
+
2. Systematically applies 13 validation checks across 7 phases
|
|
30
30
|
3. Identifies notation anti-patterns (calculations modeled as events, events mixed into the wrong entity's timeline, etc.)
|
|
31
31
|
4. Verifies read model/event distinction
|
|
32
32
|
5. Confirms every event and command traces cleanly
|
|
@@ -90,6 +90,14 @@ Use the board nodes as the model input. After the checklist, use `handle-comment
|
|
|
90
90
|
|
|
91
91
|
**Anti-pattern to catch**: events that can occur in invalid combinations; a "shared" event quietly coupling two entities together
|
|
92
92
|
|
|
93
|
+
### Phase 7: Structural Shape Validation (2 checks)
|
|
94
|
+
- Check 7.1: No SCREEN is wired to more than one COMMAND
|
|
95
|
+
- Check 7.2: Fan-out/fan-in outliers (a command with 2+ resulting events, a read model built from 3+ events, a slice with markedly more scenarios than its neighbors) have been reasoned about against the business context, not flagged on count alone
|
|
96
|
+
|
|
97
|
+
See `eventmodeling-core-rules`'s **Structural Shapes** section for the full definitions ("the bed", "left chair", "right chair", "shelf") and their thresholds — this phase doesn't restate them.
|
|
98
|
+
|
|
99
|
+
**Anti-pattern to catch**: Check 7.1 catches "the bed" — a screen fanning into multiple commands hides where the user's actual decision is made; this is a real anti-pattern, always fail it. Check 7.2 catches "the left chair" / "the right chair" / "the shelf" — these are candidates, not automatic fails: only report an outlier if the specific events/fields/scenarios involved still look like they're doing more than one job once you've checked them against the domain.
|
|
100
|
+
|
|
93
101
|
### Final Questions (2 checks)
|
|
94
102
|
- Question 1: Could a modeler unfamiliar with this domain understand the model in 15 minutes?
|
|
95
103
|
- Question 2: Could the business rule/calculation behind a read model change without rewriting event history?
|
|
@@ -158,6 +166,19 @@ EntityB reacts to EventA via a read model/automation, it doesn't own it
|
|
|
158
166
|
|
|
159
167
|
**Why**: An event belongs to the story of exactly one entity. If a second entity needs to react to it, that's a read model or automation reading it — not the same event living on two timelines.
|
|
160
168
|
|
|
169
|
+
### 4. A Screen Fanning Into Multiple Commands ("the bed")
|
|
170
|
+
```
|
|
171
|
+
ANTI-PATTERN:
|
|
172
|
+
Screen → Command A
|
|
173
|
+
→ Command B
|
|
174
|
+
→ Command C
|
|
175
|
+
|
|
176
|
+
CORRECT:
|
|
177
|
+
Screen → Command A only (one screen, one decision)
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
**Why**: A screen represents the moment a user has already committed to one decision. Wiring it to several commands hides where that choice actually gets made — see `eventmodeling-core-rules`'s **Structural Shapes** section for this and the three related fan-out/fan-in candidates ("left chair", "right chair", "shelf").
|
|
181
|
+
|
|
161
182
|
---
|
|
162
183
|
|
|
163
184
|
## Questions to Ask During Validation
|
|
@@ -181,7 +202,7 @@ EntityB reacts to EventA via a read model/automation, it doesn't own it
|
|
|
181
202
|
## Success Criteria
|
|
182
203
|
|
|
183
204
|
**Model is validated when**:
|
|
184
|
-
- All
|
|
205
|
+
- All 13 checks pass (or have documented workarounds)
|
|
185
206
|
- No critical anti-patterns identified
|
|
186
207
|
- Both final questions answer YES
|
|
187
208
|
- Event modeling principles are clearly upheld
|
|
@@ -243,7 +264,7 @@ Running the checklist after Step 2 prevents wasting time on later steps if the c
|
|
|
243
264
|
|
|
244
265
|
## Checklist Questions by Domain
|
|
245
266
|
|
|
246
|
-
The skill applies the same
|
|
267
|
+
The skill applies the same 13 checks regardless of domain. Here's how to think about it in different contexts:
|
|
247
268
|
|
|
248
269
|
**E-commerce domain**:
|
|
249
270
|
- Events: OrderCreated, OrderConfirmed, PaymentAuthorized, OrderShipped
|
|
@@ -275,7 +296,7 @@ The principle is the same across all domains: **immutable facts as events, calcu
|
|
|
275
296
|
|
|
276
297
|
## Quality Checklist
|
|
277
298
|
|
|
278
|
-
- [ ] All
|
|
299
|
+
- [ ] All 13 checks evaluated — no check skipped without documented justification
|
|
279
300
|
- [ ] Every FAIL result includes the specific event, command, or entity that violated the check
|
|
280
301
|
- [ ] Anti-patterns identified by name with the exact model element that triggered the flag
|
|
281
302
|
- [ ] Final verdict is one of: PASS / PASS WITH WARNINGS / FAIL — no ambiguous outcomes
|
|
@@ -296,5 +317,5 @@ The principle is the same across all domains: **immutable facts as events, calcu
|
|
|
296
317
|
|
|
297
318
|
## Validation Checklist Reference
|
|
298
319
|
|
|
299
|
-
The
|
|
320
|
+
The 13-point checklist is defined in the **Validation Phases** section above.
|
|
300
321
|
Each check includes the anti-pattern to catch and questions to ask when evaluating your model.
|
|
@@ -7,6 +7,8 @@ description: Business analyst exploration of an event model board. Reads all sli
|
|
|
7
7
|
|
|
8
8
|
> **Before doing anything else**, invoke the `connect` skill — if not already connected — to resolve `TOKEN`, `BOARD_ID`, and `BASE_URL`. Do not proceed until the connect skill has completed.
|
|
9
9
|
|
|
10
|
+
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, the anti-patterns to reject, and the four Structural Shapes (Category I below), so this step doesn't restate them.
|
|
11
|
+
|
|
10
12
|
You are a **sharp business analyst** reviewing an event model. You don't know the domain yet — you're seeing it fresh. Your job is to read the model, understand the intended flows, and ask the hard questions that developers and domain experts tend to overlook because they're too close to the problem.
|
|
11
13
|
|
|
12
14
|
You're not reviewing code. You're reviewing **business logic**: flows, edge cases, error paths, missing constraints, and real-world messiness that the happy path ignores.
|
|
@@ -94,14 +96,14 @@ Every question and every summary theme must be written in plain business languag
|
|
|
94
96
|
- **Do not assume** notifications (welcome email, verification, webhook) are missing just because they aren't modelled. They may belong to a different slice or context not yet built. Only ask if the model explicitly implies a notification is needed but nothing wires to it.
|
|
95
97
|
|
|
96
98
|
### Category I: Structural shapes
|
|
97
|
-
This category is about the **shape of the model**, not any one flow's business logic — it needs the edge/relationship data and per-slice scenario counts gathered across *all* slices in Step 2, so run it once after all slices are loaded, not per-slice. Check the full element graph
|
|
99
|
+
This category is about the **shape of the model**, not any one flow's business logic — it needs the edge/relationship data and per-slice scenario counts gathered across *all* slices in Step 2, so run it once after all slices are loaded, not per-slice. Check the full element graph against the four shapes defined in `eventmodeling-core-rules`'s **Structural Shapes** section (the bed, left chair, right chair, shelf) — read that section for what each shape is, its threshold, and which one is an always-flag anti-pattern vs. a context-dependent candidate; this section only covers how to word and post the finding once you've decided it holds up.
|
|
98
100
|
|
|
99
|
-
|
|
101
|
+
Never raise a candidate off the count alone — reason about the specific events/fields/scenarios involved first, and only post if, in this domain, the count still looks like it's doing more than one job. If the context justifies it, drop it silently. Each still gets a business-worded question, per the language rule — never say "bed", "left chair", "right chair", or "shelf" in a comment; those are internal names for spotting the shape, not vocabulary for the board.
|
|
100
102
|
|
|
101
|
-
- **The bed
|
|
102
|
-
- **The left chair
|
|
103
|
-
- **The right chair
|
|
104
|
-
- **The shelf
|
|
103
|
+
- **The bed** — flag directly and confidently, not as a soft maybe — still in plain business language, but assertive: "This screen lets someone trigger more than one action from the same place — should this be split into separate steps or buttons so it's clear which one they're choosing?"
|
|
104
|
+
- **The left chair** — only if it holds up: "When this action succeeds, do all of these things always happen together, or could some happen without the others?"
|
|
105
|
+
- **The right chair** — only if it holds up: "Is this screen answering one question for the user, or several different ones bundled together?"
|
|
106
|
+
- **The shelf** — only if it holds up: "This step has a lot more cases than the ones around it — is that because it's really doing more, or because it's covering something that should be its own step?"
|
|
105
107
|
|
|
106
108
|
Each of these four is inherently about a relationship or cluster of elements, so whichever you do raise always gets a drawing per Step 4.2 in addition to its comment — a group loop around the elements involved, or an arrow if the concern is specifically about one edge among several.
|
|
107
109
|
|