@eventmodelers/cli 1.0.36 → 1.0.37
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 +12 -10
- 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 +9 -319
- 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 +23 -199
- 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 +13 -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-designing-automation-chains/SKILL.md +132 -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 +9 -236
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-event-models/references/examples.md +257 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-elaborating-scenarios/SKILL.md +28 -302
- 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 +30 -343
- 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 +51 -400
- 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-optimizing-stream-design/SKILL.md +45 -152
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/references/domain-patterns.md +49 -90
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/references/patterns.md +64 -137
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-orchestrating-event-modeling/SKILL.md +74 -65
- 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 +1 -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 +19 -36
- 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 +26 -332
- 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 +9 -294
- 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 +12 -11
- 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 +6 -36
- 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 +23 -183
- package/stacks/modeling-kit/templates/.claude/skills/place-element/references/api-fallback.md +193 -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-orchestrating-event-modeling
|
|
3
|
-
description: "Orchestrates complete event modeling workflow from requirements to code generation. Models architecture as UI/Processor → Command → Event → Read Model. Use when modeling a domain end-to-end from requirements. Do not use for: executing a single step in isolation (invoke the named step skill directly, e.g., eventmodeling-brainstorming-events for Step 1 or eventmodeling-elaborating-scenarios for Step 7), validating an already-completed model (use eventmodeling-validating-event-models)
|
|
3
|
+
description: "Orchestrates complete event modeling workflow from requirements to code generation. Models architecture as UI/Processor → Command → Event → Read Model. Use when modeling a domain end-to-end from requirements. Do not use for: executing a single step in isolation (invoke the named step skill directly, e.g., eventmodeling-brainstorming-events for Step 1 or eventmodeling-elaborating-scenarios for Step 7), or validating an already-completed model (use eventmodeling-validating-event-models)."
|
|
4
4
|
allowed-tools:
|
|
5
5
|
- AskUserQuestion
|
|
6
6
|
- Write
|
|
@@ -37,11 +37,15 @@ These rules govern how every element is placed on the board. Enforce them throug
|
|
|
37
37
|
- SCREEN (input/command screen) goes in the **actor row of that same column**.
|
|
38
38
|
- **A COMMAND never stands alone.** Every COMMAND must have exactly one issuer in the actor row of its own column: a SCREEN when a human triggers it, an AUTOMATION when a processor or external-system integration triggers it. There is no third option and no exemption — a command with an empty actor-row cell is an unresolved gap the moment it's placed, not something to leave for a later step to notice. This applies just as much to a command that only *represents* an externally-triggered integration event crossing into this chapter (Step 1/Step 6 territory) as to any other command: place an AUTOMATION for the external actor even when that actor's own decision logic is out of scope for this model — the automation node documents *that* something triggers the command, not *how* it decides to.
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
**Before placing that automation, check whether the trigger is already a placed EVENT node in a second (external) swimlane** (from Step 1/brainstorming), as opposed to an unmodeled webhook/API call with no such node. These are not the same case:
|
|
41
|
+
- **No pre-existing EVENT node** (a plain webhook/API trigger) — place the AUTOMATION+COMMAND in one column as usual; the command produces a new EVENT there. Nothing further needed in Step 4.
|
|
42
|
+
- **A pre-existing EVENT node in another system's swimlane** — do **not** place the AUTOMATION/COMMAND in that event's column, and do **not** connect `COMMAND → EVENT` to it: that event already happened in another system and cannot be "produced" by a command in this one. Attribute the command to the Role Catalog and list it in the Command Catalog as *pending Step 4b*, but leave its placement and every one of its connections to Step 4b — placing it here only produces a wrong connection that Step 4b then has to delete and redo.
|
|
43
|
+
|
|
44
|
+
Every AUTOMATION placed this way still needs its own todo-list READMODEL, and one further rule governs *how* it's triggered: **an automation can only ever be directly triggered by an internal event — never by another system's event.** A signal arriving from a second swimlane must first be translated into an internal event by its own dedicated translation automation (external EVENT → todo-list READMODEL → translation AUTOMATION+COMMAND+*internal* EVENT) before any worker automation reacts to it — never one automation whose todo list is opened by the external EVENT directly. There is no exemption for a "pure relay" automation either — even one triggered only by its own resulting event still gets a todo list that opens and closes within the same slice. This is designed immediately after Step 4, in **Step 4b — Design Automation Chains** (`eventmodeling-designing-automation-chains`), precisely so it's resolved before Step 5 ever has to catch it as a gap.
|
|
41
45
|
|
|
42
46
|
### State-view slice (EVENT → READ MODEL → SCREEN)
|
|
43
47
|
- READ MODEL goes in the **interaction row** of a column that is **immediately after the primary source event's column** — never at the end of the timeline.
|
|
44
|
-
- SCREEN (view/output screen) goes in the **actor row of the same column as the READ MODEL**.
|
|
48
|
+
- SCREEN (view/output screen) goes in the **actor row of the same column as the READ MODEL**. When that column's interaction row is unavailable to the read model (e.g. already holds a COMMAND), the **read model** gets a new column immediately **before** the screen's — the screen's own position is never moved to resolve this (`eventmodeling-identifying-outputs`'s Step 5g has the full mechanics).
|
|
45
49
|
- If the primary source event's column already has a COMMAND in the interaction row, insert a **new column immediately after** (using `index = currentColumnIndex + 1`) and place the READ MODEL there.
|
|
46
50
|
|
|
47
51
|
### Never stack read models at the end
|
|
@@ -71,7 +75,7 @@ This is a **business-modeling decision, not a technical one** — it is not trig
|
|
|
71
75
|
|
|
72
76
|
The question to ask is simply: **is this fact worth a new event?** A derived condition — "is this available right now," "has this moved to its next stage," etc. — is worth its own event when it's a fact a domain expert would recognize and name in its own right (not just "some field I compute"), and when that fact is valuable to a later step in the process — another automation would react to it, a different bounded context would want to subscribe to it, some downstream process needs to trigger off of it. If both hold, it deserves to exist as its own dedicated event — e.g. "the copy was marked available" — not just as derived read-model logic recomputed from several other events.
|
|
73
77
|
|
|
74
|
-
When that's the case, model it as its own event, produced via the same todo-list + automation translation pattern Step
|
|
78
|
+
When that's the case, model it as its own event, produced via the same todo-list + automation translation pattern `eventmodeling-designing-automation-chains` (Step 4b) uses for external integrations, but triggered internally by whichever raw events can produce that outcome. If the condition is purely for display, with nothing downstream that would ever act on it, it stays a plain read-model projection — no new event needed, no matter how many raw events feed it or how wide the resulting fan-in looks.
|
|
75
79
|
|
|
76
80
|
**Only fold together causes that are genuinely redundant for the same outcome — never causes that carry distinct business meaning.** A derived condition's causes typically split into two groups: several distinct events that all mean the *same* thing from the business's point of view (e.g. `CopyReservationReleased`, `CopyReturned`, and `CopyReturnedFromRepair` all mean "the copy is available again"), and several distinct events that each mean something the business still wants told apart (e.g. `CopyReserved` → Reserved, `CopyCheckedOut` → CheckedOut, `CopySentForRepair` → UnderRepair, `CopyReportedLost` → Lost, `CopyWithdrawn` → Withdrawn). Only the first group is safe to consolidate — a dedicated event like `CopyMarkedAvailable` collapses "N different reasons, same outcome" into one reusable signal without losing information. Collapsing the second group into something like a generic `CopyMarkedUnavailable` would erase the *why*, which some downstream consumer may actually need — leave those as separate events and direct connections, even though the read model's fan-in then stays wider than the fully-consolidated ideal. That remaining fan-in is not a failure of anything — it means those events are each individually meaningful, not synonymous with each other, and collapsing them would have been the actual modeling mistake.
|
|
77
81
|
|
|
@@ -81,19 +85,13 @@ After each step that creates elements (Steps 1–5), scan for any nodes that hav
|
|
|
81
85
|
|
|
82
86
|
For each timeline in scope, check all node types that should be in cells.
|
|
83
87
|
|
|
84
|
-
**Prefer MCP:**
|
|
85
|
-
```
|
|
86
|
-
mcp__eventmodelers__get_nodes { "boardId": "$BOARD_ID", "type": "EVENT" }
|
|
88
|
+
**Prefer MCP:** run `validate_model` once per chapter — the `unplaced` findings it returns are exactly this scan, plus five other structural checks, in one call and with a compact response (no full node objects):
|
|
87
89
|
```
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
**Fallback (no MCP):**
|
|
91
|
-
```bash
|
|
92
|
-
for TYPE in EVENT COMMAND READMODEL SCREEN AUTOMATION; do
|
|
93
|
-
curl -s -H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" \
|
|
94
|
-
"$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?type=$TYPE"
|
|
95
|
-
done
|
|
90
|
+
mcp__eventmodelers__validate_model { "boardId": "$BOARD_ID", "chapterId": "$TIMELINE_ID" }
|
|
96
91
|
```
|
|
92
|
+
Only fall back to per-type `get_nodes` (`chapterId`-scoped, once each for `EVENT`, `COMMAND`, `READMODEL`, `SCREEN`, `AUTOMATION`) when you also need the node bodies for another reason in the same pass.
|
|
93
|
+
|
|
94
|
+
**Fallback (no MCP):** see `references/api-fallback.md` — "No unplaced elements (0,0 nodes) — Scan for unplaced nodes".
|
|
97
95
|
|
|
98
96
|
For each returned node, check whether it has a valid cell assignment. A node without a `cellId` (or with `chapterId` missing) is unplaced.
|
|
99
97
|
|
|
@@ -105,15 +103,7 @@ For each returned node, check whether it has a valid cell assignment. A node wit
|
|
|
105
103
|
mcp__eventmodelers__drop_node_to_cell { "boardId": "$BOARD_ID", "timelineId": "<chapterId>", "cellId": "<rowId>-<colId>", "nodeId": "<nodeId>", "nodeType": "<TYPE>" }
|
|
106
104
|
```
|
|
107
105
|
|
|
108
|
-
**Fallback (no MCP):**
|
|
109
|
-
```bash
|
|
110
|
-
curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/events" \
|
|
111
|
-
-H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" -H "x-user-id: orchestrator" \
|
|
112
|
-
-H "Content-Type: application/json" \
|
|
113
|
-
-d '[{"id":"<uuid>","eventType":"node:changed","nodeId":"<nodeId>","boardId":"<BOARD_ID>",
|
|
114
|
-
"timestamp":1234567890,"chapterId":"<chapterId>","cellId":"<rowId>-<colId>",
|
|
115
|
-
"meta":{"type":"<TYPE>","title":"<title>"}}]'
|
|
116
|
-
```
|
|
106
|
+
**Fallback (no MCP):** see `references/api-fallback.md` — "No unplaced elements (0,0 nodes) — Place a found unplaced node".
|
|
117
107
|
- **If it is an orphan (duplicate or no longer needed)** → delete it.
|
|
118
108
|
|
|
119
109
|
**Prefer MCP:**
|
|
@@ -121,18 +111,14 @@ For each returned node, check whether it has a valid cell assignment. A node wit
|
|
|
121
111
|
mcp__eventmodelers__delete_node { "boardId": "$BOARD_ID", "nodeId": "<nodeId>" }
|
|
122
112
|
```
|
|
123
113
|
|
|
124
|
-
**Fallback (no MCP):**
|
|
125
|
-
```bash
|
|
126
|
-
curl -s -X DELETE "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/<nodeId>" \
|
|
127
|
-
-H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID"
|
|
128
|
-
```
|
|
114
|
+
**Fallback (no MCP):** see `references/api-fallback.md` — "No unplaced elements (0,0 nodes) — Delete an orphaned node".
|
|
129
115
|
|
|
130
116
|
Never leave an unplaced node on the board when proceeding to the next step.
|
|
131
117
|
|
|
132
118
|
### No backward arrows
|
|
133
119
|
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.
|
|
134
120
|
|
|
135
|
-
**`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-
|
|
121
|
+
**`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-designing-automation-chains` (Step 4b) — 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.
|
|
136
122
|
|
|
137
123
|
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.
|
|
138
124
|
|
|
@@ -145,7 +131,30 @@ Before wiring any of the five forward-only pairs, verify that `column(source)
|
|
|
145
131
|
Screens placed during Step 3 (Storyboarding) are provisional positions. Steps 4 and 5 may need to move them to align with the commands or read models placed later.
|
|
146
132
|
|
|
147
133
|
### Column insertion
|
|
148
|
-
Use `
|
|
134
|
+
Use `add_column` with `{"index": N}` to insert a column at a specific position (shifts existing columns right) — or, when the insertion point is "immediately before/after a node already on the board" rather than a numeric position you'd otherwise have to compute, pass `beforeNodeId`/`afterNodeId` instead and let the tool resolve the index itself. Do not use no position at all (append) when placing read models or view screens — always target the correct position.
|
|
135
|
+
|
|
136
|
+
**Suppress auto-connect when inserting into an existing chain.** When you insert columns next to nodes that are *not* meant to connect to what you're about to place — e.g. slotting an output read model's column in beside an automation-chain column — the node placement's default auto-connect will wire the new node to whatever type-compatible node happens to sit in its own or the previous column (the "nearest event to the left"). That is the source of the recurring stray-edge cleanup. When the placement you're about to make should be wired only by your own explicit `set_connections` batch, pass `autoConnect: false` on the placing call (`submit_node_events`, `place_element`, `create_screen`/`create_screens`) and then wire every edge yourself. Keep the default (auto-connect on) for Steps 1/3/4 where same-column neighbors are exactly the intended wiring.
|
|
137
|
+
|
|
138
|
+
### Prefer batch MCP tools over one-call-per-item loops
|
|
139
|
+
|
|
140
|
+
Several MCP tools have a batch form that does the exact same thing as calling their singular form once per item, with the same validation rules and (where order matters, e.g. wiring a READMODEL→AUTOMATION edge before the backward EVENT→READMODEL edge that depends on it) the same in-order guarantee — just fewer round trips. Whenever a step's own instructions below show a single-item call and more than one item is being processed in the same pass, use the batch form instead:
|
|
141
|
+
|
|
142
|
+
- `set_connections` (not `set_connection` repeated) — wiring multiple edges
|
|
143
|
+
- `auto_connect_nodes` (not `auto_connect_node` repeated) — auto-connecting multiple freshly-placed nodes
|
|
144
|
+
- `create_slice_definitions` (not `create_slice_definition` repeated) — defining multiple slices
|
|
145
|
+
- `create_screens` (not `create_screen` repeated) — creating multiple HTML screens whose content is already authored
|
|
146
|
+
- `move_nodes` (not `move_node_in_timeline` repeated) — moving multiple already-placed nodes within one timeline
|
|
147
|
+
- `delete_nodes` / `delete_columns` (not `delete_node`/`delete_column` repeated) — removing multiple nodes or columns, e.g. a corrective cleanup after a modeling mistake
|
|
148
|
+
- `add_column`'s `count` param (not `add_column` repeated) — appending or inserting several columns at once; `beforeNodeId`/`afterNodeId` resolve the insertion point from an already-placed node instead of a computed index
|
|
149
|
+
- `create_chapter`'s `columns` param — when the chapter's initial column count is already known, instead of creating the default 3 and appending more after
|
|
150
|
+
|
|
151
|
+
Also prefer `get_nodes`' `chapterId` param over an unscoped board-wide fetch whenever the step is working within one timeline (the common case), and `get_node`'s `projection: "cells"` over a full chapter fetch whenever only `{rows, columns, cells}` is needed (most cell/column bookkeeping lookups).
|
|
152
|
+
|
|
153
|
+
For a "what is on the board and how is it wired right now" check between steps — the common orientation read, and the input to choosing an insertion anchor — use `get_board_outline` (`{boardId, chapterId}`). It returns one compact object: per-column node lists (`{id, type, title, lane}`) plus a flat edge list, with no rendered screen HTML or field bodies. Reserve full `get_nodes` (no projection) for when you actually need a node's `meta.fields` or page content.
|
|
154
|
+
|
|
155
|
+
**Structural validation is one call, not a scan.** `validate_model` (`{boardId, chapterId}`) runs the whole structural checklist server-side — unplaced nodes, backward arrows (todo-list exception applied), zero/multi-issuer commands, sourceless read models, two-screens-in-a-column, missing scenarios — and returns only `findings`. Use it for the mandatory post-step unplaced check and as the first move in Step 9, instead of per-type `get_nodes` loops and `get_node` `projection: "edges"` spot-checks.
|
|
156
|
+
|
|
157
|
+
**Ask echo-heavy write tools for less.** `add_scenario`, `add_storyline`, `set_connections` and `submit_node_events` each accept `compact: true`, which drops the full-object echo from the response (returning `{specNodeId, added, count, isNewNode}`, a `{connected, existed, removed, notFound, failed, errors}` tally, or `{persisted: <count>}` respectively). Pass it whenever you're not going to read individual fields back off the response — which is almost always for a large `set_connections` batch or a bulk scenario post.
|
|
149
158
|
|
|
150
159
|
### Documenting decisions inline, at any step
|
|
151
160
|
|
|
@@ -279,15 +288,35 @@ role or system processor.
|
|
|
279
288
|
|
|
280
289
|
---
|
|
281
290
|
|
|
291
|
+
### Step 4b: Design Automation Chains
|
|
292
|
+
|
|
293
|
+
Invoke `eventmodeling-designing-automation-chains`.
|
|
294
|
+
|
|
295
|
+
**Input**: Every AUTOMATION placed in Step 4, each already paired with its own
|
|
296
|
+
COMMAND in one column.
|
|
297
|
+
**Output to carry forward**: Every automation's todo-list READMODEL, placed
|
|
298
|
+
and wired; every externally-triggered automation resolved into a two-stage
|
|
299
|
+
translation chain (external EVENT → todo-list READMODEL → translation
|
|
300
|
+
AUTOMATION+COMMAND+internal EVENT → worker automation's own todo list).
|
|
301
|
+
**Gate**: No AUTOMATION on the board lacks an incoming `READMODEL →
|
|
302
|
+
AUTOMATION` connection, and no automation's todo list is opened directly by
|
|
303
|
+
another system's (second-swimlane) event. Skip this step only if Step 4
|
|
304
|
+
placed zero automations.
|
|
305
|
+
|
|
306
|
+
---
|
|
307
|
+
|
|
282
308
|
### Step 5: Identify Outputs
|
|
283
309
|
|
|
284
310
|
Invoke `eventmodeling-identifying-outputs`.
|
|
285
311
|
|
|
286
|
-
**Input**: Event list + Commands from Step 4 +
|
|
312
|
+
**Input**: Event list + Commands from Step 4 + automation chains already
|
|
313
|
+
resolved in Step 4b + the plain screens placed in Step 3.
|
|
287
314
|
**Output to carry forward**: Read model definitions — projections of events
|
|
288
|
-
optimized for UI
|
|
315
|
+
optimized for UI queries — one per screen component, with any
|
|
289
316
|
multi-component screen already broken apart into same-named, highlighted
|
|
290
|
-
screen copies (this step's Step 5a/5c, not Step 3's job).
|
|
317
|
+
screen copies (this step's Step 5a/5c, not Step 3's job). Automation
|
|
318
|
+
todo-list read models are already complete from Step 4b and are not
|
|
319
|
+
re-derived here — this step only ever designs screen-facing read models.
|
|
291
320
|
**Gate**: Every screen data need from the storyboards is satisfied by a read
|
|
292
321
|
model, and no read model spans more than one component.
|
|
293
322
|
|
|
@@ -319,18 +348,7 @@ the elaborating-scenarios workflow — not just happy path + one error case —
|
|
|
319
348
|
gate checklist below. A command-only pass is an incomplete Step 7, even if
|
|
320
349
|
every command's coverage looks exhaustive.
|
|
321
350
|
|
|
322
|
-
> **Do not reduce scenarios to a simple good-case / bad-case pair.** The `eventmodeling-elaborating-scenarios` skill defines a structured scenario workshop covering seven scenario types per command. All applicable types must be written before this step is complete.
|
|
323
|
-
|
|
324
|
-
**Scenario types to work through for each command** — which apply is determined by the domain, not by a fixed rule:
|
|
325
|
-
1. **Happy Path** — the normal success case
|
|
326
|
-
2. **Validation Failure** — invalid or missing input
|
|
327
|
-
3. **State Violation** — command issued when system is in an invalid state
|
|
328
|
-
4. **Duplicate Action** — command issued again after it already succeeded
|
|
329
|
-
5. **Alternative Path** — different valid outcomes depending on context
|
|
330
|
-
6. **External Failure** — external system or scheduler fails
|
|
331
|
-
7. **Compensation** — rollback or undo flow
|
|
332
|
-
|
|
333
|
-
For each type, ask the relevant question against the business case and write a scenario if the situation can occur. Do not decide based on brevity — decide based on the domain.
|
|
351
|
+
> **Do not reduce scenarios to a simple good-case / bad-case pair.** The `eventmodeling-elaborating-scenarios` skill defines a structured scenario workshop covering seven scenario types per command (Happy Path, Validation Failure, State Violation, Duplicate Action, Alternative Path, External Failure, Compensation — see that skill's own table for the question-form definition of each) — which apply is determined by the domain, not by a fixed rule. All applicable types must be written before this step is complete; do not decide based on brevity.
|
|
334
352
|
|
|
335
353
|
> **Read models need scenarios too — easy to forget since the seven types above are command-shaped.** Every READMODEL needs at least one view scenario (GWT or storyline); a read model with zero scenarios is as incomplete as a command with zero. `eventmodeling-elaborating-scenarios`'s own checklist covers the details — connectivity rules, GWT-vs-storyline judgment per read model, and avoiding redundancy between a storyline and its GWTs — don't re-derive those here, just enforce the gate.
|
|
336
354
|
|
|
@@ -401,14 +419,7 @@ Not delegated to a separate skill — performed directly by this orchestrating s
|
|
|
401
419
|
mcp__eventmodelers__add_lane { "boardId": "$BOARD_ID", "timelineId": "$CHAPTER_ID", "type": "feedback", "label": "Notes" }
|
|
402
420
|
```
|
|
403
421
|
|
|
404
|
-
**Fallback (no MCP):**
|
|
405
|
-
```bash
|
|
406
|
-
curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/timelines/$CHAPTER_ID/lanes" \
|
|
407
|
-
-H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" -H "x-user-id: orchestrator" \
|
|
408
|
-
-H "Content-Type: application/json" \
|
|
409
|
-
-d '{"type":"feedback","label":"Notes"}'
|
|
410
|
-
# → { laneId, type, label, index, totalLanes }
|
|
411
|
-
```
|
|
422
|
+
**Fallback (no MCP):** see `references/api-fallback.md` — "Step 11 — Document Reasoning — Add a feedback lane".
|
|
412
423
|
|
|
413
424
|
2. **Resolve the first column's ID** — the leftmost entry in `meta.timelineData.columns` (same chapter fetch used throughout this workflow for row/column lookups).
|
|
414
425
|
|
|
@@ -427,15 +438,7 @@ Not delegated to a separate skill — performed directly by this orchestrating s
|
|
|
427
438
|
}
|
|
428
439
|
```
|
|
429
440
|
|
|
430
|
-
**Fallback (no MCP):**
|
|
431
|
-
```bash
|
|
432
|
-
curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/events" \
|
|
433
|
-
-H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" -H "x-user-id: orchestrator" \
|
|
434
|
-
-H "Content-Type: application/json" \
|
|
435
|
-
-d '[{"id":"<event-uuid>","eventType":"node:created","nodeId":"<node-uuid>","boardId":"<BOARD_ID>",
|
|
436
|
-
"timestamp":1234567890,"chapterId":"<CHAPTER_ID>","cellId":"<feedbackLaneId>-<firstColumnId>",
|
|
437
|
-
"meta":{"type":"MARKDOWN","title":"Modeling Reasoning — <Chapter Name>","description":"<full markdown body>"}}]'
|
|
438
|
-
```
|
|
441
|
+
**Fallback (no MCP):** see `references/api-fallback.md` — "Step 11 — Document Reasoning — Create the MARKDOWN node".
|
|
439
442
|
|
|
440
443
|
The note's body lives in **`meta.description`** as plain markdown source — headings, lists, bold, code fences, tables all render. **Not `meta.content`** — that field is accepted and stored without error but never rendered by the board UI, producing a visibly empty note; this was caught by comparing against a note authored directly in the UI, so treat it as confirmed, not a guess. There is no separate render/sketch call (unlike SCREEN/HTML_SCREEN) and no `fields[]` array on this element type.
|
|
441
444
|
|
|
@@ -477,17 +480,23 @@ specific needs:
|
|
|
477
480
|
be applied at any step where those decisions arise, most commonly during or
|
|
478
481
|
after Step 1.
|
|
479
482
|
- **`eventmodeling-optimizing-stream-design`** — Use after the model is
|
|
480
|
-
complete to validate stream
|
|
483
|
+
complete to validate that every stream is anchored on a single business
|
|
484
|
+
identity, not a disguised collection or event log.
|
|
481
485
|
- **`eventmodeling-translating-external-events`** — Use when external systems
|
|
482
486
|
(webhooks, IoT, third-party APIs) need to feed into the domain model.
|
|
483
487
|
|
|
488
|
+
### Further Reading
|
|
489
|
+
|
|
490
|
+
- **[Project Planning with Event Modeling](references/project-planning-with-event-modeling.md)** — why explicit step contracts produce a flat cost curve and let teams build in parallel, plus velocity-based estimation and capacity planning built on workflow steps instead of story points.
|
|
491
|
+
|
|
484
492
|
---
|
|
485
493
|
|
|
486
494
|
## Quality Checklist
|
|
487
495
|
|
|
488
496
|
- [ ] No elements stranded at 0,0 — every EVENT, COMMAND, READMODEL, SCREEN, and AUTOMATION has a valid `cellId` in its chapter
|
|
489
497
|
- [ ] 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
|
|
490
|
-
- [ ] All 11 modeling steps completed — no step skipped without explicit reason
|
|
498
|
+
- [ ] All 11 modeling steps completed (plus Step 4b whenever Step 4 placed any automations) — no step skipped without explicit reason
|
|
499
|
+
- [ ] Every AUTOMATION has a todo-list READMODEL, and no automation's todo list is opened directly by another system's event (Step 4b)
|
|
491
500
|
- [ ] Every COMMAND, READMODEL, and AUTOMATION has a matching slice definition on the board
|
|
492
501
|
- [ ] Every chapter has a Modeling Reasoning MARKDOWN node in its first column, written after that chapter's model was complete
|
|
493
502
|
- [ ] Role Catalog exists with named human roles and system processors
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Orchestrating Event Modeling — 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
|
+
## No unplaced elements (0,0 nodes) — Scan for unplaced nodes
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
for TYPE in EVENT COMMAND READMODEL SCREEN AUTOMATION; do
|
|
9
|
+
curl -s -H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" \
|
|
10
|
+
"$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?type=$TYPE"
|
|
11
|
+
done
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## No unplaced elements (0,0 nodes) — Place a found unplaced node
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/events" \
|
|
18
|
+
-H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" -H "x-user-id: orchestrator" \
|
|
19
|
+
-H "Content-Type: application/json" \
|
|
20
|
+
-d '[{"id":"<uuid>","eventType":"node:changed","nodeId":"<nodeId>","boardId":"<BOARD_ID>",
|
|
21
|
+
"timestamp":1234567890,"chapterId":"<chapterId>","cellId":"<rowId>-<colId>",
|
|
22
|
+
"meta":{"type":"<TYPE>","title":"<title>"}}]'
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## No unplaced elements (0,0 nodes) — Delete an orphaned node
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
curl -s -X DELETE "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/<nodeId>" \
|
|
29
|
+
-H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID"
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Step 11 — Document Reasoning — Add a feedback lane
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/timelines/$CHAPTER_ID/lanes" \
|
|
36
|
+
-H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" -H "x-user-id: orchestrator" \
|
|
37
|
+
-H "Content-Type: application/json" \
|
|
38
|
+
-d '{"type":"feedback","label":"Notes"}'
|
|
39
|
+
# → { laneId, type, label, index, totalLanes }
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Step 11 — Document Reasoning — Create the MARKDOWN node
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/events" \
|
|
46
|
+
-H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" -H "x-user-id: orchestrator" \
|
|
47
|
+
-H "Content-Type: application/json" \
|
|
48
|
+
-d '[{"id":"<event-uuid>","eventType":"node:created","nodeId":"<node-uuid>","boardId":"<BOARD_ID>",
|
|
49
|
+
"timestamp":1234567890,"chapterId":"<CHAPTER_ID>","cellId":"<feedbackLaneId>-<firstColumnId>",
|
|
50
|
+
"meta":{"type":"MARKDOWN","title":"Modeling Reasoning — <Chapter Name>","description":"<full markdown body>"}}]'
|
|
51
|
+
```
|
|
@@ -108,11 +108,7 @@ Prefer MCP:
|
|
|
108
108
|
mcp__eventmodelers__get_nodes { "boardId": "$BOARD_ID", "type": "CHAPTER" }
|
|
109
109
|
```
|
|
110
110
|
|
|
111
|
-
**Fallback (no MCP):**
|
|
112
|
-
```bash
|
|
113
|
-
curl -s -H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" \
|
|
114
|
-
"$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?type=CHAPTER"
|
|
115
|
-
```
|
|
111
|
+
**Fallback (no MCP):** see `references/api-fallback.md` — "Chapters and Timelines — Resolve the Target Timeline".
|
|
116
112
|
|
|
117
113
|
If multiple timelines exist, ask the user which one to work on now. Never reorder events across timelines in a single pass.
|
|
118
114
|
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Plotting Events — 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
|
+
## Chapters and Timelines — Resolve the Target Timeline
|
|
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=CHAPTER"
|
|
10
|
+
```
|
package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/SKILL.md
CHANGED
|
@@ -62,10 +62,7 @@ Prefer MCP:
|
|
|
62
62
|
mcp__eventmodelers__get_nodes { "boardId": "<BOARD_ID>", "type": "CHAPTER" }
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
**Fallback (no MCP):**
|
|
66
|
-
```bash
|
|
67
|
-
curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?type=CHAPTER"
|
|
68
|
-
```
|
|
65
|
+
**Fallback (no MCP):** see `references/api-fallback.md` — "Step 1: Resolve the Timeline".
|
|
69
66
|
|
|
70
67
|
- **Exactly one chapter** → use it automatically, tell the user which one was selected.
|
|
71
68
|
- **Multiple chapters** → list them by name/ID and use `AskUserQuestion` to ask which one to slice.
|
|
@@ -73,34 +70,25 @@ curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?type=CHAPTER"
|
|
|
73
70
|
|
|
74
71
|
## Step 2: Enumerate Commands, Read Models, and Automations
|
|
75
72
|
|
|
76
|
-
Use `spec-info` (or existing board knowledge) to list every COMMAND
|
|
73
|
+
Use `spec-info` (or existing board knowledge) to list every COMMAND and READMODEL node across the resolved timeline — `spec-info` only ever returns EVENT/COMMAND/READMODEL, never AUTOMATION, so pass `elementTypes` to skip the EVENT rows you don't need here:
|
|
77
74
|
|
|
78
75
|
Prefer MCP:
|
|
79
76
|
```
|
|
80
|
-
mcp__eventmodelers__get_spec_info { "boardId": "<BOARD_ID>", "timelineId": "<TL>" }
|
|
77
|
+
mcp__eventmodelers__get_spec_info { "boardId": "<BOARD_ID>", "timelineId": "<TL>", "elementTypes": ["COMMAND", "READMODEL"] }
|
|
81
78
|
```
|
|
82
79
|
|
|
83
|
-
**Fallback (no MCP):**
|
|
84
|
-
```bash
|
|
85
|
-
curl "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/timelines/$TL/spec-info" -H "x-token: $TOKEN"
|
|
86
|
-
# → { timelineId, elements: [{ id, title, type }] }
|
|
87
|
-
```
|
|
80
|
+
**Fallback (no MCP):** see `references/api-fallback.md` — "Step 2: Enumerate Commands, Read Models, and Automations — spec-info".
|
|
88
81
|
|
|
89
|
-
|
|
82
|
+
Separately, enumerate AUTOMATION nodes via `get_nodes { "boardId": "<BOARD_ID>", "type": "AUTOMATION", "chapterId": "<TL>" }` — `spec-info` cannot return them.
|
|
90
83
|
|
|
91
|
-
`spec-info` doesn't include the column each element sits in, so fetch the chapter node to resolve it:
|
|
84
|
+
`spec-info` doesn't include the column each element sits in, so fetch the chapter node to resolve it — `projection: "cells"` returns just `{rows, columns, cells}`, not the whole chapter node:
|
|
92
85
|
|
|
93
86
|
Prefer MCP:
|
|
94
87
|
```
|
|
95
|
-
mcp__eventmodelers__get_node { "boardId": "<BOARD_ID>", "nodeId": "<TL>" }
|
|
88
|
+
mcp__eventmodelers__get_node { "boardId": "<BOARD_ID>", "nodeId": "<TL>", "projection": "cells" }
|
|
96
89
|
```
|
|
97
90
|
|
|
98
|
-
**Fallback (no MCP):**
|
|
99
|
-
```bash
|
|
100
|
-
curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/$TL" -H "x-token: $TOKEN"
|
|
101
|
-
# → meta.timelineData.columns: [{ id, index }]
|
|
102
|
-
# → meta.timelineData.cells: [{ id: "<rowId>-<columnId>", nodeId }]
|
|
103
|
-
```
|
|
91
|
+
**Fallback (no MCP):** see `references/api-fallback.md` — "Step 2: Enumerate Commands, Read Models, and Automations — Chapter Node".
|
|
104
92
|
|
|
105
93
|
For each filtered element, find the cell whose `nodeId` matches the element's `id` — the `columnId` is the cell `id` with the leading `<rowId>-` (36 chars + hyphen) stripped off. Record `{ elementId, elementType, title, columnId }` for every COMMAND, READMODEL, and AUTOMATION.
|
|
106
94
|
|
|
@@ -111,36 +99,30 @@ Prefer MCP:
|
|
|
111
99
|
mcp__eventmodelers__list_slices { "boardId": "<BOARD_ID>" }
|
|
112
100
|
```
|
|
113
101
|
|
|
114
|
-
**Fallback (no MCP):**
|
|
115
|
-
```bash
|
|
116
|
-
curl $BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/slicedata/slices -H "x-token: $TOKEN"
|
|
117
|
-
# → { slices: [{ id, title, status }] }
|
|
118
|
-
```
|
|
102
|
+
**Fallback (no MCP):** see `references/api-fallback.md` — "Step 2: Enumerate Commands, Read Models, and Automations — Check Existing Slices".
|
|
119
103
|
|
|
120
104
|
A column already has a slice if its element's title matches an existing slice's title.
|
|
121
105
|
|
|
122
106
|
## Step 3: Define slices
|
|
123
107
|
|
|
124
|
-
For
|
|
108
|
+
For every column from Step 2 that doesn't already have a matching slice, mark each **existing** column as a slice via the **slice-definitions** endpoint — batch all of them into one call rather than one call per column:
|
|
125
109
|
|
|
126
110
|
Prefer MCP:
|
|
127
111
|
```
|
|
128
|
-
|
|
112
|
+
mcp__eventmodelers__create_slice_definitions { "boardId": "<BOARD_ID>", "timelineId": "<TL>", "slices": [
|
|
113
|
+
{ "columnId": "<colId1>", "title": "PlaceOrder" },
|
|
114
|
+
{ "columnId": "<colId2>", "title": "OrderStatusView" }
|
|
115
|
+
] }
|
|
129
116
|
```
|
|
117
|
+
(`create_slice_definition`, singular, still exists for a one-off single-column case, but prefer the batch form here since Step 3 is defining every remaining column's slice in one pass.)
|
|
130
118
|
|
|
131
|
-
**Fallback (no MCP):**
|
|
132
|
-
```bash
|
|
133
|
-
curl -X POST $BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/timelines/$TL/slice-definitions \
|
|
134
|
-
-H "x-token: $TOKEN" -H "Content-Type: application/json" \
|
|
135
|
-
-d '{"columnId":"<colId>","title":"PlaceOrder"}'
|
|
136
|
-
# → 200 { nodeId, timelineId, columnId, title }
|
|
137
|
-
```
|
|
119
|
+
**Fallback (no MCP):** see `references/api-fallback.md` — "Step 3: Define Slices".
|
|
138
120
|
|
|
139
121
|
- COMMAND column → title = command name (state-change slice)
|
|
140
122
|
- READMODEL column → title = read model name (state-view slice)
|
|
141
123
|
- AUTOMATION column → title = automation name, or the command it issues (automation slice)
|
|
142
124
|
|
|
143
|
-
Use **`
|
|
125
|
+
Use **`create_slice_definitions`/`slice-definitions`**, never `create_slice`/the plain **`slices`** endpoint here — `create_slice`/`slices` creates a brand-new column with its own swimlane/content nodes, which would duplicate the element already placed on the timeline. `create_slice_definitions`/`slice-definitions` only adds a `SLICE_BORDER` node to each column you already resolved in Step 2. `title` always comes from the request body — it is never derived automatically from the command/read model/automation node.
|
|
144
126
|
|
|
145
127
|
**If Step 2 finds nothing to slice** (every COMMAND/READMODEL/AUTOMATION on the timeline already has a matching `SLICE_BORDER`), this skill's job is done — there is no existing element left to make explicit. Do not invent new model content here; that is out of scope for a skill whose whole design assumes the model is already complete. Invoke the `add-next-slice` skill instead — it owns deciding on and creating a genuinely new slice from scratch.
|
|
146
128
|
|
|
@@ -167,4 +149,5 @@ This is useful to surface back to the user (e.g. "`OrderDetailView` depends on `
|
|
|
167
149
|
## Reference Documentation
|
|
168
150
|
|
|
169
151
|
- **[patterns.md](references/patterns.md)** — naming, boundaries, cross-slice communication patterns
|
|
170
|
-
- **[examples.md](references/examples.md)** — worked example of deriving slices from a timeline
|
|
152
|
+
- **[examples.md](references/examples.md)** — worked example of deriving slices from a timeline
|
|
153
|
+
- **[api-fallback.md](references/api-fallback.md)** — curl fallback calls for every MCP operation this skill uses.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Slicing Event Models — 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
|
+
## Step 1: Resolve the Timeline
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?type=CHAPTER"
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Step 2: Enumerate Commands, Read Models, and Automations — spec-info
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
curl "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/timelines/$TL/spec-info" -H "x-token: $TOKEN"
|
|
15
|
+
# → { timelineId, elements: [{ id, title, type }] } — filter client-side to type in COMMAND, READMODEL (no elementTypes param over REST)
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Step 2: Enumerate Commands, Read Models, and Automations — Chapter Node
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/$TL" -H "x-token: $TOKEN"
|
|
22
|
+
# → meta.timelineData.columns: [{ id, index }]
|
|
23
|
+
# → meta.timelineData.cells: [{ id: "<rowId>-<columnId>", nodeId }]
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Step 2: Enumerate Commands, Read Models, and Automations — Check Existing Slices
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
curl $BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/slicedata/slices -H "x-token: $TOKEN"
|
|
30
|
+
# → { slices: [{ id, title, status }] }
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Step 3: Define Slices
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
curl -X POST $BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/timelines/$TL/slice-definitions \
|
|
37
|
+
-H "x-token: $TOKEN" -H "Content-Type: application/json" \
|
|
38
|
+
-d '{"columnId":"<colId>","title":"PlaceOrder"}'
|
|
39
|
+
# → 200 { nodeId, timelineId, columnId, title }
|
|
40
|
+
```
|
|
41
|
+
(one call per column — the REST fallback has no batch form)
|
|
@@ -50,18 +50,21 @@ No slice depends on another slice directly — only on the events it produces.
|
|
|
50
50
|
|
|
51
51
|
## Creating These Slices via the API
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
curl -X POST $BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/timelines/$TL/slices \
|
|
55
|
-
-H "x-token: $TOKEN" -H "Content-Type: application/json" \
|
|
56
|
-
-d '{"type":"state-change","nodes":{"swimlane":{"title":"PlaceOrder"}}}'
|
|
53
|
+
These elements already exist on the timeline (from `spec-info`) — use `create_slice_definitions`/`slice-definitions`, which only adds a `SLICE_BORDER` to each column's existing element. Never use `create_slice`/the plain `/slices` endpoint here: that endpoint creates a brand-new column with its own nodes, which would duplicate the element already on the board.
|
|
57
54
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
55
|
+
```
|
|
56
|
+
mcp__eventmodelers__create_slice_definitions { "boardId": "<BOARD_ID>", "timelineId": "<TL>", "slices": [
|
|
57
|
+
{ "columnId": "<placeOrderColumnId>", "title": "PlaceOrder" },
|
|
58
|
+
{ "columnId": "<orderDetailViewColumnId>", "title": "OrderDetailView" },
|
|
59
|
+
{ "columnId": "<reserveInventoryOnPaymentColumnId>", "title": "ReserveInventoryOnPayment" }
|
|
60
|
+
] }
|
|
61
|
+
```
|
|
61
62
|
|
|
62
|
-
|
|
63
|
+
**Fallback (no MCP)** — one call per column, the REST fallback has no batch form:
|
|
64
|
+
```bash
|
|
65
|
+
curl -X POST $BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/timelines/$TL/slice-definitions \
|
|
63
66
|
-H "x-token: $TOKEN" -H "Content-Type: application/json" \
|
|
64
|
-
-d '{"
|
|
67
|
+
-d '{"columnId":"<placeOrderColumnId>","title":"PlaceOrder"}'
|
|
65
68
|
```
|
|
66
69
|
|
|
67
70
|
---
|
|
@@ -65,16 +65,7 @@ This is the most common dependency: nearly every state-view slice depends on the
|
|
|
65
65
|
|
|
66
66
|
### 1. One Element Per Slice
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
CORRECT:
|
|
70
|
-
Slice: PlaceOrder (state-change) — just the PlaceOrder command
|
|
71
|
-
Slice: OrderDetailView (state-view) — just the OrderDetailView read model
|
|
72
|
-
|
|
73
|
-
WRONG:
|
|
74
|
-
Slice: "Order Management" containing the PlaceOrder command AND the OrderDetailView read model
|
|
75
|
-
Problem: mixes a state-change and a state-view in one slice — the API models
|
|
76
|
-
these as different slice types for a reason.
|
|
77
|
-
```
|
|
68
|
+
See the main SKILL.md's "Core Concept" section — never combine a COMMAND and a READMODEL into one slice, even under an inviting broader "feature" name.
|
|
78
69
|
|
|
79
70
|
### 2. Name the Slice After Its Element
|
|
80
71
|
|