@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eventmodelers/cli",
3
- "version": "1.0.38",
3
+ "version": "1.0.40",
4
4
  "description": "Eventmodelers CLI — real-time Claude agent + skills for Claude Code, for any stack (Node, Supabase, Axon, Cratis, or modeling-only)",
5
5
  "type": "module",
6
6
  "bin": {
@@ -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
@@ -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`, add two fields **at the scenario level** (not inside `then`):
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
 
@@ -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 12 structural checks across 6 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)."
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 12 structural checks across 6 phases. Identifies notation anti-patterns and confirms the model is internally consistent.
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 12 validation checks across 6 phases
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 12 checks pass (or have documented workarounds)
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 12 checks regardless of domain. Here's how to think about it in different contexts:
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 12 checks evaluated — no check skipped without documented justification
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 12-point checklist is defined in the **Validation Phases** section above.
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 for these four known shapes. Each still gets a business-worded question, per the language rulenever say "bed", "left-chair", "right-chair", or "shelf" in a comment; those are your internal names for spotting the shape, not vocabulary for the board.
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
- Only one of these four is an actual anti-pattern — invalid regardless of context. The other three are **candidates**: a count crossing the rough threshold means "worth checking against the business context," not "wrong." 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.
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 (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. Flag this 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?"
102
- - **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 asking. Example, only if it holds up: "When this action succeeds, do all of these things always happen together, or could some happen without the others?"
103
- - **The right chair (candidate)** — one read model 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 asking. Example, only if it holds up: "Is this screen answering one question for the user, or several different ones bundled together?"
104
- - **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 asking. Example, 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?"
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