@eventmodelers/cli 1.0.36 → 1.0.38

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/package.json +1 -1
  2. package/shared/skills/learn-eventmodelers-api/SKILL.md +22 -13
  3. package/stacks/modeling-kit/templates/.claude/skills/add-next-slice/SKILL.md +2 -23
  4. package/stacks/modeling-kit/templates/.claude/skills/add-next-slice/references/api-fallback.md +11 -0
  5. package/stacks/modeling-kit/templates/.claude/skills/analyze-existing-model/SKILL.md +6 -57
  6. package/stacks/modeling-kit/templates/.claude/skills/analyze-existing-model/references/api-fallback.md +68 -0
  7. package/stacks/modeling-kit/templates/.claude/skills/attributes/SKILL.md +4 -61
  8. package/stacks/modeling-kit/templates/.claude/skills/attributes/references/api-fallback.md +39 -0
  9. package/stacks/modeling-kit/templates/.claude/skills/discover-storyboard/SKILL.md +9 -53
  10. package/stacks/modeling-kit/templates/.claude/skills/discover-storyboard/references/api-fallback.md +63 -0
  11. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-applying-conways-law/SKILL.md +12 -380
  12. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-applying-conways-law/references/examples.md +329 -0
  13. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-brainstorming-events/SKILL.md +45 -290
  14. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-brainstorming-events/references/api-fallback.md +97 -0
  15. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-brainstorming-events/references/examples.md +35 -0
  16. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-checking-completeness/SKILL.md +15 -410
  17. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-checking-completeness/references/api-fallback.md +22 -0
  18. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-checking-completeness/references/examples.md +397 -0
  19. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-core-rules/SKILL.md +182 -0
  20. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-automation-chains/SKILL.md +148 -0
  21. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-automation-chains/references/api-fallback.md +21 -0
  22. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-event-models/SKILL.md +48 -448
  23. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-event-models/references/examples.md +167 -0
  24. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-elaborating-scenarios/SKILL.md +31 -380
  25. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-elaborating-scenarios/references/api-fallback.md +31 -0
  26. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-elaborating-scenarios/references/examples.md +216 -0
  27. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-inputs/SKILL.md +33 -393
  28. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-inputs/references/api-fallback.md +79 -0
  29. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-inputs/references/examples.md +282 -0
  30. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-outputs/SKILL.md +54 -454
  31. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-outputs/references/api-fallback.md +67 -0
  32. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-outputs/references/examples.md +273 -0
  33. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-interview-protocol/SKILL.md +31 -0
  34. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/SKILL.md +37 -184
  35. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/references/domain-patterns.md +58 -99
  36. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/references/patterns.md +82 -163
  37. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-orchestrating-event-modeling/SKILL.md +86 -78
  38. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-orchestrating-event-modeling/references/api-fallback.md +51 -0
  39. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-plotting-events/SKILL.md +5 -5
  40. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-plotting-events/references/api-fallback.md +10 -0
  41. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/SKILL.md +22 -51
  42. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/references/api-fallback.md +41 -0
  43. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/references/examples.md +12 -9
  44. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/references/patterns.md +1 -10
  45. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-storyboarding-events/SKILL.md +29 -382
  46. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-storyboarding-events/references/api-fallback.md +77 -0
  47. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-storyboarding-events/references/examples.md +271 -0
  48. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-translating-external-events/SKILL.md +12 -349
  49. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-translating-external-events/references/examples.md +306 -0
  50. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models/SKILL.md +69 -107
  51. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models/references/api-fallback.md +14 -0
  52. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models-checklist/SKILL.md +75 -160
  53. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models-checklist/references/api-fallback.md +14 -0
  54. package/stacks/modeling-kit/templates/.claude/skills/examples/SKILL.md +3 -110
  55. package/stacks/modeling-kit/templates/.claude/skills/examples/references/api-fallback.md +118 -0
  56. package/stacks/modeling-kit/templates/.claude/skills/handle-comment/SKILL.md +5 -25
  57. package/stacks/modeling-kit/templates/.claude/skills/handle-comment/references/api-fallback.md +35 -0
  58. package/stacks/modeling-kit/templates/.claude/skills/html-screen/SKILL.md +9 -44
  59. package/stacks/modeling-kit/templates/.claude/skills/html-screen/references/api-fallback.md +51 -0
  60. package/stacks/modeling-kit/templates/.claude/skills/place-element/SKILL.md +34 -180
  61. package/stacks/modeling-kit/templates/.claude/skills/place-element/references/api-fallback.md +203 -0
  62. package/stacks/modeling-kit/templates/.claude/skills/storyboard/SKILL.md +14 -81
  63. package/stacks/modeling-kit/templates/.claude/skills/storyboard/references/api-fallback.md +74 -0
  64. package/stacks/modeling-kit/templates/.claude/skills/storyboard-screen/SKILL.md +4 -45
  65. package/stacks/modeling-kit/templates/.claude/skills/storyboard-screen/references/api-fallback.md +44 -0
  66. package/stacks/modeling-kit/templates/.claude/skills/timeline/SKILL.md +19 -88
  67. package/stacks/modeling-kit/templates/.claude/skills/timeline/references/api-fallback.md +91 -0
  68. package/stacks/modeling-kit/templates/.claude/skills/update-prompt-status/SKILL.md +1 -9
  69. package/stacks/modeling-kit/templates/.claude/skills/update-prompt-status/references/api-fallback.md +14 -0
  70. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-integrating-legacy-systems/SKILL.md +0 -674
  71. 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), or modernizing legacy systems (use eventmodeling-integrating-legacy-systems)."
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
@@ -11,6 +11,8 @@ allowed-tools:
11
11
 
12
12
  > **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.
13
13
 
14
+ 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.
15
+
14
16
  Prefer `mcp__eventmodelers__*` tools when available (registered by the `connect` skill) — the curl blocks below are the fallback for sessions without MCP connected.
15
17
 
16
18
  Coordinates the 11-step Event Modeling workflow. Each step delegates to a
@@ -37,11 +39,15 @@ These rules govern how every element is placed on the board. Enforce them throug
37
39
  - SCREEN (input/command screen) goes in the **actor row of that same column**.
38
40
  - **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
41
 
40
- Every AUTOMATION placed this way still needs its own todo-list READMODEL per `eventmodeling-identifying-outputs` Step 5b — including one whose trigger is an external integration signal. There is no exemption for this either: even when the only visible trigger is the automation's own resulting event, model a todo list that opens and closes within that same slice (per Step 5b's worked pattern) rather than leaving the automation without an incoming READMODEL.
42
+ **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:
43
+ - **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.
44
+ - **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.
45
+
46
+ 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
47
 
42
48
  ### State-view slice (EVENT → READ MODEL → SCREEN)
43
49
  - 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**.
50
+ - 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
51
  - 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
52
 
47
53
  ### Never stack read models at the end
@@ -71,7 +77,7 @@ This is a **business-modeling decision, not a technical one** — it is not trig
71
77
 
72
78
  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
79
 
74
- When that's the case, model it as its own event, produced via the same todo-list + automation translation pattern Step 5b 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.
80
+ 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
81
 
76
82
  **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
83
 
@@ -81,19 +87,13 @@ After each step that creates elements (Steps 1–5), scan for any nodes that hav
81
87
 
82
88
  For each timeline in scope, check all node types that should be in cells.
83
89
 
84
- **Prefer MCP:** call `get_nodes` once per type (each call returns the full node objects, including `meta.chapterId`/cell placement, so no separate cell-occupancy lookup is needed):
90
+ **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):
85
91
  ```
86
- mcp__eventmodelers__get_nodes { "boardId": "$BOARD_ID", "type": "EVENT" }
87
- ```
88
- Repeat with `"type": "COMMAND"`, `"READMODEL"`, `"SCREEN"`, `"AUTOMATION"`.
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
92
+ mcp__eventmodelers__validate_model { "boardId": "$BOARD_ID", "chapterId": "$TIMELINE_ID" }
96
93
  ```
94
+ 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.
95
+
96
+ **Fallback (no MCP):** see `references/api-fallback.md` — "No unplaced elements (0,0 nodes) — Scan for unplaced nodes".
97
97
 
98
98
  For each returned node, check whether it has a valid cell assignment. A node without a `cellId` (or with `chapterId` missing) is unplaced.
99
99
 
@@ -105,15 +105,7 @@ For each returned node, check whether it has a valid cell assignment. A node wit
105
105
  mcp__eventmodelers__drop_node_to_cell { "boardId": "$BOARD_ID", "timelineId": "<chapterId>", "cellId": "<rowId>-<colId>", "nodeId": "<nodeId>", "nodeType": "<TYPE>" }
106
106
  ```
107
107
 
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
- ```
108
+ **Fallback (no MCP):** see `references/api-fallback.md` — "No unplaced elements (0,0 nodes) — Place a found unplaced node".
117
109
  - **If it is an orphan (duplicate or no longer needed)** → delete it.
118
110
 
119
111
  **Prefer MCP:**
@@ -121,18 +113,14 @@ For each returned node, check whether it has a valid cell assignment. A node wit
121
113
  mcp__eventmodelers__delete_node { "boardId": "$BOARD_ID", "nodeId": "<nodeId>" }
122
114
  ```
123
115
 
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
- ```
116
+ **Fallback (no MCP):** see `references/api-fallback.md` — "No unplaced elements (0,0 nodes) — Delete an orphaned node".
129
117
 
130
118
  Never leave an unplaced node on the board when proceeding to the next step.
131
119
 
132
120
  ### No backward arrows
133
121
  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
122
 
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-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.
123
+ **`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
124
 
137
125
  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
126
 
@@ -145,7 +133,30 @@ Before wiring any of the five forward-only pairs, verify that `column(source)
145
133
  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
134
 
147
135
  ### Column insertion
148
- Use `POST /timelines/:tl/columns` with `{"index": N}` to insert a column at a specific position (shifts existing columns right). Do not use `{}` (append) when placing read models or view screens — always target the correct position.
136
+ 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.
137
+
138
+ **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.
139
+
140
+ ### Prefer batch MCP tools over one-call-per-item loops
141
+
142
+ 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:
143
+
144
+ - `set_connections` (not `set_connection` repeated) — wiring multiple edges
145
+ - `auto_connect_nodes` (not `auto_connect_node` repeated) — auto-connecting multiple freshly-placed nodes
146
+ - `create_slice_definitions` (not `create_slice_definition` repeated) — defining multiple slices
147
+ - `create_screens` (not `create_screen` repeated) — creating multiple HTML screens whose content is already authored
148
+ - `move_nodes` (not `move_node_in_timeline` repeated) — moving multiple already-placed nodes within one timeline
149
+ - `delete_nodes` / `delete_columns` (not `delete_node`/`delete_column` repeated) — removing multiple nodes or columns, e.g. a corrective cleanup after a modeling mistake
150
+ - `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
151
+ - `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
152
+
153
+ 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).
154
+
155
+ 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.
156
+
157
+ **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.
158
+
159
+ **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
160
 
150
161
  ### Documenting decisions inline, at any step
151
162
 
@@ -174,7 +185,7 @@ scope, and stated output goal (code, design, learning, docs).
174
185
  Confirm understanding before proceeding: "So we're modeling [domain], goal is
175
186
  [goal], constraints are [constraints]. Starting from [step]. Does that match?"
176
187
 
177
- **Capture findings** — write to `.trogonai/interviews/[project-name]/EVENTMODELING.md`:
188
+ **Capture findings** — create `.trogonai/interviews/[project-name]/EVENTMODELING.md` with this header (this step is what creates the file; every later step appends to it per `eventmodeling-interview-protocol`):
178
189
 
179
190
  ```markdown
180
191
  # Event Modeling: [Project Name]
@@ -188,10 +199,9 @@ Confirm understanding before proceeding: "So we're modeling [domain], goal is
188
199
 
189
200
  | Step | Skill | Status | Key Output |
190
201
  |------|-------|--------|------------|
191
- | Orchestration | eventmodeling-orchestrating-event-modeling | Done | Domain scoped, starting point confirmed |
192
202
  ```
193
203
 
194
- Update this file as each step completes.
204
+ Then follow **`eventmodeling-interview-protocol`** to record this step's own findings and add its Interview Trail row ("Orchestration" / `eventmodeling-orchestrating-event-modeling` / domain scoped, starting point confirmed). Every later step updates the same file as it completes.
195
205
 
196
206
  ---
197
207
 
@@ -279,15 +289,35 @@ role or system processor.
279
289
 
280
290
  ---
281
291
 
292
+ ### Step 4b: Design Automation Chains
293
+
294
+ Invoke `eventmodeling-designing-automation-chains`.
295
+
296
+ **Input**: Every AUTOMATION placed in Step 4, each already paired with its own
297
+ COMMAND in one column.
298
+ **Output to carry forward**: Every automation's todo-list READMODEL, placed
299
+ and wired; every externally-triggered automation resolved into a two-stage
300
+ translation chain (external EVENT → todo-list READMODEL → translation
301
+ AUTOMATION+COMMAND+internal EVENT → worker automation's own todo list).
302
+ **Gate**: No AUTOMATION on the board lacks an incoming `READMODEL →
303
+ AUTOMATION` connection, and no automation's todo list is opened directly by
304
+ another system's (second-swimlane) event. Skip this step only if Step 4
305
+ placed zero automations.
306
+
307
+ ---
308
+
282
309
  ### Step 5: Identify Outputs
283
310
 
284
311
  Invoke `eventmodeling-identifying-outputs`.
285
312
 
286
- **Input**: Event list + Commands from Step 4 + the plain screens placed in Step 3.
313
+ **Input**: Event list + Commands from Step 4 + automation chains already
314
+ resolved in Step 4b + the plain screens placed in Step 3.
287
315
  **Output to carry forward**: Read model definitions — projections of events
288
- optimized for UI and processor queries — one per screen component, with any
316
+ optimized for UI queries — one per screen component, with any
289
317
  multi-component screen already broken apart into same-named, highlighted
290
- screen copies (this step's Step 5a/5c, not Step 3's job).
318
+ screen copies (this step's Step 5a/5c, not Step 3's job). Automation
319
+ todo-list read models are already complete from Step 4b and are not
320
+ re-derived here — this step only ever designs screen-facing read models.
291
321
  **Gate**: Every screen data need from the storyboards is satisfied by a read
292
322
  model, and no read model spans more than one component.
293
323
 
@@ -319,18 +349,7 @@ the elaborating-scenarios workflow — not just happy path + one error case —
319
349
  gate checklist below. A command-only pass is an incomplete Step 7, even if
320
350
  every command's coverage looks exhaustive.
321
351
 
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.
352
+ > **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
353
 
335
354
  > **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
355
 
@@ -359,12 +378,11 @@ Invoke `eventmodeling-validating-event-models`.
359
378
 
360
379
  If FAIL: address findings and re-invoke `eventmodeling-validating-event-models`.
361
380
 
362
- **Optional — Production Readiness Checklist**: Invoke
363
- `eventmodeling-validating-event-models-checklist` when the model is destined
364
- for production. It runs 17 architectural checks across 7 phases and returns a
381
+ **Optional — Structural Checklist**: Invoke
382
+ `eventmodeling-validating-event-models-checklist` for a second, mechanical
383
+ pass. It runs 12 structural checks across 6 phases and returns a
365
384
  PASS / PASS WITH WARNINGS / FAIL verdict independently of Step 9. A PASS on
366
- Step 9 does not substitute for this checklist when production readiness is
367
- required.
385
+ Step 9 does not substitute for this checklist.
368
386
 
369
387
  ---
370
388
 
@@ -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,20 +438,12 @@ 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
 
442
445
  **What the note should actually contain** — write for the next person (or next session) who opens this board cold, not for whoever just built it:
443
- - **Scope**: what business process this chapter covers, and its stream roots (identity keys).
446
+ - **Scope**: what business process this chapter covers, and its entities (identity keys).
444
447
  - **Assumptions added beyond the literal brief** — anything invented to fill a gap the requirements left open, and why (e.g. adding a resolution event so a state isn't a one-way trap door).
445
448
  - **Business rules deliberately encoded as scenarios, not new events** — so a reader doesn't mistake a missing event for an oversight.
446
449
  - **Sequencing or design corrections made mid-workflow** — e.g. a column reorder because an event's original placement implied the wrong causality.
@@ -472,22 +475,27 @@ A complete, sliced event model consisting of:
472
475
  These skills are not part of the 11-step main path but extend the model for
473
476
  specific needs:
474
477
 
475
- - **`eventmodeling-designing-event-models`** — Use when stream identity,
476
- per-command state shapes, or event causality need detailed design work. Can
477
- be applied at any step where those decisions arise, most commonly during or
478
- after Step 1.
478
+ - **`eventmodeling-designing-event-models`** — Use when the Command/Event/Read-Model
479
+ structure or event causality need detailed design work. Can be applied at
480
+ any step where those decisions arise, most commonly during or after Step 1.
479
481
  - **`eventmodeling-optimizing-stream-design`** — Use after the model is
480
- complete to validate stream growth estimates and snapshotting decisions.
482
+ complete to validate that every entity's event timeline is anchored on a
483
+ single business identity, not a disguised collection or event log.
481
484
  - **`eventmodeling-translating-external-events`** — Use when external systems
482
485
  (webhooks, IoT, third-party APIs) need to feed into the domain model.
483
486
 
487
+ ### Further Reading
488
+
489
+ - **[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.
490
+
484
491
  ---
485
492
 
486
493
  ## Quality Checklist
487
494
 
488
495
  - [ ] No elements stranded at 0,0 — every EVENT, COMMAND, READMODEL, SCREEN, and AUTOMATION has a valid `cellId` in its chapter
489
496
  - [ ] 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
497
+ - [ ] All 11 modeling steps completed (plus Step 4b whenever Step 4 placed any automations) — no step skipped without explicit reason
498
+ - [ ] Every AUTOMATION has a todo-list READMODEL, and no automation's todo list is opened directly by another system's event (Step 4b)
491
499
  - [ ] Every COMMAND, READMODEL, and AUTOMATION has a matching slice definition on the board
492
500
  - [ ] Every chapter has a Modeling Reasoning MARKDOWN node in its first column, written after that chapter's model was complete
493
501
  - [ ] 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
+ ```
@@ -10,6 +10,8 @@ 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
17
  Arrange all brainstormed events chronologically to create a logical sequence that makes sense as a narrative timeline. Show how events flow and depend on each other.
@@ -78,6 +80,8 @@ Path A: Payment succeeds → PaymentProcessed
78
80
  Path B: Payment fails → PaymentFailed → OrderCancelled
79
81
  ```
80
82
 
83
+ **Every path here is a decision point, not a divergent journey** — by the time plotting runs, chapter structure is already fixed (Step 1), so a path in this step is always one trigger resolving to one of several outcomes within *this* timeline's story, shown as branching columns. If a "path" you're documenting actually starts a different story with its own screens/commands rather than just deciding how this one ends, it was mis-grouped in Step 1 — stop and send it back to `eventmodeling-brainstorming-events`'s chapter grouping (see its "Divergent journey vs. a decision point" note) rather than modeling it as a branch here.
84
+
81
85
  ### 4. Create Timeline Diagram
82
86
  Visual representation of event flow:
83
87
 
@@ -108,11 +112,7 @@ Prefer MCP:
108
112
  mcp__eventmodelers__get_nodes { "boardId": "$BOARD_ID", "type": "CHAPTER" }
109
113
  ```
110
114
 
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
- ```
115
+ **Fallback (no MCP):** see `references/api-fallback.md` — "Chapters and Timelines — Resolve the Target Timeline".
116
116
 
117
117
  If multiple timelines exist, ask the user which one to work on now. Never reorder events across timelines in a single pass.
118
118
 
@@ -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
+ ```
@@ -11,6 +11,8 @@ allowed-tools:
11
11
 
12
12
  > **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` (in particular the **Slices** section) only if you need to look up a specific endpoint or field this file doesn't cover — don't load it eagerly.
13
13
 
14
+ This step applies the shared element and slice rules in **`eventmodeling-core-rules`** — read it once per session if you haven't already; its "Slices" section defines the state-change/state-view/automation slice types this step derives, so this step doesn't restate them.
15
+
14
16
  > Prefer `mcp__eventmodelers__*` tools when available (registered by the `connect` skill) — the curl blocks below are the fallback for sessions without MCP connected.
15
17
 
16
18
  **Purpose**: Turn a completed event model's timeline into explicit slice definitions on the board, and note the event dependencies between them.
@@ -24,21 +26,7 @@ allowed-tools:
24
26
 
25
27
  ## Core Concept: A Slice Is One Command, One Read Model, or One Automation — Never Combined
26
28
 
27
- A **Feature Slice** is the thinnest possible vertical cut through the model exactly one decision or one query:
28
-
29
- ```
30
- state-change slice = SCREEN/Processor → COMMAND → EVENT(s)
31
- state-view slice = EVENT(s) → READMODEL → SCREEN/Processor
32
- automation slice = EVENT(s) → AUTOMATION → COMMAND → EVENT(s)
33
- ```
34
-
35
- A slice never mixes a COMMAND and a READMODEL — the platform models these as two distinct slice types (`state-change` and `state-view`). If a "feature" needs both a command and a read model (e.g. "place an order" needs the `PlaceOrder` command *and* an `OrderDetailView` read model), that's **two slices**, not one.
36
-
37
- **Key characteristics**:
38
- - Exactly one COMMAND (state-change), exactly one READMODEL (state-view), or one AUTOMATION's command — never combined
39
- - Named after that command, read model, or automation
40
- - Independently deployable
41
- - Communicates with other slices via events only
29
+ See `eventmodeling-core-rules`'s "Slices" section for the definition (state-change / state-view / automation, never combined) and why a feature needing both a command and a read model is two slices, not one.
42
30
 
43
31
  ---
44
32
 
@@ -62,10 +50,7 @@ Prefer MCP:
62
50
  mcp__eventmodelers__get_nodes { "boardId": "<BOARD_ID>", "type": "CHAPTER" }
63
51
  ```
64
52
 
65
- **Fallback (no MCP):**
66
- ```bash
67
- curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?type=CHAPTER"
68
- ```
53
+ **Fallback (no MCP):** see `references/api-fallback.md` — "Step 1: Resolve the Timeline".
69
54
 
70
55
  - **Exactly one chapter** → use it automatically, tell the user which one was selected.
71
56
  - **Multiple chapters** → list them by name/ID and use `AskUserQuestion` to ask which one to slice.
@@ -73,34 +58,25 @@ curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?type=CHAPTER"
73
58
 
74
59
  ## Step 2: Enumerate Commands, Read Models, and Automations
75
60
 
76
- Use `spec-info` (or existing board knowledge) to list every COMMAND, READMODEL, and AUTOMATION node across the resolved timeline:
61
+ 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
62
 
78
63
  Prefer MCP:
79
64
  ```
80
- mcp__eventmodelers__get_spec_info { "boardId": "<BOARD_ID>", "timelineId": "<TL>" }
65
+ mcp__eventmodelers__get_spec_info { "boardId": "<BOARD_ID>", "timelineId": "<TL>", "elementTypes": ["COMMAND", "READMODEL"] }
81
66
  ```
82
67
 
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
- ```
68
+ **Fallback (no MCP):** see `references/api-fallback.md` — "Step 2: Enumerate Commands, Read Models, and Automations — spec-info".
88
69
 
89
- Filter to `type` in `COMMAND`, `READMODEL`, `AUTOMATION`.
70
+ Separately, enumerate AUTOMATION nodes via `get_nodes { "boardId": "<BOARD_ID>", "type": "AUTOMATION", "chapterId": "<TL>" }` `spec-info` cannot return them.
90
71
 
91
- `spec-info` doesn't include the column each element sits in, so fetch the chapter node to resolve it:
72
+ `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
73
 
93
74
  Prefer MCP:
94
75
  ```
95
- mcp__eventmodelers__get_node { "boardId": "<BOARD_ID>", "nodeId": "<TL>" }
76
+ mcp__eventmodelers__get_node { "boardId": "<BOARD_ID>", "nodeId": "<TL>", "projection": "cells" }
96
77
  ```
97
78
 
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
- ```
79
+ **Fallback (no MCP):** see `references/api-fallback.md` — "Step 2: Enumerate Commands, Read Models, and Automations — Chapter Node".
104
80
 
105
81
  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
82
 
@@ -111,36 +87,30 @@ Prefer MCP:
111
87
  mcp__eventmodelers__list_slices { "boardId": "<BOARD_ID>" }
112
88
  ```
113
89
 
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
- ```
90
+ **Fallback (no MCP):** see `references/api-fallback.md` — "Step 2: Enumerate Commands, Read Models, and Automations — Check Existing Slices".
119
91
 
120
92
  A column already has a slice if its element's title matches an existing slice's title.
121
93
 
122
94
  ## Step 3: Define slices
123
95
 
124
- For each column from Step 2 that doesn't already have a matching slice, mark that **existing** column as a slice via the **slice-definitions** endpoint:
96
+ 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
97
 
126
98
  Prefer MCP:
127
99
  ```
128
- mcp__eventmodelers__create_slice_definition { "boardId": "<BOARD_ID>", "timelineId": "<TL>", "columnId": "<colId>", "title": "PlaceOrder" }
100
+ mcp__eventmodelers__create_slice_definitions { "boardId": "<BOARD_ID>", "timelineId": "<TL>", "slices": [
101
+ { "columnId": "<colId1>", "title": "PlaceOrder" },
102
+ { "columnId": "<colId2>", "title": "OrderStatusView" }
103
+ ] }
129
104
  ```
105
+ (`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
106
 
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
- ```
107
+ **Fallback (no MCP):** see `references/api-fallback.md` — "Step 3: Define Slices".
138
108
 
139
109
  - COMMAND column → title = command name (state-change slice)
140
110
  - READMODEL column → title = read model name (state-view slice)
141
111
  - AUTOMATION column → title = automation name, or the command it issues (automation slice)
142
112
 
143
- Use **`create_slice_definition`/`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_definition`/`slice-definitions` only adds a `SLICE_BORDER` node to the 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.
113
+ 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
114
 
145
115
  **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
116
 
@@ -167,4 +137,5 @@ This is useful to surface back to the user (e.g. "`OrderDetailView` depends on `
167
137
  ## Reference Documentation
168
138
 
169
139
  - **[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
140
+ - **[examples.md](references/examples.md)** — worked example of deriving slices from a timeline
141
+ - **[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)