@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.
- package/package.json +1 -1
- package/shared/skills/learn-eventmodelers-api/SKILL.md +22 -13
- package/stacks/modeling-kit/templates/.claude/skills/add-next-slice/SKILL.md +2 -23
- package/stacks/modeling-kit/templates/.claude/skills/add-next-slice/references/api-fallback.md +11 -0
- package/stacks/modeling-kit/templates/.claude/skills/analyze-existing-model/SKILL.md +6 -57
- package/stacks/modeling-kit/templates/.claude/skills/analyze-existing-model/references/api-fallback.md +68 -0
- package/stacks/modeling-kit/templates/.claude/skills/attributes/SKILL.md +4 -61
- package/stacks/modeling-kit/templates/.claude/skills/attributes/references/api-fallback.md +39 -0
- package/stacks/modeling-kit/templates/.claude/skills/discover-storyboard/SKILL.md +9 -53
- package/stacks/modeling-kit/templates/.claude/skills/discover-storyboard/references/api-fallback.md +63 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-applying-conways-law/SKILL.md +12 -380
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-applying-conways-law/references/examples.md +329 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-brainstorming-events/SKILL.md +45 -290
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-brainstorming-events/references/api-fallback.md +97 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-brainstorming-events/references/examples.md +35 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-checking-completeness/SKILL.md +15 -410
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-checking-completeness/references/api-fallback.md +22 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-checking-completeness/references/examples.md +397 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-core-rules/SKILL.md +182 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-automation-chains/SKILL.md +148 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-automation-chains/references/api-fallback.md +21 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-event-models/SKILL.md +48 -448
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-event-models/references/examples.md +167 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-elaborating-scenarios/SKILL.md +31 -380
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-elaborating-scenarios/references/api-fallback.md +31 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-elaborating-scenarios/references/examples.md +216 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-inputs/SKILL.md +33 -393
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-inputs/references/api-fallback.md +79 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-inputs/references/examples.md +282 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-outputs/SKILL.md +54 -454
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-outputs/references/api-fallback.md +67 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-outputs/references/examples.md +273 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-interview-protocol/SKILL.md +31 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/SKILL.md +37 -184
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/references/domain-patterns.md +58 -99
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/references/patterns.md +82 -163
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-orchestrating-event-modeling/SKILL.md +86 -78
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-orchestrating-event-modeling/references/api-fallback.md +51 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-plotting-events/SKILL.md +5 -5
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-plotting-events/references/api-fallback.md +10 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/SKILL.md +22 -51
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/references/api-fallback.md +41 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/references/examples.md +12 -9
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/references/patterns.md +1 -10
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-storyboarding-events/SKILL.md +29 -382
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-storyboarding-events/references/api-fallback.md +77 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-storyboarding-events/references/examples.md +271 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-translating-external-events/SKILL.md +12 -349
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-translating-external-events/references/examples.md +306 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models/SKILL.md +69 -107
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models/references/api-fallback.md +14 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models-checklist/SKILL.md +75 -160
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models-checklist/references/api-fallback.md +14 -0
- package/stacks/modeling-kit/templates/.claude/skills/examples/SKILL.md +3 -110
- package/stacks/modeling-kit/templates/.claude/skills/examples/references/api-fallback.md +118 -0
- package/stacks/modeling-kit/templates/.claude/skills/handle-comment/SKILL.md +5 -25
- package/stacks/modeling-kit/templates/.claude/skills/handle-comment/references/api-fallback.md +35 -0
- package/stacks/modeling-kit/templates/.claude/skills/html-screen/SKILL.md +9 -44
- package/stacks/modeling-kit/templates/.claude/skills/html-screen/references/api-fallback.md +51 -0
- package/stacks/modeling-kit/templates/.claude/skills/place-element/SKILL.md +34 -180
- package/stacks/modeling-kit/templates/.claude/skills/place-element/references/api-fallback.md +203 -0
- package/stacks/modeling-kit/templates/.claude/skills/storyboard/SKILL.md +14 -81
- package/stacks/modeling-kit/templates/.claude/skills/storyboard/references/api-fallback.md +74 -0
- package/stacks/modeling-kit/templates/.claude/skills/storyboard-screen/SKILL.md +4 -45
- package/stacks/modeling-kit/templates/.claude/skills/storyboard-screen/references/api-fallback.md +44 -0
- package/stacks/modeling-kit/templates/.claude/skills/timeline/SKILL.md +19 -88
- package/stacks/modeling-kit/templates/.claude/skills/timeline/references/api-fallback.md +91 -0
- package/stacks/modeling-kit/templates/.claude/skills/update-prompt-status/SKILL.md +1 -9
- package/stacks/modeling-kit/templates/.claude/skills/update-prompt-status/references/api-fallback.md +14 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-integrating-legacy-systems/SKILL.md +0 -674
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/references/snapshotting.md +0 -204
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: eventmodeling-validating-event-models-checklist
|
|
3
|
-
description: "Validate event
|
|
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)."
|
|
4
4
|
allowed-tools:
|
|
5
5
|
- Write
|
|
6
6
|
- Bash
|
|
@@ -10,25 +10,26 @@ allowed-tools:
|
|
|
10
10
|
|
|
11
11
|
> **Before doing anything else**, invoke the `connect` skill — if not already connected — to resolve `TOKEN`, `BOARD_ID`, `ORG_ID`, and `BASE_URL`. Do not proceed until it has completed. Consult `learn-eventmodelers-api` only if you need to look up a specific endpoint or field this file doesn't cover — don't load it eagerly.
|
|
12
12
|
|
|
13
|
+
This step applies the shared element rules in **`eventmodeling-core-rules`** — read it once per session if you haven't already; it defines what a COMMAND/EVENT/READMODEL/SCREEN/AUTOMATION is, how each is named, and the anti-patterns to reject, so this step doesn't restate them.
|
|
14
|
+
|
|
13
15
|
Prefer `mcp__eventmodelers__*` tools when available (registered by the `connect` skill) — the curl blocks below are the fallback for sessions without MCP connected.
|
|
14
16
|
|
|
15
|
-
**Purpose**: Validate any event
|
|
17
|
+
**Purpose**: Validate any event model against 12 structural checks across 6 phases. Identifies notation anti-patterns and confirms the model is internally consistent.
|
|
16
18
|
|
|
17
19
|
**Applies To**: Any domain - e-commerce, banking, SaaS, marketplace, healthcare, etc.
|
|
18
20
|
|
|
19
21
|
**When to Use**:
|
|
20
|
-
- After completing Step 2 (Event Plot) of the
|
|
21
|
-
- Alongside Step 9 (Validate), as
|
|
22
|
-
- When reviewing an existing event model
|
|
23
|
-
- When suspicious of
|
|
22
|
+
- After completing Step 2 (Event Plot) of the event modeling workflow, as an early structural check
|
|
23
|
+
- Alongside Step 9 (Validate), as an optional second pass before declaring the model complete
|
|
24
|
+
- When reviewing an existing event model
|
|
25
|
+
- When suspicious of structural issues in the model
|
|
24
26
|
|
|
25
27
|
**What It Does**:
|
|
26
28
|
1. Reads current board state (EVENT, COMMAND, READMODEL nodes) as input
|
|
27
|
-
2. Systematically applies
|
|
28
|
-
|
|
29
|
-
3. Flags anti-patterns (calculations as events, non-entity streams, etc.)
|
|
29
|
+
2. Systematically applies 12 validation checks across 6 phases
|
|
30
|
+
3. Identifies notation anti-patterns (calculations modeled as events, events mixed into the wrong entity's timeline, etc.)
|
|
30
31
|
4. Verifies read model/event distinction
|
|
31
|
-
5. Confirms
|
|
32
|
+
5. Confirms every event and command traces cleanly
|
|
32
33
|
6. Returns pass/fail verdict with evidence
|
|
33
34
|
|
|
34
35
|
---
|
|
@@ -45,66 +46,53 @@ mcp__eventmodelers__get_nodes { "boardId": "<BOARD_ID>", "type": "COMMAND" }
|
|
|
45
46
|
mcp__eventmodelers__get_nodes { "boardId": "<BOARD_ID>", "type": "READMODEL" }
|
|
46
47
|
```
|
|
47
48
|
|
|
48
|
-
**Fallback (no MCP):**
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
"$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?type=EVENT"
|
|
52
|
-
curl -s -H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" \
|
|
53
|
-
"$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?type=COMMAND"
|
|
54
|
-
curl -s -H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" \
|
|
55
|
-
"$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?type=READMODEL"
|
|
56
|
-
```
|
|
49
|
+
**Fallback (no MCP):** see `references/api-fallback.md` — "Board Context".
|
|
50
|
+
|
|
51
|
+
Also run `validate_model` (`{boardId, chapterId}`) once per chapter up front — several checklist items (Command With Multiple Issuers in Phase 1, backward-arrow / event-flow in Phase 6, read-model-source distinctions in Phase 3) have a purely structural half the tool answers directly, so start each of those from its `findings` and spend the manual effort on the semantic judgement the tool can't make.
|
|
57
52
|
|
|
58
53
|
Use the board nodes as the model input. After the checklist, use `handle-comment` to post `TASK` comments on nodes that fail checks (that skill covers the MCP `add_comment`/curl choice for comment-posting itself).
|
|
59
54
|
|
|
60
55
|
## Validation Phases (Domain-Agnostic)
|
|
61
56
|
|
|
62
|
-
### Phase 1: Event
|
|
63
|
-
- Check 1.1: Each event belongs to exactly one
|
|
64
|
-
- Check 1.2: Each command
|
|
65
|
-
- Check 1.3: No hard dependencies between command handlers (orchestrated via events only)
|
|
66
|
-
- Check 1.4: Each command is issued by exactly one thing — no COMMAND node has more than one inbound SCREEN/AUTOMATION edge
|
|
57
|
+
### Phase 1: Event & Command Ownership Validation (2 checks)
|
|
58
|
+
- Check 1.1: Each event belongs to exactly one entity/timeline
|
|
59
|
+
- Check 1.2: Each command is issued by exactly one thing — no COMMAND node has more than one inbound SCREEN/AUTOMATION edge
|
|
67
60
|
|
|
68
|
-
**Anti-pattern to catch**:
|
|
61
|
+
**Anti-pattern to catch**: a command wired from two issuers — auto-connect itself now guards against this (see `learn-eventmodelers-api` §3), so a double-issuer command found on the board is most likely a manual `set_connection` call or an edge left over from before that guard existed, not a fresh auto-connect artifact
|
|
69
62
|
|
|
70
63
|
### Phase 2: Event Quality Validation (3 checks)
|
|
71
64
|
- Check 2.1: Events represent domain facts, not calculations
|
|
72
65
|
- Check 2.2: Event data is immutable after creation
|
|
73
66
|
- Check 2.3: Event names use past tense (what actually happened)
|
|
74
67
|
|
|
75
|
-
**Anti-pattern to catch**:
|
|
68
|
+
**Anti-pattern to catch**: storing computed/aggregated data as an event
|
|
76
69
|
|
|
77
70
|
### Phase 3: Read Model vs Event Distinction (2 checks)
|
|
78
|
-
- Check 3.1: Each read model is NOT an event
|
|
79
|
-
- Check 3.2: Read model has natural query pattern
|
|
71
|
+
- Check 3.1: Each read model is NOT an event timeline
|
|
72
|
+
- Check 3.2: Read model has a natural query pattern
|
|
80
73
|
|
|
81
|
-
**Anti-pattern to catch**:
|
|
74
|
+
**Anti-pattern to catch**: confusing projections/calculations with domain facts
|
|
82
75
|
|
|
83
76
|
### Phase 4: Business Rules Validation (2 checks)
|
|
84
|
-
- Check 4.1:
|
|
85
|
-
- Check 4.2: Event preconditions are explicit (what
|
|
77
|
+
- Check 4.1: Every command's preconditions are documented explicitly
|
|
78
|
+
- Check 4.2: Event preconditions are explicit (what must already be true before a command is valid)
|
|
86
79
|
|
|
87
|
-
**Anti-pattern to catch**:
|
|
80
|
+
**Anti-pattern to catch**: business rules scattered across the model or left implicit ("obviously can't ship an unconfirmed order")
|
|
88
81
|
|
|
89
82
|
### Phase 5: Data Traceability (1 check)
|
|
90
83
|
- Check 5.1: Input → Event → Read Model traceability is complete
|
|
91
84
|
|
|
92
|
-
**Anti-pattern to catch**:
|
|
93
|
-
|
|
94
|
-
### Phase 6: Event Flow Validation (1 check)
|
|
95
|
-
- Check 6.1: No impossible event sequences (state machine is sound)
|
|
85
|
+
**Anti-pattern to catch**: command inputs that disappear, or read model fields without a source
|
|
96
86
|
|
|
97
|
-
|
|
87
|
+
### Phase 6: Event Flow Validation (2 checks)
|
|
88
|
+
- Check 6.1: No impossible event sequences (the slice-transition flow is sound)
|
|
89
|
+
- Check 6.2: No event belongs to more than one entity's timeline — an event that seems to span two entities usually means a naming or boundary mistake, not a shared fact
|
|
98
90
|
|
|
99
|
-
|
|
100
|
-
- Check 7.1: Each stream can be versioned/restored independently
|
|
91
|
+
**Anti-pattern to catch**: events that can occur in invalid combinations; a "shared" event quietly coupling two entities together
|
|
101
92
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
- Question 1: Could an architect unfamiliar with this domain understand the model in 15 minutes?
|
|
106
|
-
- Question 2: Could you change your core algorithm/calculation without changing event history?
|
|
107
|
-
- Question 3: Could this be implemented in your target technology stack (e.g., TypeScript + PostgreSQL)?
|
|
93
|
+
### Final Questions (2 checks)
|
|
94
|
+
- Question 1: Could a modeler unfamiliar with this domain understand the model in 15 minutes?
|
|
95
|
+
- Question 2: Could the business rule/calculation behind a read model change without rewriting event history?
|
|
108
96
|
|
|
109
97
|
---
|
|
110
98
|
|
|
@@ -114,7 +102,7 @@ The skill returns a validation report with:
|
|
|
114
102
|
|
|
115
103
|
### For Each Check
|
|
116
104
|
```
|
|
117
|
-
Check 1.2:
|
|
105
|
+
Check 1.2: Command Issued by Exactly One Thing
|
|
118
106
|
Status: PASS
|
|
119
107
|
Evidence: [Specific examples from your model]
|
|
120
108
|
```
|
|
@@ -122,7 +110,7 @@ Evidence: [Specific examples from your model]
|
|
|
122
110
|
### Anti-Patterns Identified (if any)
|
|
123
111
|
```
|
|
124
112
|
CRITICAL: [Anti-pattern description]
|
|
125
|
-
Problem: [Why it violates event
|
|
113
|
+
Problem: [Why it violates event modeling principles]
|
|
126
114
|
Violates: [Which checks fail]
|
|
127
115
|
Fix: [Recommended action]
|
|
128
116
|
```
|
|
@@ -130,7 +118,6 @@ Fix: [Recommended action]
|
|
|
130
118
|
### Final Verdict
|
|
131
119
|
```
|
|
132
120
|
Status: PASS (or PASS WITH WARNINGS or FAIL)
|
|
133
|
-
Implementation Ready: YES (or NO - fix issues first)
|
|
134
121
|
Confidence: [percentage]
|
|
135
122
|
```
|
|
136
123
|
|
|
@@ -151,124 +138,65 @@ CalculationPerformed {
|
|
|
151
138
|
- ReadModel: MetricView (recalculated from events)
|
|
152
139
|
```
|
|
153
140
|
|
|
154
|
-
**Why**: Calculations change
|
|
141
|
+
**Why**: Calculations change as source data changes. Events are immutable.
|
|
155
142
|
|
|
156
|
-
### 2.
|
|
157
|
-
```
|
|
158
|
-
ANTI-PATTERN:
|
|
159
|
-
One shared "OrderAggregate" class used by all handlers
|
|
160
|
-
- ConfirmOrderHandler shares OrderAggregate state
|
|
161
|
-
- ShipOrderHandler modifies same OrderAggregate
|
|
162
|
-
- Result: Tight coupling, hard to parallelize
|
|
143
|
+
### 2. Command With Multiple Issuers
|
|
163
144
|
|
|
164
|
-
|
|
165
|
-
Each handler owns its own [CommandHandler]State class
|
|
166
|
-
- ConfirmOrderState (only ConfirmOrderHandler uses)
|
|
167
|
-
- ShipOrderState (only ShipOrderHandler uses)
|
|
168
|
-
- CancelOrderState (only CancelOrderHandler uses)
|
|
169
|
-
- All reconstruct state from same events, but independently
|
|
170
|
-
```
|
|
145
|
+
A command is never issued by more than one thing — a COMMAND with 2+ inbound SCREEN/AUTOMATION edges hides which actor is actually responsible. See `place-element`'s Step 7c for the full check-and-fix mechanics (which edge to keep, how to remove the rest).
|
|
171
146
|
|
|
172
|
-
**Why**: Each
|
|
147
|
+
**Why**: Each command represents one specific trigger's decision to act — collapsing two triggers onto one command node usually means either a naming/slice-boundary mistake or a stray manual/pre-existing edge (auto-connect itself now guards against fresh occurrences — see `learn-eventmodelers-api` §3).
|
|
173
148
|
|
|
174
|
-
### 3.
|
|
149
|
+
### 3. An Event Shared Across Entities
|
|
175
150
|
```
|
|
176
151
|
ANTI-PATTERN:
|
|
177
|
-
|
|
178
|
-
StreamB → EventB → affects
|
|
179
|
-
StreamA (circular!)
|
|
152
|
+
EntityA → EventA → also placed on EntityB's timeline
|
|
180
153
|
|
|
181
154
|
CORRECT:
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
ReadModels ← consume (one-way only)
|
|
185
|
-
No feedback loops
|
|
155
|
+
EntityA → EventA (on EntityA's timeline only)
|
|
156
|
+
EntityB reacts to EventA via a read model/automation, it doesn't own it
|
|
186
157
|
```
|
|
187
158
|
|
|
188
|
-
**Why**:
|
|
189
|
-
|
|
190
|
-
### 4. Persistent State vs Ephemeral State
|
|
191
|
-
```
|
|
192
|
-
ANTI-PATTERN:
|
|
193
|
-
Treat [CommandHandler]State as persistent entity
|
|
194
|
-
- Save SubmitReviewState to database after command
|
|
195
|
-
- Load it again next time
|
|
196
|
-
- Result: Duplicates event sourcing, loses audit trail
|
|
197
|
-
|
|
198
|
-
CORRECT:
|
|
199
|
-
Reconstruct [CommandHandler]State on-demand
|
|
200
|
-
- Load events from stream
|
|
201
|
-
- Replay via evolve() to rebuild state
|
|
202
|
-
- Process command, emit outcome events
|
|
203
|
-
- Discard state (it's ephemeral, not persisted)
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
**Why**: State is derived from events, never stored. Events are source of truth. This enables consistent replay, audit trails, and time-travel debugging.
|
|
207
|
-
|
|
208
|
-
### 5. Command With Multiple Issuers
|
|
209
|
-
```
|
|
210
|
-
ANTI-PATTERN:
|
|
211
|
-
FlagLoanOverdue (COMMAND) has two inbound edges:
|
|
212
|
-
- "Flag Overdue Loans" (AUTOMATION, same column)
|
|
213
|
-
- "Adjust Due Date" (SCREEN, previous column)
|
|
214
|
-
- Result: unclear who/what actually triggers the command; validation and UI-vs-automation
|
|
215
|
-
authority checks (e.g. Role & Actor Attribution) can no longer be answered
|
|
216
|
-
|
|
217
|
-
CORRECT:
|
|
218
|
-
FlagLoanOverdue (COMMAND) has exactly one inbound edge, from the AUTOMATION that owns it.
|
|
219
|
-
If the SCREEN's user genuinely needs to trigger the same outcome, that's a second,
|
|
220
|
-
distinctly-named command (or the SCREEN issuing it directly, with the automation removed) —
|
|
221
|
-
not two issuers sharing one command.
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
**Why**: A command is never issued by more than one thing. Each command represents one specific trigger's decision to act — collapsing two triggers onto one command node hides which actor is actually responsible, and usually means either a naming/slice-boundary mistake or a stray manual/pre-existing edge (auto-connect itself now guards against this — see `learn-eventmodelers-api` §3). Fix by removing the extra edge via `set_connection` (`action: "remove"`), not by keeping both.
|
|
159
|
+
**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.
|
|
225
160
|
|
|
226
161
|
---
|
|
227
162
|
|
|
228
163
|
## Questions to Ask During Validation
|
|
229
164
|
|
|
230
|
-
**For each
|
|
231
|
-
1. "Do all events
|
|
232
|
-
2. "Could these events occur in any order, or
|
|
233
|
-
3. "Is every event
|
|
165
|
+
**For each entity's timeline**:
|
|
166
|
+
1. "Do all events on this timeline belong to the same entity?"
|
|
167
|
+
2. "Could these events occur in any order, or does sequence matter?"
|
|
168
|
+
3. "Is every event on this timeline an immutable fact that actually happened?"
|
|
234
169
|
|
|
235
|
-
**For each command
|
|
236
|
-
1. "
|
|
237
|
-
2. "
|
|
238
|
-
3. "Can I trace the state reconstruction: events → evolve() → decision?"
|
|
170
|
+
**For each command**:
|
|
171
|
+
1. "Are its preconditions written down, not just assumed?"
|
|
172
|
+
2. "Does it produce an event, or document why it's rejected?"
|
|
239
173
|
|
|
240
174
|
**For each read model**:
|
|
241
175
|
1. "Is this calculated from events via a projection?"
|
|
242
176
|
2. "Does it answer a specific query need?"
|
|
243
|
-
3. "Could its data change due to new events
|
|
244
|
-
|
|
245
|
-
**For system architecture**:
|
|
246
|
-
1. "Does each command handler operate independently (communicate via events only)?"
|
|
247
|
-
2. "Could I run two handlers' code in parallel without merge conflicts?"
|
|
248
|
-
3. "Are the only shared artifacts the event definitions?"
|
|
177
|
+
3. "Could its data change due to new events?"
|
|
249
178
|
|
|
250
179
|
---
|
|
251
180
|
|
|
252
181
|
## Success Criteria
|
|
253
182
|
|
|
254
183
|
**Model is validated when**:
|
|
255
|
-
- All
|
|
184
|
+
- All 12 checks pass (or have documented workarounds)
|
|
256
185
|
- No critical anti-patterns identified
|
|
257
|
-
-
|
|
258
|
-
- Event
|
|
259
|
-
- Ready to proceed to code generation
|
|
186
|
+
- Both final questions answer YES
|
|
187
|
+
- Event modeling principles are clearly upheld
|
|
260
188
|
|
|
261
189
|
**Model needs fixes when**:
|
|
262
190
|
- Any check fails with clear evidence
|
|
263
191
|
- Anti-patterns identified with specific violations
|
|
264
|
-
-
|
|
192
|
+
- A final question has a NO answer
|
|
265
193
|
- Fixes are straightforward and targeted
|
|
266
194
|
|
|
267
195
|
**Model should be redesigned when**:
|
|
268
196
|
- Multiple phases fail
|
|
269
|
-
-
|
|
197
|
+
- Structural assumptions are fundamentally flawed
|
|
270
198
|
- Anti-patterns are systemic and pervasive
|
|
271
|
-
- Would require rewriting core event
|
|
199
|
+
- Would require rewriting the core event timeline
|
|
272
200
|
|
|
273
201
|
---
|
|
274
202
|
|
|
@@ -278,25 +206,13 @@ not two issuers sharing one command.
|
|
|
278
206
|
When you see something like "CalculationDone" or "ReviewRatingUpdated":
|
|
279
207
|
- Ask: "Is this immutable and caused by a user/system action?"
|
|
280
208
|
- If NO → It's a read model, not an event
|
|
281
|
-
- Fix: Remove from events, create read model projection instead
|
|
282
|
-
|
|
283
|
-
### Pattern: Shared vs Isolated State
|
|
284
|
-
When you see "ReviewAggregate" used by multiple handlers:
|
|
285
|
-
- Ask: "Could SubmitReviewHandler and ApproveReviewHandler work on separate files?"
|
|
286
|
-
- If NO → State classes aren't properly isolated
|
|
287
|
-
- Fix: Create SubmitReviewState and ApproveReviewState, each handler owns one
|
|
288
|
-
|
|
289
|
-
### Pattern: Persistent vs Ephemeral State
|
|
290
|
-
When state is saved to database after a command:
|
|
291
|
-
- Ask: "Is this state only needed during command processing?"
|
|
292
|
-
- If YES → It's ephemeral, reconstruct from events instead
|
|
293
|
-
- Fix: Load events, replay via evolve(), process command, discard state
|
|
209
|
+
- Fix: Remove from events, create a read model projection instead
|
|
294
210
|
|
|
295
211
|
### Pattern: Data That Doesn't Trace
|
|
296
212
|
When a read model field appears without source:
|
|
297
213
|
- Ask: "Where did this come from?"
|
|
298
|
-
- If no event source → Add event or remove field
|
|
299
|
-
- If sourced from calculation → Verify it's in
|
|
214
|
+
- If no event source → Add the event or remove the field
|
|
215
|
+
- If sourced from a calculation → Verify it's in the read model, not the event
|
|
300
216
|
|
|
301
217
|
---
|
|
302
218
|
|
|
@@ -315,19 +231,19 @@ Step 3-8: Storyboard, Inputs, Outputs, Conway's Law, Scenarios, Completeness
|
|
|
315
231
|
↓
|
|
316
232
|
Step 9: Validate (eventmodeling-validating-event-models)
|
|
317
233
|
↓
|
|
318
|
-
→ RUN eventmodeling-validating-event-models-checklist again (
|
|
234
|
+
→ RUN eventmodeling-validating-event-models-checklist again (final structural pass)
|
|
319
235
|
↓
|
|
320
|
-
PASS → Step 10: Slice, Step 11: Document Reasoning
|
|
236
|
+
PASS → Step 10: Slice, Step 11: Document Reasoning
|
|
321
237
|
FAIL → Fix identified issues
|
|
322
238
|
```
|
|
323
239
|
|
|
324
|
-
Running the checklist after Step 2 prevents wasting time on later steps if core events are flawed.
|
|
240
|
+
Running the checklist after Step 2 prevents wasting time on later steps if the core events are flawed.
|
|
325
241
|
|
|
326
242
|
---
|
|
327
243
|
|
|
328
244
|
## Checklist Questions by Domain
|
|
329
245
|
|
|
330
|
-
The skill applies the same
|
|
246
|
+
The skill applies the same 12 checks regardless of domain. Here's how to think about it in different contexts:
|
|
331
247
|
|
|
332
248
|
**E-commerce domain**:
|
|
333
249
|
- Events: OrderCreated, OrderConfirmed, PaymentAuthorized, OrderShipped
|
|
@@ -351,26 +267,26 @@ The principle is the same across all domains: **immutable facts as events, calcu
|
|
|
351
267
|
|
|
352
268
|
## Tips for Best Results
|
|
353
269
|
|
|
354
|
-
1. **Be specific**: List actual event
|
|
355
|
-
2. **Reference your documentation**: Link to or quote from your step 1-7 documents
|
|
356
|
-
3. **Provide context**: Explain what your domain is
|
|
357
|
-
4. **Ask follow-ups**: If a check flags an issue, ask "How do I fix this specifically?"
|
|
358
|
-
5. **Iterate**: Run again after making fixes to confirm all checks pass
|
|
270
|
+
1. **Be specific**: List actual event and command names from your model
|
|
271
|
+
2. **Reference your documentation**: Link to or quote from your step 1-7 documents
|
|
272
|
+
3. **Provide context**: Explain what your domain is
|
|
273
|
+
4. **Ask follow-ups**: If a check flags an issue, ask "How do I fix this specifically?"
|
|
274
|
+
5. **Iterate**: Run again after making fixes to confirm all checks pass
|
|
359
275
|
|
|
360
276
|
## Quality Checklist
|
|
361
277
|
|
|
362
|
-
- [ ] All
|
|
363
|
-
- [ ] Every FAIL result includes the specific event,
|
|
278
|
+
- [ ] All 12 checks evaluated — no check skipped without documented justification
|
|
279
|
+
- [ ] Every FAIL result includes the specific event, command, or entity that violated the check
|
|
364
280
|
- [ ] Anti-patterns identified by name with the exact model element that triggered the flag
|
|
365
281
|
- [ ] Final verdict is one of: PASS / PASS WITH WARNINGS / FAIL — no ambiguous outcomes
|
|
366
|
-
- [ ]
|
|
282
|
+
- [ ] Both final questions answered YES before declaring the model ready
|
|
367
283
|
- [ ] Any FAIL result has a recommended fix, not just a problem statement
|
|
368
284
|
|
|
369
285
|
---
|
|
370
286
|
|
|
371
287
|
## Related Skills
|
|
372
288
|
|
|
373
|
-
- **eventmodeling-orchestrating-event-modeling**: Main skill coordinating the
|
|
289
|
+
- **eventmodeling-orchestrating-event-modeling**: Main skill coordinating the full event modeling process
|
|
374
290
|
- **eventmodeling-brainstorming-events**: Extract events from requirements (Step 1)
|
|
375
291
|
- **eventmodeling-plotting-events**: Sequence events chronologically (Step 2)
|
|
376
292
|
- **eventmodeling-designing-event-models**: Design your complete event model
|
|
@@ -380,6 +296,5 @@ The principle is the same across all domains: **immutable facts as events, calcu
|
|
|
380
296
|
|
|
381
297
|
## Validation Checklist Reference
|
|
382
298
|
|
|
383
|
-
The
|
|
299
|
+
The 12-point checklist is defined in the **Validation Phases** section above.
|
|
384
300
|
Each check includes the anti-pattern to catch and questions to ask when evaluating your model.
|
|
385
|
-
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Event Model Validation Checklist Skill — curl Fallback Calls
|
|
2
|
+
|
|
3
|
+
Only needed when MCP is not connected. Every call below has an MCP equivalent in the main SKILL.md — always prefer that.
|
|
4
|
+
|
|
5
|
+
## Board Context
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
curl -s -H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" \
|
|
9
|
+
"$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?type=EVENT"
|
|
10
|
+
curl -s -H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" \
|
|
11
|
+
"$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?type=COMMAND"
|
|
12
|
+
curl -s -H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" \
|
|
13
|
+
"$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?type=READMODEL"
|
|
14
|
+
```
|
|
@@ -45,93 +45,11 @@ mcp__eventmodelers__add_field_examples { "boardId": "$BOARD_ID", "cellName": "<t
|
|
|
45
45
|
|
|
46
46
|
If this succeeds, skip straight to Step 6 (report back), describing the fields the tool reports as changed. Use the manual fallback flow below (Steps 2–5) only if MCP isn't connected.
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
Try the resolution strategies in order until one succeeds.
|
|
51
|
-
|
|
52
|
-
### 2a — UUID
|
|
53
|
-
If `target` looks like a UUID (pattern `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`), fetch it directly:
|
|
54
|
-
|
|
55
|
-
```bash
|
|
56
|
-
curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/$target" \
|
|
57
|
-
-H "x-user-id: examples-skill"
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
### 2b — Name search
|
|
61
|
-
If `target` is not a UUID, search by name:
|
|
62
|
-
|
|
63
|
-
```bash
|
|
64
|
-
curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/events/search?name=$(python3 -c 'import urllib.parse,sys; print(urllib.parse.quote(sys.argv[1]))' "$target")" \
|
|
65
|
-
-H "x-user-id: examples-skill"
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
Pick the best match (exact title match preferred; case-insensitive). If multiple matches exist, list them and ask the user to pick one.
|
|
69
|
-
|
|
70
|
-
### 2c — Cell name (spreadsheet-style, e.g. "B3")
|
|
71
|
-
If `target` matches the pattern `[A-Z]+[0-9]+`:
|
|
72
|
-
|
|
73
|
-
1. Fetch all chapters on the board to find the relevant timeline:
|
|
74
|
-
|
|
75
|
-
```bash
|
|
76
|
-
curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?type=CHAPTER" \
|
|
77
|
-
-H "x-user-id: examples-skill"
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
If multiple chapters exist, ask the user which one to use.
|
|
81
|
-
|
|
82
|
-
2. Fetch the chapter **fresh** to decode the grid — never use cached chapter data, as cells are updated frequently:
|
|
83
|
-
|
|
84
|
-
```bash
|
|
85
|
-
curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/$CHAPTER_ID" \
|
|
86
|
-
-H "x-user-id: examples-skill"
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
From `meta.timelineData`, decode the cell name into a `cellId`:
|
|
90
|
-
- Column letter(s) → 0-based column index (A=0, B=1, … Z=25, AA=26, …)
|
|
91
|
-
- Row digit → 0-based row index (1→0, 2→1, …)
|
|
92
|
-
- Find the matching column in `columns` and the matching row in `rows`.
|
|
93
|
-
- Compute: **`CELL_ID = row.id + "-" + column.id`** (cell IDs are always `<rowId>-<columnId>`).
|
|
94
|
-
|
|
95
|
-
3. **Always fetch the cell live** to get the current node list — do not rely on the `nodeId` in the chapter's cell data, as it may be stale. No MCP equivalent: `get_nodes` only filters by `type`, not `cellId`:
|
|
96
|
-
|
|
97
|
-
```bash
|
|
98
|
-
curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?cellId=$CELL_ID" \
|
|
99
|
-
-H "x-user-id: examples-skill"
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
Use the first non-CHAPTER result (filter out CHAPTER type).
|
|
103
|
-
|
|
104
|
-
If no element is found after all strategies, stop and tell the user what was tried.
|
|
105
|
-
|
|
106
|
-
Save the resolved node as `TARGET_NODE` (full JSON including `id`, `meta`, `edges`).
|
|
48
|
+
**Fallback (no MCP):** see `references/api-fallback.md` — "Step 2 — Resolve the element".
|
|
107
49
|
|
|
108
50
|
---
|
|
109
51
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
Collect nearby elements to understand the domain context and generate consistent examples. **Never fetch all board nodes.** Only fetch specific nodes you already have IDs for.
|
|
113
|
-
|
|
114
|
-
### 3a — Nodes from edges
|
|
115
|
-
If `TARGET_NODE.edges` is non-empty, fetch each connected node individually by its ID:
|
|
116
|
-
|
|
117
|
-
```bash
|
|
118
|
-
curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/<EDGE_NODE_ID>" \
|
|
119
|
-
-H "x-user-id: examples-skill"
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
Fetch all edge-connected nodes in parallel (one request per node ID).
|
|
123
|
-
|
|
124
|
-
### 3b — Nodes from the same column (cell-based resolution only)
|
|
125
|
-
If you resolved `TARGET_NODE` via a cell name (Step 2c), you already have the full chapter `cells` array in memory. Use it — **no extra API call needed**:
|
|
126
|
-
|
|
127
|
-
- Find all cells that share the same `colId` as `TARGET_NODE`'s cell.
|
|
128
|
-
- Collect their `nodeId` values (skip the target itself and any cell without a `nodeId`).
|
|
129
|
-
- Fetch each of those nodes individually by ID (in parallel):
|
|
130
|
-
|
|
131
|
-
```bash
|
|
132
|
-
curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/<NODE_ID>" \
|
|
133
|
-
-H "x-user-id: examples-skill"
|
|
134
|
-
```
|
|
52
|
+
**Fallback (no MCP):** see `references/api-fallback.md` — "Step 3 — Load linked elements for context".
|
|
135
53
|
|
|
136
54
|
### 3c — Read neighbour fields
|
|
137
55
|
For each neighbour element collected above (COMMAND, EVENT, READMODEL), extract its `meta.fields` and their existing `example` values. This gives you a pool of consistent values to reuse — e.g. if a COMMAND already has `email: "jane@example.com"`, use the same email in the linked EVENT.
|
|
@@ -183,32 +101,7 @@ mcp__eventmodelers__submit_node_events {
|
|
|
183
101
|
}
|
|
184
102
|
```
|
|
185
103
|
|
|
186
|
-
**Fallback (no MCP
|
|
187
|
-
|
|
188
|
-
```bash
|
|
189
|
-
python3 - <<EOF > /tmp/examples_payload.json
|
|
190
|
-
import json, time, uuid
|
|
191
|
-
payload = [{
|
|
192
|
-
"id": str(uuid.uuid4()),
|
|
193
|
-
"eventType": "node:changed",
|
|
194
|
-
"nodeId": "<TARGET_NODE.id>",
|
|
195
|
-
"boardId": "<BOARD_ID>",
|
|
196
|
-
"timestamp": int(time.time() * 1000),
|
|
197
|
-
"changedAttributes": ["meta.fields"],
|
|
198
|
-
"meta": {
|
|
199
|
-
"fields": <updated-fields-array as Python list>
|
|
200
|
-
}
|
|
201
|
-
}]
|
|
202
|
-
print(json.dumps(payload))
|
|
203
|
-
EOF
|
|
204
|
-
|
|
205
|
-
curl -s -w "\n%{http_code}" -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/events" \
|
|
206
|
-
-H "Content-Type: application/json" \
|
|
207
|
-
-H "x-token: $TOKEN" \
|
|
208
|
-
-H "x-board-id: $BOARD_ID" \
|
|
209
|
-
-H "x-user-id: examples-skill" \
|
|
210
|
-
--data-binary @/tmp/examples_payload.json
|
|
211
|
-
```
|
|
104
|
+
**Fallback (no MCP):** see `references/api-fallback.md` — "Step 5 — Write the update".
|
|
212
105
|
|
|
213
106
|
Verify the response is HTTP 200. If it fails, report the error and stop.
|
|
214
107
|
|