@eventmodelers/cli 1.0.36 → 1.0.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/shared/skills/learn-eventmodelers-api/SKILL.md +22 -13
- package/stacks/modeling-kit/templates/.claude/skills/add-next-slice/SKILL.md +2 -23
- package/stacks/modeling-kit/templates/.claude/skills/add-next-slice/references/api-fallback.md +11 -0
- package/stacks/modeling-kit/templates/.claude/skills/analyze-existing-model/SKILL.md +6 -57
- package/stacks/modeling-kit/templates/.claude/skills/analyze-existing-model/references/api-fallback.md +68 -0
- package/stacks/modeling-kit/templates/.claude/skills/attributes/SKILL.md +4 -61
- package/stacks/modeling-kit/templates/.claude/skills/attributes/references/api-fallback.md +39 -0
- package/stacks/modeling-kit/templates/.claude/skills/discover-storyboard/SKILL.md +9 -53
- package/stacks/modeling-kit/templates/.claude/skills/discover-storyboard/references/api-fallback.md +63 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-applying-conways-law/SKILL.md +12 -380
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-applying-conways-law/references/examples.md +329 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-brainstorming-events/SKILL.md +45 -290
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-brainstorming-events/references/api-fallback.md +97 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-brainstorming-events/references/examples.md +35 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-checking-completeness/SKILL.md +15 -410
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-checking-completeness/references/api-fallback.md +22 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-checking-completeness/references/examples.md +397 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-core-rules/SKILL.md +182 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-automation-chains/SKILL.md +148 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-automation-chains/references/api-fallback.md +21 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-event-models/SKILL.md +48 -448
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-event-models/references/examples.md +167 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-elaborating-scenarios/SKILL.md +31 -380
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-elaborating-scenarios/references/api-fallback.md +31 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-elaborating-scenarios/references/examples.md +216 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-inputs/SKILL.md +33 -393
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-inputs/references/api-fallback.md +79 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-inputs/references/examples.md +282 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-outputs/SKILL.md +54 -454
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-outputs/references/api-fallback.md +67 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-outputs/references/examples.md +273 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-interview-protocol/SKILL.md +31 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/SKILL.md +37 -184
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/references/domain-patterns.md +58 -99
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/references/patterns.md +82 -163
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-orchestrating-event-modeling/SKILL.md +86 -78
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-orchestrating-event-modeling/references/api-fallback.md +51 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-plotting-events/SKILL.md +5 -5
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-plotting-events/references/api-fallback.md +10 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/SKILL.md +22 -51
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/references/api-fallback.md +41 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/references/examples.md +12 -9
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/references/patterns.md +1 -10
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-storyboarding-events/SKILL.md +29 -382
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-storyboarding-events/references/api-fallback.md +77 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-storyboarding-events/references/examples.md +271 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-translating-external-events/SKILL.md +12 -349
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-translating-external-events/references/examples.md +306 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models/SKILL.md +69 -107
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models/references/api-fallback.md +14 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models-checklist/SKILL.md +75 -160
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models-checklist/references/api-fallback.md +14 -0
- package/stacks/modeling-kit/templates/.claude/skills/examples/SKILL.md +3 -110
- package/stacks/modeling-kit/templates/.claude/skills/examples/references/api-fallback.md +118 -0
- package/stacks/modeling-kit/templates/.claude/skills/handle-comment/SKILL.md +5 -25
- package/stacks/modeling-kit/templates/.claude/skills/handle-comment/references/api-fallback.md +35 -0
- package/stacks/modeling-kit/templates/.claude/skills/html-screen/SKILL.md +9 -44
- package/stacks/modeling-kit/templates/.claude/skills/html-screen/references/api-fallback.md +51 -0
- package/stacks/modeling-kit/templates/.claude/skills/place-element/SKILL.md +34 -180
- package/stacks/modeling-kit/templates/.claude/skills/place-element/references/api-fallback.md +203 -0
- package/stacks/modeling-kit/templates/.claude/skills/storyboard/SKILL.md +14 -81
- package/stacks/modeling-kit/templates/.claude/skills/storyboard/references/api-fallback.md +74 -0
- package/stacks/modeling-kit/templates/.claude/skills/storyboard-screen/SKILL.md +4 -45
- package/stacks/modeling-kit/templates/.claude/skills/storyboard-screen/references/api-fallback.md +44 -0
- package/stacks/modeling-kit/templates/.claude/skills/timeline/SKILL.md +19 -88
- package/stacks/modeling-kit/templates/.claude/skills/timeline/references/api-fallback.md +91 -0
- package/stacks/modeling-kit/templates/.claude/skills/update-prompt-status/SKILL.md +1 -9
- package/stacks/modeling-kit/templates/.claude/skills/update-prompt-status/references/api-fallback.md +14 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-integrating-legacy-systems/SKILL.md +0 -674
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/references/snapshotting.md +0 -204
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: eventmodeling-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
|
|
@@ -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
|
-
|
|
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
|
|
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:**
|
|
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
|
-
|
|
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-
|
|
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 `
|
|
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** —
|
|
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
|
-
|
|
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 +
|
|
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
|
|
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 —
|
|
363
|
-
`eventmodeling-validating-event-models-checklist`
|
|
364
|
-
|
|
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
|
|
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
|
|
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
|
|
476
|
-
|
|
477
|
-
|
|
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
|
|
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
|
+
```
|
package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/SKILL.md
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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 **`
|
|
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)
|