@eventmodelers/cli 1.0.37 → 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 +10 -3
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-applying-conways-law/SKILL.md +3 -61
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-brainstorming-events/SKILL.md +24 -93
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-checking-completeness/SKILL.md +2 -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 +23 -7
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-event-models/SKILL.md +50 -223
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-event-models/references/examples.md +30 -120
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-elaborating-scenarios/SKILL.md +3 -78
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-inputs/SKILL.md +3 -50
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-outputs/SKILL.md +3 -54
- 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 +27 -67
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/references/domain-patterns.md +15 -15
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/references/patterns.md +44 -52
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-orchestrating-event-modeling/SKILL.md +14 -15
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-plotting-events/SKILL.md +4 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/SKILL.md +3 -15
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-storyboarding-events/SKILL.md +3 -50
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-translating-external-events/SKILL.md +4 -56
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models/SKILL.md +58 -97
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models-checklist/SKILL.md +72 -127
- package/stacks/modeling-kit/templates/.claude/skills/place-element/SKILL.md +15 -1
- package/stacks/modeling-kit/templates/.claude/skills/place-element/references/api-fallback.md +11 -1
|
@@ -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
|
---
|
|
@@ -53,52 +54,45 @@ Use the board nodes as the model input. After the checklist, use `handle-comment
|
|
|
53
54
|
|
|
54
55
|
## Validation Phases (Domain-Agnostic)
|
|
55
56
|
|
|
56
|
-
### Phase 1: Event
|
|
57
|
-
- Check 1.1: Each event belongs to exactly one
|
|
58
|
-
- Check 1.2: Each command
|
|
59
|
-
- Check 1.3: No hard dependencies between command handlers (orchestrated via events only)
|
|
60
|
-
- 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
|
|
61
60
|
|
|
62
|
-
**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
|
|
63
62
|
|
|
64
63
|
### Phase 2: Event Quality Validation (3 checks)
|
|
65
64
|
- Check 2.1: Events represent domain facts, not calculations
|
|
66
65
|
- Check 2.2: Event data is immutable after creation
|
|
67
66
|
- Check 2.3: Event names use past tense (what actually happened)
|
|
68
67
|
|
|
69
|
-
**Anti-pattern to catch**:
|
|
68
|
+
**Anti-pattern to catch**: storing computed/aggregated data as an event
|
|
70
69
|
|
|
71
70
|
### Phase 3: Read Model vs Event Distinction (2 checks)
|
|
72
|
-
- Check 3.1: Each read model is NOT an event
|
|
73
|
-
- 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
|
|
74
73
|
|
|
75
|
-
**Anti-pattern to catch**:
|
|
74
|
+
**Anti-pattern to catch**: confusing projections/calculations with domain facts
|
|
76
75
|
|
|
77
76
|
### Phase 4: Business Rules Validation (2 checks)
|
|
78
|
-
- Check 4.1:
|
|
79
|
-
- 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)
|
|
80
79
|
|
|
81
|
-
**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")
|
|
82
81
|
|
|
83
82
|
### Phase 5: Data Traceability (1 check)
|
|
84
83
|
- Check 5.1: Input → Event → Read Model traceability is complete
|
|
85
84
|
|
|
86
|
-
**Anti-pattern to catch**:
|
|
87
|
-
|
|
88
|
-
### Phase 6: Event Flow Validation (1 check)
|
|
89
|
-
- Check 6.1: No impossible event sequences (state machine is sound)
|
|
90
|
-
|
|
91
|
-
**Anti-pattern to catch**: Events that can occur in invalid state combinations
|
|
85
|
+
**Anti-pattern to catch**: command inputs that disappear, or read model fields without a source
|
|
92
86
|
|
|
93
|
-
### Phase
|
|
94
|
-
- Check
|
|
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
|
|
95
90
|
|
|
96
|
-
**Anti-pattern to catch**:
|
|
91
|
+
**Anti-pattern to catch**: events that can occur in invalid combinations; a "shared" event quietly coupling two entities together
|
|
97
92
|
|
|
98
|
-
### Final Questions (
|
|
99
|
-
- Question 1: Could
|
|
100
|
-
- Question 2: Could
|
|
101
|
-
- 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?
|
|
102
96
|
|
|
103
97
|
---
|
|
104
98
|
|
|
@@ -108,7 +102,7 @@ The skill returns a validation report with:
|
|
|
108
102
|
|
|
109
103
|
### For Each Check
|
|
110
104
|
```
|
|
111
|
-
Check 1.2:
|
|
105
|
+
Check 1.2: Command Issued by Exactly One Thing
|
|
112
106
|
Status: PASS
|
|
113
107
|
Evidence: [Specific examples from your model]
|
|
114
108
|
```
|
|
@@ -116,7 +110,7 @@ Evidence: [Specific examples from your model]
|
|
|
116
110
|
### Anti-Patterns Identified (if any)
|
|
117
111
|
```
|
|
118
112
|
CRITICAL: [Anti-pattern description]
|
|
119
|
-
Problem: [Why it violates event
|
|
113
|
+
Problem: [Why it violates event modeling principles]
|
|
120
114
|
Violates: [Which checks fail]
|
|
121
115
|
Fix: [Recommended action]
|
|
122
116
|
```
|
|
@@ -124,7 +118,6 @@ Fix: [Recommended action]
|
|
|
124
118
|
### Final Verdict
|
|
125
119
|
```
|
|
126
120
|
Status: PASS (or PASS WITH WARNINGS or FAIL)
|
|
127
|
-
Implementation Ready: YES (or NO - fix issues first)
|
|
128
121
|
Confidence: [percentage]
|
|
129
122
|
```
|
|
130
123
|
|
|
@@ -145,100 +138,65 @@ CalculationPerformed {
|
|
|
145
138
|
- ReadModel: MetricView (recalculated from events)
|
|
146
139
|
```
|
|
147
140
|
|
|
148
|
-
**Why**: Calculations change
|
|
141
|
+
**Why**: Calculations change as source data changes. Events are immutable.
|
|
149
142
|
|
|
150
|
-
### 2.
|
|
143
|
+
### 2. Command With Multiple Issuers
|
|
151
144
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
**Why**: Each handler is a micro-slice. Separate state classes maintain isolation, enable parallel teams, prevent merge conflicts.
|
|
155
|
-
|
|
156
|
-
### 3. Circular Dependencies
|
|
157
|
-
```
|
|
158
|
-
ANTI-PATTERN:
|
|
159
|
-
StreamA → EventA → affects
|
|
160
|
-
StreamB → EventB → affects
|
|
161
|
-
StreamA (circular!)
|
|
162
|
-
|
|
163
|
-
CORRECT:
|
|
164
|
-
StreamA → EventA → Event Bus
|
|
165
|
-
StreamB → EventB → Event Bus
|
|
166
|
-
ReadModels ← consume (one-way only)
|
|
167
|
-
No feedback loops
|
|
168
|
-
```
|
|
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).
|
|
169
146
|
|
|
170
|
-
**Why**:
|
|
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).
|
|
171
148
|
|
|
172
|
-
###
|
|
149
|
+
### 3. An Event Shared Across Entities
|
|
173
150
|
```
|
|
174
151
|
ANTI-PATTERN:
|
|
175
|
-
|
|
176
|
-
- Save SubmitReviewState to database after command
|
|
177
|
-
- Load it again next time
|
|
178
|
-
- Result: Duplicates event sourcing, loses audit trail
|
|
152
|
+
EntityA → EventA → also placed on EntityB's timeline
|
|
179
153
|
|
|
180
154
|
CORRECT:
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
- Replay via evolve() to rebuild state
|
|
184
|
-
- Process command, emit outcome events
|
|
185
|
-
- Discard state (it's ephemeral, not persisted)
|
|
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
|
-
### 5. Command With Multiple Issuers
|
|
191
|
-
|
|
192
|
-
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).
|
|
193
|
-
|
|
194
|
-
**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).
|
|
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.
|
|
195
160
|
|
|
196
161
|
---
|
|
197
162
|
|
|
198
163
|
## Questions to Ask During Validation
|
|
199
164
|
|
|
200
|
-
**For each
|
|
201
|
-
1. "Do all events
|
|
202
|
-
2. "Could these events occur in any order, or
|
|
203
|
-
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?"
|
|
204
169
|
|
|
205
|
-
**For each command
|
|
206
|
-
1. "
|
|
207
|
-
2. "
|
|
208
|
-
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?"
|
|
209
173
|
|
|
210
174
|
**For each read model**:
|
|
211
175
|
1. "Is this calculated from events via a projection?"
|
|
212
176
|
2. "Does it answer a specific query need?"
|
|
213
|
-
3. "Could its data change due to new events
|
|
214
|
-
|
|
215
|
-
**For system architecture**:
|
|
216
|
-
1. "Does each command handler operate independently (communicate via events only)?"
|
|
217
|
-
2. "Could I run two handlers' code in parallel without merge conflicts?"
|
|
218
|
-
3. "Are the only shared artifacts the event definitions?"
|
|
177
|
+
3. "Could its data change due to new events?"
|
|
219
178
|
|
|
220
179
|
---
|
|
221
180
|
|
|
222
181
|
## Success Criteria
|
|
223
182
|
|
|
224
183
|
**Model is validated when**:
|
|
225
|
-
- All
|
|
184
|
+
- All 12 checks pass (or have documented workarounds)
|
|
226
185
|
- No critical anti-patterns identified
|
|
227
|
-
-
|
|
228
|
-
- Event
|
|
229
|
-
- Ready to proceed to code generation
|
|
186
|
+
- Both final questions answer YES
|
|
187
|
+
- Event modeling principles are clearly upheld
|
|
230
188
|
|
|
231
189
|
**Model needs fixes when**:
|
|
232
190
|
- Any check fails with clear evidence
|
|
233
191
|
- Anti-patterns identified with specific violations
|
|
234
|
-
-
|
|
192
|
+
- A final question has a NO answer
|
|
235
193
|
- Fixes are straightforward and targeted
|
|
236
194
|
|
|
237
195
|
**Model should be redesigned when**:
|
|
238
196
|
- Multiple phases fail
|
|
239
|
-
-
|
|
197
|
+
- Structural assumptions are fundamentally flawed
|
|
240
198
|
- Anti-patterns are systemic and pervasive
|
|
241
|
-
- Would require rewriting core event
|
|
199
|
+
- Would require rewriting the core event timeline
|
|
242
200
|
|
|
243
201
|
---
|
|
244
202
|
|
|
@@ -248,25 +206,13 @@ A command is never issued by more than one thing — a COMMAND with 2+ inbound S
|
|
|
248
206
|
When you see something like "CalculationDone" or "ReviewRatingUpdated":
|
|
249
207
|
- Ask: "Is this immutable and caused by a user/system action?"
|
|
250
208
|
- If NO → It's a read model, not an event
|
|
251
|
-
- Fix: Remove from events, create read model projection instead
|
|
252
|
-
|
|
253
|
-
### Pattern: Shared vs Isolated State
|
|
254
|
-
When you see "ReviewAggregate" used by multiple handlers:
|
|
255
|
-
- Ask: "Could SubmitReviewHandler and ApproveReviewHandler work on separate files?"
|
|
256
|
-
- If NO → State classes aren't properly isolated
|
|
257
|
-
- Fix: Create SubmitReviewState and ApproveReviewState, each handler owns one
|
|
258
|
-
|
|
259
|
-
### Pattern: Persistent vs Ephemeral State
|
|
260
|
-
When state is saved to database after a command:
|
|
261
|
-
- Ask: "Is this state only needed during command processing?"
|
|
262
|
-
- If YES → It's ephemeral, reconstruct from events instead
|
|
263
|
-
- Fix: Load events, replay via evolve(), process command, discard state
|
|
209
|
+
- Fix: Remove from events, create a read model projection instead
|
|
264
210
|
|
|
265
211
|
### Pattern: Data That Doesn't Trace
|
|
266
212
|
When a read model field appears without source:
|
|
267
213
|
- Ask: "Where did this come from?"
|
|
268
|
-
- If no event source → Add event or remove field
|
|
269
|
-
- 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
|
|
270
216
|
|
|
271
217
|
---
|
|
272
218
|
|
|
@@ -285,19 +231,19 @@ Step 3-8: Storyboard, Inputs, Outputs, Conway's Law, Scenarios, Completeness
|
|
|
285
231
|
↓
|
|
286
232
|
Step 9: Validate (eventmodeling-validating-event-models)
|
|
287
233
|
↓
|
|
288
|
-
→ RUN eventmodeling-validating-event-models-checklist again (
|
|
234
|
+
→ RUN eventmodeling-validating-event-models-checklist again (final structural pass)
|
|
289
235
|
↓
|
|
290
|
-
PASS → Step 10: Slice, Step 11: Document Reasoning
|
|
236
|
+
PASS → Step 10: Slice, Step 11: Document Reasoning
|
|
291
237
|
FAIL → Fix identified issues
|
|
292
238
|
```
|
|
293
239
|
|
|
294
|
-
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.
|
|
295
241
|
|
|
296
242
|
---
|
|
297
243
|
|
|
298
244
|
## Checklist Questions by Domain
|
|
299
245
|
|
|
300
|
-
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:
|
|
301
247
|
|
|
302
248
|
**E-commerce domain**:
|
|
303
249
|
- Events: OrderCreated, OrderConfirmed, PaymentAuthorized, OrderShipped
|
|
@@ -321,26 +267,26 @@ The principle is the same across all domains: **immutable facts as events, calcu
|
|
|
321
267
|
|
|
322
268
|
## Tips for Best Results
|
|
323
269
|
|
|
324
|
-
1. **Be specific**: List actual event
|
|
325
|
-
2. **Reference your documentation**: Link to or quote from your step 1-7 documents
|
|
326
|
-
3. **Provide context**: Explain what your domain is
|
|
327
|
-
4. **Ask follow-ups**: If a check flags an issue, ask "How do I fix this specifically?"
|
|
328
|
-
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
|
|
329
275
|
|
|
330
276
|
## Quality Checklist
|
|
331
277
|
|
|
332
|
-
- [ ] All
|
|
333
|
-
- [ ] 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
|
|
334
280
|
- [ ] Anti-patterns identified by name with the exact model element that triggered the flag
|
|
335
281
|
- [ ] Final verdict is one of: PASS / PASS WITH WARNINGS / FAIL — no ambiguous outcomes
|
|
336
|
-
- [ ]
|
|
282
|
+
- [ ] Both final questions answered YES before declaring the model ready
|
|
337
283
|
- [ ] Any FAIL result has a recommended fix, not just a problem statement
|
|
338
284
|
|
|
339
285
|
---
|
|
340
286
|
|
|
341
287
|
## Related Skills
|
|
342
288
|
|
|
343
|
-
- **eventmodeling-orchestrating-event-modeling**: Main skill coordinating the
|
|
289
|
+
- **eventmodeling-orchestrating-event-modeling**: Main skill coordinating the full event modeling process
|
|
344
290
|
- **eventmodeling-brainstorming-events**: Extract events from requirements (Step 1)
|
|
345
291
|
- **eventmodeling-plotting-events**: Sequence events chronologically (Step 2)
|
|
346
292
|
- **eventmodeling-designing-event-models**: Design your complete event model
|
|
@@ -350,6 +296,5 @@ The principle is the same across all domains: **immutable facts as events, calcu
|
|
|
350
296
|
|
|
351
297
|
## Validation Checklist Reference
|
|
352
298
|
|
|
353
|
-
The
|
|
299
|
+
The 12-point checklist is defined in the **Validation Phases** section above.
|
|
354
300
|
Each check includes the anti-pattern to catch and questions to ask when evaluating your model.
|
|
355
|
-
|
|
@@ -196,9 +196,23 @@ Cell IDs are always `<rowId>-<columnId>` — no cell array search needed.
|
|
|
196
196
|
|
|
197
197
|
**Same swimlane for events emitted by the same command.** When one command emits more than one event, each event still gets its own column (per the hard rule above), but all of them belong in the *same* swimlane row, placed in adjacent columns immediately after the command. Do not scatter a command's sibling events across different swimlane rows — one command producing multiple events is one system doing multiple things in sequence, not several systems reacting independently.
|
|
198
198
|
|
|
199
|
+
**One COMMAND / READMODEL / SCREEN / AUTOMATION per column — server-enforced, not just a heuristic.** Unlike the EVENT rule above (which this skill has to check for itself), the server itself rejects a second `COMMAND`, `READMODEL`, `SCREEN`/`HTML_SCREEN`, or `AUTOMATION` landing in a column that already has one of that type — across *every* row of the relevant lane (`interaction` for COMMAND/READMODEL, `actor` for SCREEN/AUTOMATION), not only the exact target cell. A board can have several separate `interaction` or `actor` rows, so the target cell itself can be empty and the placement will still fail with a `ValidationError` ("Column already has a … node … — only one … is allowed per column"). Treat that rejection exactly like a same-cell conflict in the table below — insert a new column rather than retrying the same one.
|
|
200
|
+
|
|
199
201
|
**Check if the cell is already occupied.**
|
|
200
202
|
|
|
201
|
-
**
|
|
203
|
+
**Fastest path**: use the `cells` array you already fetched in Step 3 via `get_node` (`projection: "cells"`) on the chapter/timeline node — `cells` is a sparse array, so a `nodeId` absent from the entry for `CELL_ID` means the cell is empty. Also scan it for the column-wide conflict from the rule above: any entry with `colId === columnId` and `nodeType === elementType` (for COMMAND/READMODEL/SCREEN/AUTOMATION) means the column is occupied even though `CELL_ID` itself is free. This avoids an extra round-trip, but can be stale if a column was just created in Step 5 — re-fetch first in that case.
|
|
204
|
+
|
|
205
|
+
**No direct MCP equivalent** for querying by cell/column: `get_nodes` only filters by `type`. The REST API does support it directly though — `GET /nodes` takes `cellId` **or** `colId`, both requiring `timelineId`:
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
# Same-cell occupancy — returns [] if empty, or [nodeRecord] if occupied
|
|
209
|
+
curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?cellId=$CELL_ID&timelineId=$TIMELINE_ID"
|
|
210
|
+
|
|
211
|
+
# Column-wide occupancy (any row) — optionally add &type=READMODEL to narrow to one element type
|
|
212
|
+
curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?colId=$COLUMN_ID&timelineId=$TIMELINE_ID"
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
Use this REST call (see the curl fallback below) when you don't already have fresh `timelineData` loaded, instead of re-fetching the whole chapter node just to check occupancy.
|
|
202
216
|
|
|
203
217
|
**Fallback (no MCP):** see `references/api-fallback.md` — "Step 6 — Check cell occupancy".
|
|
204
218
|
|
package/stacks/modeling-kit/templates/.claude/skills/place-element/references/api-fallback.md
CHANGED
|
@@ -55,10 +55,20 @@ Response: `{ "columnId": "<uuid>", "index": <n>, "totalColumns": <n> }`
|
|
|
55
55
|
|
|
56
56
|
## Step 6 — Check cell occupancy
|
|
57
57
|
|
|
58
|
+
`GET /nodes` takes `cellId` **or** `colId`, both requiring `timelineId` — no need to re-fetch and parse the whole chapter node just for this:
|
|
59
|
+
|
|
58
60
|
```bash
|
|
59
|
-
|
|
61
|
+
# Same-cell occupancy — [] if empty, [nodeRecord] if occupied
|
|
62
|
+
curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?cellId=$CELL_ID&timelineId=$TIMELINE_ID"
|
|
63
|
+
|
|
64
|
+
# Same-column occupancy, across every row of the timeline — add &type=<elementType> to narrow
|
|
65
|
+
# (the server enforces one COMMAND/READMODEL/SCREEN/HTML_SCREEN/AUTOMATION per column even when
|
|
66
|
+
# the target cell itself is empty — see SKILL.md)
|
|
67
|
+
curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?colId=$COLUMN_ID&timelineId=$TIMELINE_ID"
|
|
60
68
|
```
|
|
61
69
|
|
|
70
|
+
If you already have fresh `timelineData` loaded from Step 3, reading its `cells` array directly (sparse — an entry only exists once something has been placed there) avoids the extra round-trip; use the calls above otherwise, or when `timelineData` might be stale (e.g. a column was just created).
|
|
71
|
+
|
|
62
72
|
## Step 6 — Insert a column at a specific index (conflict resolution)
|
|
63
73
|
|
|
64
74
|
No relative-insertion equivalent over REST (unlike MCP's `afterNodeId`) — compute the index by hand:
|