@milehimikey/em 1.20.0 → 1.22.0

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 (208) hide show
  1. package/.claude/agents/em-implementer.md +10 -0
  2. package/.claude/agents/em-validator.md +1 -0
  3. package/.claude/skills/event-modeling/SKILL.md +1 -1
  4. package/.claude/skills/event-modeling-conform/SKILL.md +7 -4
  5. package/.claude/skills/event-modeling-conform/reference/conform.md +82 -4
  6. package/.claude/skills/event-modeling-design/SKILL.md +23 -8
  7. package/.claude/skills/event-modeling-discover/SKILL.md +2 -2
  8. package/.claude/skills/event-modeling-discover/reference/extract.md +5 -1
  9. package/.claude/skills/event-modeling-engagement/SKILL.md +1 -1
  10. package/.claude/skills/event-modeling-engagement/reference/engagement.md +1 -0
  11. package/.claude/skills/event-modeling-implement/SKILL.md +5 -3
  12. package/.claude/skills/event-modeling-implement/reference/implement.md +14 -0
  13. package/.claude/skills/event-modeling-review/SKILL.md +19 -7
  14. package/.claude/skills/event-modeling-shared/reference/em-dsl.md +54 -9
  15. package/.claude/skills/event-modeling-shared/reference/methodology.md +35 -2
  16. package/.claude/skills/event-modeling-shared/reference/operating-principles.md +26 -15
  17. package/.claude/skills/event-modeling-shared/reference/slice-doc-schema.md +2 -1
  18. package/.claude/skills/event-modeling-shared/templates/model-readme.md +10 -2
  19. package/.claude/skills/event-modeling-shared/templates/slice.md +7 -1
  20. package/.claude-plugin/marketplace.json +2 -2
  21. package/dist/catalog/build.js +6 -5
  22. package/dist/catalog/build.js.map +1 -1
  23. package/dist/catalog/coverage.d.ts +3 -0
  24. package/dist/catalog/coverage.js +12 -0
  25. package/dist/catalog/coverage.js.map +1 -1
  26. package/dist/catalog/docLocate.d.ts +17 -0
  27. package/dist/catalog/docLocate.js +97 -0
  28. package/dist/catalog/docLocate.js.map +1 -0
  29. package/dist/catalog/frontmatterCoherenceValidate.js +16 -1
  30. package/dist/catalog/frontmatterCoherenceValidate.js.map +1 -1
  31. package/dist/catalog/orphanedSliceDocValidate.js +15 -10
  32. package/dist/catalog/orphanedSliceDocValidate.js.map +1 -1
  33. package/dist/catalog/readSliceDoc.js +5 -4
  34. package/dist/catalog/readSliceDoc.js.map +1 -1
  35. package/dist/catalog/scenarioQualityValidate.js +2 -2
  36. package/dist/catalog/scenarioQualityValidate.js.map +1 -1
  37. package/dist/catalog/sliceDoc.d.ts +8 -0
  38. package/dist/catalog/sliceDoc.js +9 -0
  39. package/dist/catalog/sliceDoc.js.map +1 -1
  40. package/dist/catalog/sliceSections.d.ts +18 -1
  41. package/dist/catalog/sliceSections.js +38 -4
  42. package/dist/catalog/sliceSections.js.map +1 -1
  43. package/dist/cli/api.d.ts +84 -0
  44. package/dist/cli/api.js +146 -15
  45. package/dist/cli/api.js.map +1 -1
  46. package/dist/cli/bindings.d.ts +152 -0
  47. package/dist/cli/bindings.js +462 -0
  48. package/dist/cli/bindings.js.map +1 -0
  49. package/dist/cli/conformScope.d.ts +32 -0
  50. package/dist/cli/conformScope.js +68 -5
  51. package/dist/cli/conformScope.js.map +1 -1
  52. package/dist/cli/defer.js +3 -2
  53. package/dist/cli/defer.js.map +1 -1
  54. package/dist/cli/engagement.d.ts +24 -1
  55. package/dist/cli/engagement.js +50 -6
  56. package/dist/cli/engagement.js.map +1 -1
  57. package/dist/cli/engagementBrief.d.ts +127 -0
  58. package/dist/cli/engagementBrief.js +313 -0
  59. package/dist/cli/engagementBrief.js.map +1 -0
  60. package/dist/cli/engagementFile.d.ts +14 -0
  61. package/dist/cli/engagementFile.js +54 -0
  62. package/dist/cli/engagementFile.js.map +1 -1
  63. package/dist/cli/ledgerCheck.js +11 -8
  64. package/dist/cli/ledgerCheck.js.map +1 -1
  65. package/dist/cli/markImplemented.js +2 -2
  66. package/dist/cli/markImplemented.js.map +1 -1
  67. package/dist/cli/ratify.js +2 -2
  68. package/dist/cli/ratify.js.map +1 -1
  69. package/dist/cli/refsCheck.js +3 -2
  70. package/dist/cli/refsCheck.js.map +1 -1
  71. package/dist/cli/render-inputs.d.ts +1 -1
  72. package/dist/cli/render-inputs.js +3 -2
  73. package/dist/cli/render-inputs.js.map +1 -1
  74. package/dist/cli/review.js +2 -2
  75. package/dist/cli/review.js.map +1 -1
  76. package/dist/cli/revise.js +2 -2
  77. package/dist/cli/revise.js.map +1 -1
  78. package/dist/cli/skillDirs.d.ts +22 -0
  79. package/dist/cli/skillDirs.js +24 -0
  80. package/dist/cli/skillDirs.js.map +1 -1
  81. package/dist/cli/sliceConform.js +2 -1
  82. package/dist/cli/sliceConform.js.map +1 -1
  83. package/dist/cli/sliceIndex.d.ts +19 -3
  84. package/dist/cli/sliceIndex.js +81 -17
  85. package/dist/cli/sliceIndex.js.map +1 -1
  86. package/dist/cli/sliceNew.js +2 -0
  87. package/dist/cli/sliceNew.js.map +1 -1
  88. package/dist/cli/sliceStubAll.js +7 -2
  89. package/dist/cli/sliceStubAll.js.map +1 -1
  90. package/dist/cli/sliceSync.d.ts +12 -0
  91. package/dist/cli/sliceSync.js +42 -4
  92. package/dist/cli/sliceSync.js.map +1 -1
  93. package/dist/cli/status.d.ts +8 -4
  94. package/dist/cli/status.js +6 -4
  95. package/dist/cli/status.js.map +1 -1
  96. package/dist/cli/storylineSplit.d.ts +18 -0
  97. package/dist/cli/storylineSplit.js +110 -0
  98. package/dist/cli/storylineSplit.js.map +1 -0
  99. package/dist/cli/upgrade.js +47 -23
  100. package/dist/cli/upgrade.js.map +1 -1
  101. package/dist/cli/watchStoryline.d.ts +6 -0
  102. package/dist/cli/watchStoryline.js +10 -0
  103. package/dist/cli/watchStoryline.js.map +1 -1
  104. package/dist/cli.js +408 -78
  105. package/dist/cli.js.map +1 -1
  106. package/dist/emit/api.d.ts +8 -1
  107. package/dist/emit/api.js +68 -24
  108. package/dist/emit/api.js.map +1 -1
  109. package/dist/emit/apiSurfaceJson.d.ts +3 -0
  110. package/dist/emit/apiSurfaceJson.js +26 -0
  111. package/dist/emit/apiSurfaceJson.js.map +1 -0
  112. package/dist/emit/engagementJson.d.ts +8 -3
  113. package/dist/emit/engagementJson.js +31 -4
  114. package/dist/emit/engagementJson.js.map +1 -1
  115. package/dist/emit/json.d.ts +22 -1
  116. package/dist/emit/json.js +12 -1
  117. package/dist/emit/json.js.map +1 -1
  118. package/dist/mcp/server.js +111 -9
  119. package/dist/mcp/server.js.map +1 -1
  120. package/dist/model/edges.d.ts +1 -1
  121. package/dist/model/edges.js +8 -1
  122. package/dist/model/edges.js.map +1 -1
  123. package/dist/model/loadModel.d.ts +38 -0
  124. package/dist/model/loadModel.js +122 -0
  125. package/dist/model/loadModel.js.map +1 -0
  126. package/dist/model/model.d.ts +26 -9
  127. package/dist/model/model.js +22 -17
  128. package/dist/model/model.js.map +1 -1
  129. package/dist/model/rules.d.ts +23 -0
  130. package/dist/model/rules.js +23 -0
  131. package/dist/model/rules.js.map +1 -1
  132. package/dist/model/shapeLint.js +95 -0
  133. package/dist/model/shapeLint.js.map +1 -1
  134. package/dist/model/sliceDocIndex.js +13 -5
  135. package/dist/model/sliceDocIndex.js.map +1 -1
  136. package/dist/model/sliceDocPath.d.ts +19 -0
  137. package/dist/model/sliceDocPath.js +49 -0
  138. package/dist/model/sliceDocPath.js.map +1 -0
  139. package/dist/model/storylineMap.d.ts +20 -0
  140. package/dist/model/storylineMap.js +55 -0
  141. package/dist/model/storylineMap.js.map +1 -0
  142. package/dist/model/validate.d.ts +7 -0
  143. package/dist/model/validate.js +8 -0
  144. package/dist/model/validate.js.map +1 -1
  145. package/dist/parser/ast.d.ts +19 -0
  146. package/dist/parser/parser.d.ts +17 -1
  147. package/dist/parser/parser.js +91 -2
  148. package/dist/parser/parser.js.map +1 -1
  149. package/dist/pipeline.d.ts +16 -0
  150. package/dist/pipeline.js +19 -2
  151. package/dist/pipeline.js.map +1 -1
  152. package/dist/render/drawEdges.d.ts +5 -1
  153. package/dist/render/drawEdges.js +57 -4
  154. package/dist/render/drawEdges.js.map +1 -1
  155. package/dist/render/drawNotes.d.ts +4 -1
  156. package/dist/render/drawNotes.js +40 -10
  157. package/dist/render/drawNotes.js.map +1 -1
  158. package/dist/render/render.d.ts +11 -0
  159. package/dist/render/render.js +94 -11
  160. package/dist/render/render.js.map +1 -1
  161. package/dist/render/serve.d.ts +5 -0
  162. package/dist/render/serve.js +18 -2
  163. package/dist/render/serve.js.map +1 -1
  164. package/dist/render/sliceDiagram.js +3 -0
  165. package/dist/render/sliceDiagram.js.map +1 -1
  166. package/dist/render/sliceOverlay.d.ts +4 -5
  167. package/dist/render/sliceOverlay.js +4 -7
  168. package/dist/render/sliceOverlay.js.map +1 -1
  169. package/dist/render/sliceStatus.d.ts +8 -0
  170. package/dist/render/sliceStatus.js +22 -15
  171. package/dist/render/sliceStatus.js.map +1 -1
  172. package/dist/render/storylineBands.d.ts +0 -3
  173. package/dist/render/storylineBands.js +2 -22
  174. package/dist/render/storylineBands.js.map +1 -1
  175. package/dist/render/storylineDiagram.js +17 -69
  176. package/dist/render/storylineDiagram.js.map +1 -1
  177. package/dist/render/storylineMap.d.ts +18 -0
  178. package/dist/render/storylineMap.js +263 -0
  179. package/dist/render/storylineMap.js.map +1 -0
  180. package/dist/render/svgGeometry.d.ts +9 -0
  181. package/dist/render/svgGeometry.js +16 -0
  182. package/dist/render/svgGeometry.js.map +1 -1
  183. package/dist/render/viewerHtml.js +1 -1
  184. package/dist/render/viewerHtml.js.map +1 -1
  185. package/dist/templates.d.ts +5 -1
  186. package/dist/templates.js +39 -2
  187. package/dist/templates.js.map +1 -1
  188. package/package.json +1 -1
  189. package/plugin/.claude-plugin/plugin.json +2 -2
  190. package/plugin/agents/em-implementer.md +10 -0
  191. package/plugin/agents/em-validator.md +1 -0
  192. package/plugin/shared/reference/em-dsl.md +54 -9
  193. package/plugin/shared/reference/methodology.md +35 -2
  194. package/plugin/shared/reference/operating-principles.md +26 -15
  195. package/plugin/shared/reference/slice-doc-schema.md +2 -1
  196. package/plugin/shared/templates/model-readme.md +10 -2
  197. package/plugin/shared/templates/slice.md +7 -1
  198. package/plugin/skills/conform/SKILL.md +7 -4
  199. package/plugin/skills/conform/reference/conform.md +82 -4
  200. package/plugin/skills/design/SKILL.md +23 -8
  201. package/plugin/skills/discover/SKILL.md +2 -2
  202. package/plugin/skills/discover/reference/extract.md +5 -1
  203. package/plugin/skills/engagement/SKILL.md +1 -1
  204. package/plugin/skills/engagement/reference/engagement.md +1 -0
  205. package/plugin/skills/event-modeling/SKILL.md +1 -1
  206. package/plugin/skills/implement/SKILL.md +5 -3
  207. package/plugin/skills/implement/reference/implement.md +14 -0
  208. package/plugin/skills/review/SKILL.md +19 -7
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: design
3
- em-version: 1.20.0
3
+ em-version: 1.22.0
4
4
  description: >-
5
5
  Use when structuring a draft event model into swimlanes and the four patterns (State Change,
6
6
  State View, Automation, Translation), evaluating a model's structural completeness, or writing
@@ -72,7 +72,13 @@ Goal: a structurally complete, **validated** model with correct patterns and swi
72
72
  optional `after "<storyline>"` timeline clause: `em-dsl.md`) so the diagram gets a band per
73
73
  story and `em render --storyline "Name"` can show one alone; slices keep their file order, and
74
74
  a model can adopt storylines incrementally (`slice-outside-storyline` is only an advisory
75
- warning) — but name them before you slice, not after. Then group events into **contexts** (bounded contexts /
75
+ warning) — but name them before you slice, not after. **Once the storylines are named, give
76
+ each its own file** (GH #421): run `em storyline split <root>.em` so the root keeps the
77
+ vocabulary and the storyline list with its flow (`storyline "Name" [after "Other"]`) and each
78
+ story's slices live in `<slug>/<slug>.em` with its docs in `<slug>/slices/` — do this before any
79
+ doc is wired, so nothing moves twice. **A storyline that reads another story's events declares
80
+ `after` it** (`storyline-reads-without-after` flags the ones you miss); two stories that run in
81
+ parallel read nothing from each other. Then group events into **contexts** (bounded contexts /
76
82
  aggregates) — ask which events share a consistency boundary and who owns them. Classify each
77
83
  slice as one of the 4 patterns. **Share the slice between every automation or translation and
78
84
  the command it triggers** (the reaction — processor/translation — together with the command
@@ -92,17 +98,26 @@ Goal: a structurally complete, **validated** model with correct patterns and swi
92
98
  read model; a child view only when its query needs what the parent view lacks), the
93
99
  **views-as-lookups check** per `from "E"` on a view (does E add, change or remove a row here? if
94
100
  it only fills a column, put the column on the event that creates the row and drop E — see
95
- `${CLAUDE_PLUGIN_ROOT}/shared/reference/methodology.md`, "Views as lookups"), and the
101
+ `${CLAUDE_PLUGIN_ROOT}/shared/reference/methodology.md`, "Views as lookups"), then the
102
+ **trigger / housekeeping split** on what is left (*which event is the reason this row appears?*
103
+ that one stays in `from`; every event that only keeps a row current or removes it moves to
104
+ `updates from` — the view still reads it, the diagram no longer draws it; a to-do list with more
105
+ than one or two inbound arrows is missing this split), the **continuation check** per `view X
106
+ again` (it names only the events that changed the view since the previous instance, never the
107
+ first instance's list again), and the
96
108
  **conditional-invariant signal** (invariants or fields that apply only "if `<field>` is set"
97
- mean two intents in one command: split it). The `timeline-entity-clustered`,
98
- `command-second-intent`, `automation-split-by-outcome` and `view-lookup-source` lints are the
99
- mechanical half (the last one only catches the cross-context cases — do the check by eye too); the
100
- 1.18.0 design exit gate is `em validate --shape`. Shape the model first, scaffold docs after: a rename,
109
+ mean two intents in one command: split it). Read each story on its own render and on the canvas
110
+ (`em render <root>.em --map`), not on the full timeline. The `timeline-entity-clustered`,
111
+ `command-second-intent`, `automation-split-by-outcome`, `view-lookup-source`,
112
+ `again-restates-sources` and `storyline-reads-without-after` lints are the
113
+ mechanical half (the lookup one only catches the cross-context cases — do the check by eye too); the
114
+ design exit gate is `em validate --shape`. Shape the model first, scaffold docs after: a rename,
101
115
  split or merge from the reshape would orphan docs already wired with `--wire`. The `slice` phase is unchanged (timeline order).
102
116
  3. **Elaborate scenarios — first pass (step 6).** Scaffold every slice's doc now, one per
103
117
  slice, none skipped: `em slice new "<slice name>" --pattern <state-change|state-view|
104
118
  automation|translation> --swimlane "<Persona> → <Context>" --wire <model>.em` writes
105
- `slices/<slice-name>.md` at `status: draft` (the same command, flags, and `--wire`
119
+ `slices/<slice-name>.md` at `status: draft` (into the slice's own storyline folder when the model
120
+ is split — pass the ROOT model to `--wire`) (the same command, flags, and `--wire`
106
121
  note-binding the `slice` phase's step 2 below documents in full). A slice whose only element
107
122
  is a `view X again` instance is a **continuation** (MIL-208), not a slice to scaffold —
108
123
  `--wire` refuses it and names the originating slice holding `X`'s first declaration; its
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: discover
3
- em-version: 1.20.0
3
+ em-version: 1.22.0
4
4
  description: >-
5
5
  Use when starting a brand-new event model from scratch — greenfield discovery: brainstorming
6
6
  past-tense events, storyboarding the happy path, finding the commands and read models — or when
@@ -69,7 +69,7 @@ Goal: a draft model of events, storyboard, commands, and views. Loose is OK; str
69
69
  **Close the loop before leaving this step:** every event from step 3 must be read by at least one
70
70
  read model. Walk the event list and ask, for each one, *"who looks at this, and what do they do
71
71
  with it?"* An event with no answer is either missing its read model or shouldn't be recorded —
72
- both are worth raising with the user rather than leaving dangling.
72
+ both are worth raising with the user rather than leaving dangling. Keep the draft in one file with inline `storyline` blocks; the design phase splits it into one file per story (`em storyline split`) once the names are settled.
73
73
 
74
74
  End of phase: write/refresh the `.em`, render it, update `.event-modeling.md` (steps done,
75
75
  decisions, open questions — run `em state set-phase model` rather than hand-editing `Current
@@ -104,7 +104,11 @@ it is fine to finish a round with `# TBD`s still parked.
104
104
  here, that would be inventing desired state. Note it as a finding in the Decisions log the same
105
105
  way as an unread event, and leave it for `model`/`slice` to apply the views-as-lookups rule
106
106
  (`../../../shared/reference/methodology.md`, "Views as lookups") once the as-is
107
- model is agreed.
107
+ model is agreed. **Housekeeping handlers are `updates from`, as-is:** when the projection code
108
+ handles an event only to update or delete a row it already holds (a status flip, a due date
109
+ moved, an address changed, a row removed), write that event in `updates from "…"`, not `from` —
110
+ that is what the code does today, it keeps the field tracing complete, and the as-is render then
111
+ shows the one line that puts work on the list instead of every handler.
108
112
  - **R5 — Boundaries & reactions.** Current automations and integrations as-is: schedulers,
109
113
  listeners, outbound syncs, inbound webhooks. Model each as a reaction sharing its slice with
110
114
  the `command` + `event` it triggers (`reaction → command → event`, per `em-dsl.md`) — the
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: engagement
3
- em-version: 1.20.0
3
+ em-version: 1.22.0
4
4
  description: >-
5
5
  Use when leading an engagement: building a named set of ratified event-modeling slices
6
6
  (`em engagement`) into one independent PR per slice, each against main, by dispatching the
@@ -48,6 +48,7 @@ Validator (em-validator, <model>):
48
48
  | diff footprint inside the slice package | PASS |
49
49
  | no diff under `slices/**`, `*.em`, `constitution.md`, `engagements/` | PASS |
50
50
  | PR body cites the slice doc | PASS |
51
+ | `conformance/bindings/<key>.yaml` exists + `em conform bindings check --slice <key> --exit-code` | PASS |
51
52
 
52
53
  Reviewer (em-reviewer, <model>): <findings list verbatim, or NO FINDINGS>
53
54
  Critic (em-critic, <model>): <findings list verbatim, or NO FINDINGS>
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: event-modeling
3
- em-version: 1.20.0
3
+ em-version: 1.22.0
4
4
  description: >-
5
5
  Use when the user runs `/em:event-modeling` (with or without a phase name), or wants to resume an
6
6
  event-modeling session without specifying which part of the process applies. Reads the model's
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: implement
3
- em-version: 1.20.0
3
+ em-version: 1.22.0
4
4
  description: >-
5
5
  Use when building a single ratified event-modeling slice (status: ready-to-implement) into
6
6
  merged, tested code — the one phase where the agent builds rather than facilitates. Gates on
@@ -29,8 +29,10 @@ ships in the originating doc's PR); ship the endpoint a
29
29
  model doesn't show; surface every gap to the user instead of deciding it silently; cover every
30
30
  `INV-<MNEMONIC>-n` and every scenario with tests, proving the citations before merge with
31
31
  `em coverage <model>.em --slice <key> --tests <dir> --strict` (the default form skips a
32
- `ready-to-implement` slice); in spec-kit projects, allocate via
33
- em-sdd-bridge (redirect mode) and never run `/speckit.specify`.
32
+ `ready-to-implement` slice); write or update the slice's `conformance/bindings/<key>.yaml`
33
+ (GH #450, `docs/bindings.md`'s schema) and verify it with `em conform bindings check <model>.em
34
+ --repo <path> --slice <key> --exit-code` before calling the slice done; in spec-kit projects,
35
+ allocate via em-sdd-bridge (redirect mode) and never run `/speckit.specify`.
34
36
 
35
37
  **Gate: no constitution, no first slice.** The constitution is the project's ratified house rules
36
38
  — stack and architectural shape (including which implementation skill each slice pattern routes
@@ -301,6 +301,20 @@ or seem small — see §10.
301
301
  you didn't touch the `.em`, so this only fails if something else broke).
302
302
  - Nothing between the slice doc and the code was committed as a source of truth (see §9 —
303
303
  work containers are ephemeral; generated or symlinked specs are renderings).
304
+ - **The slice's bindings file is written or updated** (GH #450): `conformance/bindings/<slice-
305
+ key>.yaml`, beside the model, per [`docs/bindings.md`](https://github.com/milehimikey/em/blob/main/docs/bindings.md)'s
306
+ schema. You just wrote the code — you know which file and identifier anchors each element
307
+ this slice's doc declares (`ref: <kind>.<slug>`, bare, no `<slice-key>/` prefix) and each
308
+ `INV-<MNEMONIC>-n` invariant's enforcement and test sites. This is a file contract, not an
309
+ `em`-run write: author or hand-edit the YAML directly, the same way you'd write any other file
310
+ in your PR. Verify it before calling the slice done:
311
+ ```bash
312
+ em conform bindings check <model>.em --repo <path> --slice <slice-key> --exit-code
313
+ ```
314
+ Exit 0 is required — fix the file (a wrong `ref`, a stale `file`/`identifier` pair) rather than
315
+ shipping a binding that doesn't check out. A continuation key (§5, an `again` view instance)
316
+ has no bindings file of its own; its elements and invariants are bound inside the originating
317
+ slice's file alongside the rest of that doc's bindings.
304
318
 
305
319
  ## 6. At merge: the lifecycle flip
306
320
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: review
3
- em-version: 1.20.0
3
+ em-version: 1.22.0
4
4
  description: >-
5
5
  Use when starting em's live browser viewer (`em watch --serve`) so a team can watch a model
6
6
  update in real time, or facilitating a SCHEDULED stakeholder walkthrough that steps through
@@ -16,8 +16,16 @@ description: >-
16
16
  Start the watcher with `--serve` in the background:
17
17
  `em watch <model-name>.em -o <model-name>.svg --serve` (run_in_background). It re-renders on every
18
18
  save and pushes an instant reload to the browser over Server-Sent Events. Tell the user to open the
19
- URL it prints (e.g. `http://localhost:5173/?svg=<model-name>.svg`) and share their screen — updates
20
- appear the moment you save, with no polling and no idle churn between edits.
19
+ URL it prints and share their screen — updates appear the moment you save, with no polling and no
20
+ idle churn between edits.
21
+
22
+ What that URL opens depends on the model. A model that declares storylines opens on the
23
+ **storyline canvas** (`http://localhost:5173/map`): every storyline's own diagram in a draggable
24
+ frame, the flow between storylines drawn between frames, reloaded live on every save with the
25
+ layout kept. A frame's **open ›** drills into that storyline — the viewer on its own slices and
26
+ nothing from outside it — and **‹ Storylines** in the header returns to the canvas. A model
27
+ without storylines opens on the timeline (`http://localhost:5173/?svg=<model-name>.svg`). Never
28
+ send a room to the full timeline of a storyline model; the storyline is the unit people read.
21
29
 
22
30
  The viewer navigates like a map — drag to pan, scroll/pinch to zoom, **Fit** to reset — and its
23
31
  **Review mode** steps through slices one at a time (see the `review` phase below). A save that
@@ -35,10 +43,14 @@ speculation.** Don't propose this phase proactively; it exists for facilitated r
35
43
  non-engineer stakeholders in the room, not routine model editing.
36
44
 
37
45
  Start the same live server as `watch`: `em watch <model-name>.em -o <model-name>.svg --serve`
38
- (run_in_background). Open the printed URL, click **Review mode** in the header, and share the
39
- screen. Use Prev/Next (or the left/right arrow keys) to step through slices in declaration
40
- order — each one pans/zooms into view with everything else dimmed, so the room's attention
41
- tracks one slice at a time.
46
+ (run_in_background). Open the printed URL and share the screen. With storylines, review one
47
+ storyline at a time: open it from the canvas (or start inside it with `--storyline "<name>"`),
48
+ then click **Review mode** in the header — Prev/Next walk that storyline's slices only. Between
49
+ storylines, **‹ Storylines** returns to the canvas, where the arrows between frames are the
50
+ order to take them in. Without storylines, click **Review mode** on the timeline. Use Prev/Next
51
+ (or the left/right arrow keys) to step through slices in declaration order — each one
52
+ pans/zooms into view with everything else dimmed, so the room's attention tracks one slice at
53
+ a time.
42
54
 
43
55
  **When a State View slice is on screen, ask who reads it (MIL-215):** a person or client in the
44
56
  room → the `ui` should draw it; another system → `public`; only an automation → nothing, it's