@eventmodelers/cli 1.0.29 → 1.0.31
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 +18 -2
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-brainstorming-events/SKILL.md +1 -1
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-checking-completeness/SKILL.md +3 -1
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-elaborating-scenarios/SKILL.md +6 -4
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-outputs/SKILL.md +14 -5
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-orchestrating-event-modeling/SKILL.md +7 -2
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models-checklist/SKILL.md +8 -6
- package/stacks/modeling-kit/templates/.claude/skills/place-element/SKILL.md +14 -0
package/package.json
CHANGED
|
@@ -51,6 +51,7 @@ Server name: `eventmodelers`. Every tool takes `boardId` explicitly; none need `
|
|
|
51
51
|
| `add_storyline` | `boardId`, `timelineId`, `columnId`, `storylines[]` | **Experimental — only use when explicitly asked for a storyline/walkthrough.** Append storyline(s) (ordered, branchable beats over existing elements) to a column's spec node | §6 `POST .../storylines` |
|
|
52
52
|
| `set_connection` | `boardId`, `source`, `target`, `action` (`'connect'\|'remove'`) | Add or remove a type-checked directed edge | — (via `edges` on §3 events) |
|
|
53
53
|
| `auto_connect_node` | `boardId`, `nodeId` | Re-run auto-connect for a node | §3 `POST .../nodes/:nodeId/auto-connect` |
|
|
54
|
+
| `link_element` | `boardId`, `nodeId`, `targetNodeId` | Link two existing same-type nodes: `targetNodeId` is replaced with a full copy of `nodeId`'s meta plus `meta.linkedTo`. Linking means first create, then link | §3 `POST .../nodes/:nodeId/link` |
|
|
54
55
|
| `add_comment` | `boardId`, `nodeId`, `text`, `type?` (`'COMMENT'\|'TASK'\|'QUESTION'`), `author?` | Add a comment — `QUESTION` flags gaps/edge cases during review | — (via comment events) |
|
|
55
56
|
| `update_comment` | `boardId`, `nodeId`, `commentId`, `action` (`'resolve'\|'delete'`) | Resolve or delete a comment | — (via comment events) |
|
|
56
57
|
| `create_screen` | `boardId`, `contentType` (`'image'\|'sketch'\|'html'`), `nodeId?`, `chapterId`, `cellId?`/`cellName?`, plus content fields (`imageBase64`/`mimeType`, `elements[]`, or `pages[]`/`backgroundColor`), `description?` | Create + place a new screen node (SCREEN or HTML_SCREEN) atomically, in one call | §4 `POST .../images/:id/sketch` + `image-nodes` |
|
|
@@ -342,7 +343,7 @@ interface NodeChangeEvent {
|
|
|
342
343
|
backgroundColor?: string
|
|
343
344
|
title?: string
|
|
344
345
|
url?: string
|
|
345
|
-
linkedTo?: string //
|
|
346
|
+
linkedTo?: string // rendering mirror only — meta.linkedTo (below) is authoritative
|
|
346
347
|
// ...other node data fields
|
|
347
348
|
// Do NOT set a "type" here — the server derives the node's render type from
|
|
348
349
|
// meta.type automatically. Setting one yourself risks it being read as the
|
|
@@ -354,6 +355,7 @@ interface NodeChangeEvent {
|
|
|
354
355
|
title?: string
|
|
355
356
|
description?: string
|
|
356
357
|
fields?: Record<string, unknown>
|
|
358
|
+
linkedTo?: string // origin node id — the authoritative linked-copy pointer
|
|
357
359
|
// ...
|
|
358
360
|
}
|
|
359
361
|
edges?: Array<{
|
|
@@ -396,7 +398,7 @@ A COMMAND is driven by exactly one upstream trigger — one SCREEN or one AUTOMA
|
|
|
396
398
|
|
|
397
399
|
**Connections (both auto-connect and `set_connection`) only ever pair nodes on the same timeline** — a node in Chapter A can never be wired directly to a node in Chapter B, even when the type pair is otherwise valid (e.g. EVENT→READMODEL). No direct cross-timeline connection is possible.
|
|
398
400
|
|
|
399
|
-
**The supported workaround is a linked copy**: place a
|
|
401
|
+
**The supported workaround is a linked copy**: place a plain EVENT node into its own swimlane on the *consuming* timeline, then call `link_element` (below) to link it to the origin node. Linking means first create, then link. `eventmodeling-checking-completeness` documents how to recognize a linked copy when reading the board — it's an intentional copy, never a duplicate to clean up.
|
|
400
402
|
|
|
401
403
|
**Response**:
|
|
402
404
|
- `200` — `{ connected: [{edgeId, source, target, created}], skipped: [{nodeId, reason}] }`
|
|
@@ -415,6 +417,20 @@ Create a single type-checked directed edge between two existing nodes — the RE
|
|
|
415
417
|
|
|
416
418
|
---
|
|
417
419
|
|
|
420
|
+
### POST `/api/org/:orgId/boards/:boardId/nodes/:nodeId/link`
|
|
421
|
+
Link two existing same-type nodes — the REST fallback for `link_element`. Linking means first create, then link: `targetNodeId` must already exist. It's replaced with a full copy of `:nodeId`'s meta (not a merge) plus `meta.linkedTo`. COMMAND/EVENT/READMODEL only; `:nodeId` must not itself already be a linked copy.
|
|
422
|
+
|
|
423
|
+
**Request body**:
|
|
424
|
+
```typescript
|
|
425
|
+
{
|
|
426
|
+
targetNodeId: string // existing same-type node to convert into a linked copy
|
|
427
|
+
}
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
**Response**: `200` — `{ nodeId, linkedTo, type }` · `400` — missing `targetNodeId`, type mismatch, self-link, unsupported element type, or the original is itself a linked copy · `404` — the original or `targetNodeId` doesn't exist
|
|
431
|
+
|
|
432
|
+
---
|
|
433
|
+
|
|
418
434
|
## 4. Images
|
|
419
435
|
|
|
420
436
|
**File**: `src/slices/change/api-images/routes.ts`
|
package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-brainstorming-events/SKILL.md
CHANGED
|
@@ -370,7 +370,7 @@ An event left without a chapter and cell reference will never appear in any time
|
|
|
370
370
|
|
|
371
371
|
**Use swimlanes sparingly — a swimlane exists for exactly one purpose: marking where integration with another system happens. Nothing else justifies one.** Not a different actor, not a different role, not visual grouping, not "an explicit business rule" in the abstract. Every chapter starts with, and in the common case keeps, a single default swimlane holding all of this bounded context's own domain events. Before adding a lane, check whether an existing lane already covers the element's type. If yes, place the element in that lane.
|
|
372
372
|
|
|
373
|
-
**The only valid reason to create a second `swimlane`-type lane: another system's own events cross into this chapter as integration triggers for
|
|
373
|
+
**The only valid reason to create a second `swimlane`-type lane: another system's own events cross into this chapter as integration triggers for a translation automation** (see `eventmodeling-identifying-outputs` Step 5b). Label it for that system and place its trigger events there — never fold them into this chapter's own event swimlane (they are not this bounded context's domain facts) and never treat them as an informal "signal" with no EVENT node at all. An external EVENT may only ever open the *translation* automation's todo list — never the todo list of the automation that does the actual domain work; that automation is triggered solely by the internal event the translation automation produces (Step 5b covers the full two-automation chain).
|
|
374
374
|
|
|
375
375
|
**Never** add a swimlane for any other reason — not a new actor, not a new role, not visual grouping. Human roles get their own **actor** lane during Step 3 (Storyboarding) — a different row type entirely — never a new swimlane here.
|
|
376
376
|
|
package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-checking-completeness/SKILL.md
CHANGED
|
@@ -555,7 +555,9 @@ The model is **complete** when:
|
|
|
555
555
|
## Next Steps
|
|
556
556
|
|
|
557
557
|
If completeness check passes:
|
|
558
|
-
→ Proceed to
|
|
558
|
+
→ Proceed to Step 9 (`eventmodeling-validating-event-models`) — completeness is not the
|
|
559
|
+
final gate; validation, slicing, and documentation (Steps 9–11) still follow before
|
|
560
|
+
the model is ready for code generation.
|
|
559
561
|
|
|
560
562
|
If gaps found:
|
|
561
563
|
→ Return to appropriate step to fix
|
package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-elaborating-scenarios/SKILL.md
CHANGED
|
@@ -133,7 +133,7 @@ Append findings to the project's event modeling file:
|
|
|
133
133
|
Use Write tool to add/update this section:
|
|
134
134
|
|
|
135
135
|
```markdown
|
|
136
|
-
##
|
|
136
|
+
## 7. Scenarios (eventmodeling-elaborating-scenarios)
|
|
137
137
|
|
|
138
138
|
### Coverage Goals
|
|
139
139
|
[From Q1: Happy path / Comprehensive / Deep]
|
|
@@ -172,10 +172,12 @@ Use Write tool to add/update this section:
|
|
|
172
172
|
|
|
173
173
|
Update Interview Trail:
|
|
174
174
|
```markdown
|
|
175
|
-
|
|
|
175
|
+
| 7 | eventmodeling-elaborating-scenarios | [today] | Scenario coverage, testing strategy, edge cases |
|
|
176
176
|
```
|
|
177
177
|
|
|
178
|
-
|
|
178
|
+
Scenarios are done, but the model is not yet ready for implementation — Steps 8–11
|
|
179
|
+
(Completeness, Validation, Slicing, Documentation) still follow. Proceed to Step 8
|
|
180
|
+
(`eventmodeling-checking-completeness`).
|
|
179
181
|
|
|
180
182
|
---
|
|
181
183
|
|
|
@@ -809,7 +811,7 @@ After posting, tell the user:
|
|
|
809
811
|
**Per read model — this is a separate, equally mandatory pass, not an afterthought of the command pass above:**
|
|
810
812
|
- [ ] **Every READMODEL on the board has at least one view scenario** — GWT (`given`: source EVENTs, `when`: empty, `then`: the READMODEL) or a storyline. A model with dozens of command scenarios and 0 read-model scenarios is not a complete Step 7 — it's easy to walk away thinking coverage is thorough because the command side looks exhaustive, so check the read-model side explicitly before reporting this step done.
|
|
811
813
|
- [ ] **Population scenario** — the view shows correct data after its source event(s)
|
|
812
|
-
- [ ] **Removal/update scenario, where applicable** — a row disappears or changes (`expectEmptyList: true` for list-type views) after an event that supersedes it (expiry, return, archival, withdrawal, status change, etc.). `EVENT → READMODEL` is exempt from column ordering **only when the read model already feeds an AUTOMATION** (`READMODEL → AUTOMATION` edge; see `learn-eventmodelers-api` §3) — a later event connecting back to an earlier-placed read model is normal for that accumulator shape, so add the connection if it's missing rather than assuming the scenario is impossible. If the read model has no automation to feed, the backward connection is rejected —
|
|
814
|
+
- [ ] **Removal/update scenario, where applicable** — a row disappears or changes (`expectEmptyList: true` for list-type views) after an event that supersedes it (expiry, return, archival, withdrawal, status change, etc.). `EVENT → READMODEL` is exempt from column ordering **only when the read model already feeds an AUTOMATION** (`READMODEL → AUTOMATION` edge; see `learn-eventmodelers-api` §3 and `eventmodeling-orchestrating-event-modeling`'s "No backward arrows") — a later event connecting back to an earlier-placed todo-list read model is normal for that accumulator shape, so add the connection if it's missing rather than assuming the scenario is impossible. If the read model has no automation to feed, the backward connection is rejected — by Step 5 this should already have been modeled the forward way (see `eventmodeling-identifying-outputs` Step 5g's copy pattern: a new read model + screen copy in the later event's column, never a link back). If it wasn't, write the scenario against that forward-placed copy rather than the original. Only skip this scenario, with a documented gap (TASK comment), when the superseding event genuinely lives in a different chapter.
|
|
813
815
|
- [ ] **GWT vs. storyline decided per read model, not applied uniformly** — reach for a storyline wherever the *same* read model row genuinely walks through multiple states worth narrating; the rest of the read models in the same model may be correctly GWT-only. Don't default to one format for every read model just because it worked for the first one, and don't judge "multiple states" by counting *distinct connected event types* — that undercounts real candidates. **A single event type recurring with different data is just as valid a storyline driver as several different event types**: `AccountFunded($40)` then `AccountFunded($70)` walking a balance read model from $40 to $110 is exactly as strong a storyline as a multi-event lifecycle. In practice this means almost every list/aggregate read model qualifies — a titles list growing from one row to two as the same `TitleAdded`-shaped event recurs, a dashboard's counters incrementing as the same `CopyAdded` event recurs, are both genuine storylines, not "just" GWT territory. Ask "does replaying this read model's *actually connected* event(s) more than once produce an interesting accumulated/changed state?" — not "how many different event types feed this."
|
|
814
816
|
- [ ] **No redundancy or contradiction between a read model's GWT scenarios and its storyline** — if both exist for the same read model, read the storyline's beats before finalizing the GWTs. A GWT that asserts the same state a beat already shows is redundant (delete it); a GWT written without tracing the same causal sequence the storyline encodes can end up asserting something the storyline's beats actually contradict (e.g. claiming two entities coexist in a view when the storyline correctly shows one superseding the other) — delete or fix it, never leave a contradiction on the board.
|
|
815
817
|
- [ ] **Cross-context read models handled honestly** — if a read model's true source events live in a different chapter, `given` can't reference them (same-timeline-only, like connections); write the scenario with an empty `given` and say so explicitly in the scenario title, rather than silently omitting the scenario or fabricating a same-timeline event that isn't the real source
|
package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-outputs/SKILL.md
CHANGED
|
@@ -405,12 +405,18 @@ After this step is done, **every SCREEN and every AUTOMATION on the board must b
|
|
|
405
405
|
- `NotificationSent` (the event this automation's own resulting command produces) **closes** that row (removes it — the list only ever shows outstanding work).
|
|
406
406
|
- The automation (`Send Welcome Notification`) reads `NotificationsToSend`, and for every open row issues `SendNotification`.
|
|
407
407
|
|
|
408
|
-
Even an automation that looks like a "pure signal relay"
|
|
408
|
+
Even an automation that looks like a "pure signal relay" still has a todo list — model it anyway: it documents that the automation is idempotent/complete once its own event fires, and keeps every automation consistent with the same `READMODEL → AUTOMATION → COMMAND → EVENT` pattern instead of silently exempting some as "too simple to need one."
|
|
409
409
|
|
|
410
|
-
**There is no such thing as an invisible or informal "signal" — a trigger is always a real EVENT node, placed in a second swimlane when it belongs to another system.**
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
410
|
+
**There is no such thing as an invisible or informal "signal" — a trigger is always a real EVENT node, placed in a second swimlane when it belongs to another system.**
|
|
411
|
+
|
|
412
|
+
**An automation can only ever be directly triggered by an internal event — never by another system's event.** A "trigger" arriving from a second swimlane is not itself the thing that drives your domain's work; it first has to be *translated* into an internal event. Do not model this as one automation whose todo list is opened by the external EVENT and that also does the real work (e.g. an automation reading a todo list opened by `ReservationRequested` from another system's swimlane and directly issuing `ReserveCopy`) — that lets an external system trigger domain work with no translation step, which this model doesn't allow. When an integration trigger comes from another team's system (Step 6 territory), model it as **two chained automations**, never one:
|
|
413
|
+
|
|
414
|
+
1. **Translation automation** — its only job is converting the external fact into an internal one; the upstream decision logic on the other system's side is out of scope. Its todo list is opened by the external EVENT (second swimlane) and closed by the internal EVENT its own command produces — this is the one and only place an external EVENT is allowed to open a todo list.
|
|
415
|
+
- Second swimlane: place one EVENT per integration trigger point there, in the **same column** as this translation automation's AUTOMATION/COMMAND/EVENT triplet (e.g. `ReservationRequested` in the same column as a `Record Reservation Request` automation/command/`ReservationRequestReceived` event). This event represents that other system's own domain fact arriving at the boundary — it is a real, first-class EVENT, not a comment or a placeholder.
|
|
416
|
+
- Its command and resulting event carry no business decision of their own — they exist to produce the internal event the next automation needs, nothing more.
|
|
417
|
+
2. **Worker automation** — the one that does the actual work (the domain reaction the process is really about, e.g. `ReserveCopy`). Its todo list is opened **only** by the internal EVENT the translation automation produced (this chapter's own swimlane) — never by the external EVENT directly — and closed by whatever event marks that work done.
|
|
418
|
+
|
|
419
|
+
Wire the todo lists the standard way for each automation separately: for the translation automation, the external EVENT (second swimlane) **opens** the row and its own resulting internal EVENT **closes** it; for the worker automation, that same internal EVENT **opens** its row and its own resulting EVENT **closes** it. `EVENT → READMODEL` connections from both swimlanes are unaffected by which swimlane the event sits in.
|
|
414
420
|
|
|
415
421
|
**Fields**: a todo-list read model's fields describe the pending item — the identity it's about (e.g. `customerId`) plus enough context to act on it (e.g. `email`, `notificationType`). Do not add a `status` field to mark items done — a todo list's "open" state is *membership in the list itself* (the row exists at all), not a status flag on a row that never leaves. If the same underlying data is also useful with an explicit status column for a different consumer, that is a different read model, not this one.
|
|
416
422
|
|
|
@@ -584,6 +590,8 @@ For each view screen S that queries this read model:
|
|
|
584
590
|
|
|
585
591
|
**View screens go in the column immediately to the right of the read model they display** — either because they were placed there in Step 3, or because you move them here now.
|
|
586
592
|
|
|
593
|
+
**The same rule applies to `EVENT → READMODEL`.** If a later event needs to update data a read model already feeds to a SCREEN, do not connect that later event back into the existing read model — the platform only accepts an `EVENT → READMODEL` backward connection when the read model already has a `READMODEL → AUTOMATION` edge (the todo-list pattern from Step 5b). For any read model feeding a SCREEN, resolve the update the same way Step 5c resolves multi-component screens: place a **new copy of the read model** in (or immediately after) the later event's column, connect the later event forward into that copy, and place a matching copy of the same screen there — same title, updated data, optionally re-marked/highlighted via `html-screen`'s Marks feature. Never link the new copy back to the earlier read model instance.
|
|
594
|
+
|
|
587
595
|
### Step 5h — Wire connections after placing each READMODEL (and its SCREEN)
|
|
588
596
|
|
|
589
597
|
After `place-element` returns the READMODEL node ID, create the arrows that complete the slice:
|
|
@@ -771,6 +779,7 @@ Identify UI needs without event sources:
|
|
|
771
779
|
- [ ] **Typical pattern applied**: most screens follow `READ MODEL → SCREEN → COMMAND → EVENT`
|
|
772
780
|
- [ ] **Every SCREEN from storyboarding is connected to at least one read model** (via `READMODEL → SCREEN`); only blank creation forms may be exempt — verified via the mandatory per-node pass above, not assumed
|
|
773
781
|
- [ ] **Every AUTOMATION from storyboarding is connected to at least one todo-list read model** (via `READMODEL → AUTOMATION`, Step 5b) — no exemption for automations, unlike screens; even a simple relay automation gets one
|
|
782
|
+
- [ ] **No automation's todo list is opened directly by another system's (second-swimlane) EVENT unless that automation is itself the translation automation** (Step 5b) — an automation doing the actual domain work is only ever opened by an internal event; a second-swimlane EVENT feeding straight into a work automation's todo list is a missing translation automation
|
|
774
783
|
- [ ] **No read model is placed without a connected SCREEN or AUTOMATION consumer**
|
|
775
784
|
- [ ] **No read model spans more than one component** — a screen with N distinct components gets N read models and N highlighted screen copies (same screen name, one component crisp per copy), not one screen-wide read model
|
|
776
785
|
- [ ] **Every multi-component screen was broken apart in Step 5c** — each copy keeps the original screen's name, differs only in which component is marked/highlighted
|
|
@@ -113,7 +113,11 @@ Never leave an unplaced node on the board when proceeding to the next step.
|
|
|
113
113
|
### No backward arrows
|
|
114
114
|
The timeline must always progress left-to-right — this is the goal to design toward, not just a validation check to run afterward. Every connection arrow — SCREEN→COMMAND, COMMAND→EVENT, READMODEL→SCREEN, READMODEL→AUTOMATION, AUTOMATION→COMMAND — must point to the right or downward (within the same column). A right-to-left arrow among these is always a layout error, full stop.
|
|
115
115
|
|
|
116
|
-
**`EVENT → READMODEL`
|
|
116
|
+
**`EVENT → READMODEL` has exactly one exception, and it is narrow.** A read model that already carries a `READMODEL → AUTOMATION` edge — i.e. a todo-list read model feeding an automation, per `eventmodeling-identifying-outputs` Step 5b — may also be fed by a later-column event closing an item it opened earlier. That accumulator shape is what the todo-list pattern exists for, and it is confirmed against the platform API (`learn-eventmodelers-api` §3 — `POST .../connections`). **Outside that one case, the platform rejects the connection, for good reason:** without it, a read model would become a moving target for whatever screen or scenario later reaches back into it.
|
|
117
|
+
|
|
118
|
+
For every other read model — in particular one feeding a SCREEN rather than an AUTOMATION — never connect a later event back into it, no matter how convenient. If a later event needs to update what a screen already shows, resolve it the same way Step 5c resolves multi-component screens: place a **new copy of the read model** in (or immediately after) the later event's column, connect the later event forward into that copy, and place a matching copy of the same screen there (same title, updated data, optionally re-marked/highlighted per `html-screen`'s Marks feature). Never link the new copy back to the earlier instance.
|
|
119
|
+
|
|
120
|
+
A wide fan-in read model (many connected events, one column) is a different problem with a different fix — see "one read model per component" and the >3-events heuristic above. It is never a justification for a backward arrow. The one real signal to treat as a prunable connection regardless of column position is a **connected event that isn't actually used by any field** on the read model.
|
|
117
121
|
|
|
118
122
|
Before wiring any of the five forward-only pairs, verify that `column(source) ≤ column(target)`. If this is violated:
|
|
119
123
|
- Move the earlier-placed element to the correct column, OR
|
|
@@ -338,7 +342,7 @@ If FAIL: address findings and re-invoke `eventmodeling-validating-event-models`.
|
|
|
338
342
|
|
|
339
343
|
**Optional — Production Readiness Checklist**: Invoke
|
|
340
344
|
`eventmodeling-validating-event-models-checklist` when the model is destined
|
|
341
|
-
for production. It runs
|
|
345
|
+
for production. It runs 17 architectural checks across 7 phases and returns a
|
|
342
346
|
PASS / PASS WITH WARNINGS / FAIL verdict independently of Step 9. A PASS on
|
|
343
347
|
Step 9 does not substitute for this checklist when production readiness is
|
|
344
348
|
required.
|
|
@@ -463,6 +467,7 @@ specific needs:
|
|
|
463
467
|
## Quality Checklist
|
|
464
468
|
|
|
465
469
|
- [ ] No elements stranded at 0,0 — every EVENT, COMMAND, READMODEL, SCREEN, and AUTOMATION has a valid `cellId` in its chapter
|
|
470
|
+
- [ ] No `EVENT → READMODEL` connection points backward unless the read model already has a `READMODEL → AUTOMATION` edge (todo-list pattern) — every other later-event update uses a new read model + screen copy, never a link back to the earlier instance
|
|
466
471
|
- [ ] All 11 modeling steps completed — no step skipped without explicit reason
|
|
467
472
|
- [ ] Every COMMAND, READMODEL, and AUTOMATION has a matching slice definition on the board
|
|
468
473
|
- [ ] Every chapter has a Modeling Reasoning MARKDOWN node in its first column, written after that chapter's model was complete
|
|
@@ -17,8 +17,8 @@ Prefer `mcp__eventmodelers__*` tools when available (registered by the `connect`
|
|
|
17
17
|
**Applies To**: Any domain - e-commerce, banking, SaaS, marketplace, healthcare, etc.
|
|
18
18
|
|
|
19
19
|
**When to Use**:
|
|
20
|
-
- After completing Step 2 (Event Plot) of
|
|
21
|
-
-
|
|
20
|
+
- After completing Step 2 (Event Plot) of the 11-step event modeling workflow, as an early structural check
|
|
21
|
+
- Alongside Step 9 (Validate), as the optional production-readiness pass before declaring model complete
|
|
22
22
|
- When reviewing an existing event model for production readiness
|
|
23
23
|
- When suspicious of architectural issues in event design
|
|
24
24
|
|
|
@@ -311,11 +311,13 @@ Step 2: The Plot (Sequence)
|
|
|
311
311
|
↓
|
|
312
312
|
Fix any violations
|
|
313
313
|
↓
|
|
314
|
-
Step 3-
|
|
314
|
+
Step 3-8: Storyboard, Inputs, Outputs, Conway's Law, Scenarios, Completeness
|
|
315
315
|
↓
|
|
316
|
-
|
|
316
|
+
Step 9: Validate (eventmodeling-validating-event-models)
|
|
317
317
|
↓
|
|
318
|
-
|
|
318
|
+
→ RUN eventmodeling-validating-event-models-checklist again (production-readiness pass)
|
|
319
|
+
↓
|
|
320
|
+
PASS → Step 10: Slice, Step 11: Document Reasoning → Code generation
|
|
319
321
|
FAIL → Fix identified issues
|
|
320
322
|
```
|
|
321
323
|
|
|
@@ -368,7 +370,7 @@ The principle is the same across all domains: **immutable facts as events, calcu
|
|
|
368
370
|
|
|
369
371
|
## Related Skills
|
|
370
372
|
|
|
371
|
-
- **eventmodeling-orchestrating-event-modeling**: Main skill coordinating the
|
|
373
|
+
- **eventmodeling-orchestrating-event-modeling**: Main skill coordinating the 11-step event modeling process
|
|
372
374
|
- **eventmodeling-brainstorming-events**: Extract events from requirements (Step 1)
|
|
373
375
|
- **eventmodeling-plotting-events**: Sequence events chronologically (Step 2)
|
|
374
376
|
- **eventmodeling-designing-event-models**: Design your complete event model
|
|
@@ -280,6 +280,20 @@ If no matching row is found, stop and report the error — the timeline may be m
|
|
|
280
280
|
|
|
281
281
|
---
|
|
282
282
|
|
|
283
|
+
## Step 6a — Referencing a node on a different timeline
|
|
284
|
+
|
|
285
|
+
**Connections only ever pair nodes on the same timeline** — a node in Chapter A can never be wired directly to a node in Chapter B, even for an otherwise-valid type pair (e.g. `EVENT → READMODEL`). If the element you're placing needs to connect to something that lives on a *different* timeline, do not place it and then attempt `set_connection`/auto-connect across timelines — it will fail.
|
|
286
|
+
|
|
287
|
+
Instead, create a **linked copy**: place the new node normally (Step 7, same title/type as the origin), then call `link_element` to mark it as a copy of the origin node:
|
|
288
|
+
|
|
289
|
+
```
|
|
290
|
+
mcp__eventmodelers__link_element { "boardId": "<BOARD_ID>", "nodeId": "<origin-node-id>", "targetNodeId": "<newly-placed-node-id>" }
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
(REST fallback: `POST .../nodes/:nodeId/link` with `{ "targetNodeId": "<newly-placed-node-id>" }` — see `learn-eventmodelers-api` §3.) This replaces the new node's meta with a full copy of the origin's, sets `meta.linkedTo`, and only works for COMMAND/EVENT/READMODEL. Once linked, wire the local copy to its neighbors with normal same-timeline `set_connection`/auto-connect calls. `eventmodeling-checking-completeness` treats any `linkedTo`-marked node it finds as this intentional pattern, never a duplicate to flag.
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
283
297
|
## Step 7 — Create the node
|
|
284
298
|
|
|
285
299
|
### Step 7a — SCREEN only: create and render in one atomic call
|