@milehimikey/em 1.13.1 → 1.14.1

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 (235) hide show
  1. package/.claude/agents/em-critic.md +26 -0
  2. package/.claude/agents/em-implementer.md +34 -0
  3. package/.claude/agents/em-reviewer.md +31 -0
  4. package/.claude/agents/em-validator.md +27 -0
  5. package/.claude/skills/event-modeling/SKILL.md +50 -11
  6. package/.claude/skills/event-modeling-conform/SKILL.md +1 -1
  7. package/.claude/skills/event-modeling-design/SKILL.md +127 -18
  8. package/.claude/skills/event-modeling-discover/SKILL.md +1 -1
  9. package/.claude/skills/event-modeling-engagement/SKILL.md +192 -0
  10. package/.claude/skills/event-modeling-engagement/reference/engagement.md +143 -0
  11. package/.claude/skills/event-modeling-implement/SKILL.md +1 -1
  12. package/.claude/skills/event-modeling-implement/reference/implement.md +38 -11
  13. package/.claude/skills/event-modeling-review/SKILL.md +2 -2
  14. package/.claude/skills/event-modeling-shared/reference/em-dsl.md +279 -189
  15. package/.claude/skills/event-modeling-shared/reference/operating-principles.md +61 -0
  16. package/.claude/skills/event-modeling-shared/reference/slice-doc-schema.md +116 -5
  17. package/.claude/skills/event-modeling-shared/templates/constitution.md +18 -1
  18. package/.claude/skills/event-modeling-shared/templates/slice.md +64 -39
  19. package/.claude/skills/event-modeling-shared/templates/state.md +5 -1
  20. package/.claude-plugin/marketplace.json +14 -0
  21. package/README.md +25 -11
  22. package/dist/catalog/apiFirst.d.ts +28 -0
  23. package/dist/catalog/apiFirst.js +49 -0
  24. package/dist/catalog/apiFirst.js.map +1 -0
  25. package/dist/catalog/docJoin.d.ts +13 -0
  26. package/dist/catalog/docJoin.js +11 -0
  27. package/dist/catalog/docJoin.js.map +1 -1
  28. package/dist/catalog/docModelConsistencyValidate.js +44 -4
  29. package/dist/catalog/docModelConsistencyValidate.js.map +1 -1
  30. package/dist/catalog/invariantsValidate.d.ts +4 -0
  31. package/dist/catalog/invariantsValidate.js +102 -0
  32. package/dist/catalog/invariantsValidate.js.map +1 -0
  33. package/dist/catalog/scenarios.d.ts +15 -0
  34. package/dist/catalog/scenarios.js +97 -0
  35. package/dist/catalog/scenarios.js.map +1 -0
  36. package/dist/catalog/sliceDoc.d.ts +8 -0
  37. package/dist/catalog/sliceDoc.js +9 -0
  38. package/dist/catalog/sliceDoc.js.map +1 -1
  39. package/dist/catalog/sliceReadyValidate.d.ts +31 -4
  40. package/dist/catalog/sliceReadyValidate.js +66 -8
  41. package/dist/catalog/sliceReadyValidate.js.map +1 -1
  42. package/dist/catalog/sliceSections.d.ts +55 -0
  43. package/dist/catalog/sliceSections.js +317 -0
  44. package/dist/catalog/sliceSections.js.map +1 -0
  45. package/dist/cli/agentsMd.js +7 -1
  46. package/dist/cli/agentsMd.js.map +1 -1
  47. package/dist/cli/api.d.ts +90 -0
  48. package/dist/cli/api.js +318 -0
  49. package/dist/cli/api.js.map +1 -0
  50. package/dist/cli/ciInit.d.ts +82 -21
  51. package/dist/cli/ciInit.js +468 -64
  52. package/dist/cli/ciInit.js.map +1 -1
  53. package/dist/cli/conformScope.d.ts +28 -0
  54. package/dist/cli/conformScope.js +67 -0
  55. package/dist/cli/conformScope.js.map +1 -1
  56. package/dist/cli/coverage.d.ts +9 -0
  57. package/dist/cli/coverage.js +60 -8
  58. package/dist/cli/coverage.js.map +1 -1
  59. package/dist/cli/defer.d.ts +55 -0
  60. package/dist/cli/defer.js +244 -0
  61. package/dist/cli/defer.js.map +1 -0
  62. package/dist/cli/engagement.d.ts +210 -0
  63. package/dist/cli/engagement.js +444 -0
  64. package/dist/cli/engagement.js.map +1 -0
  65. package/dist/cli/engagementFile.d.ts +86 -0
  66. package/dist/cli/engagementFile.js +255 -0
  67. package/dist/cli/engagementFile.js.map +1 -0
  68. package/dist/cli/metrics.d.ts +10 -0
  69. package/dist/cli/metrics.js +49 -1
  70. package/dist/cli/metrics.js.map +1 -1
  71. package/dist/cli/pluginPin.d.ts +55 -0
  72. package/dist/cli/pluginPin.js +188 -0
  73. package/dist/cli/pluginPin.js.map +1 -0
  74. package/dist/cli/ratify.d.ts +27 -2
  75. package/dist/cli/ratify.js +112 -13
  76. package/dist/cli/ratify.js.map +1 -1
  77. package/dist/cli/reratify.d.ts +4 -2
  78. package/dist/cli/reratify.js +41 -16
  79. package/dist/cli/reratify.js.map +1 -1
  80. package/dist/cli/scopeInputs.d.ts +48 -0
  81. package/dist/cli/scopeInputs.js +176 -0
  82. package/dist/cli/scopeInputs.js.map +1 -0
  83. package/dist/cli/skillCheck.d.ts +15 -1
  84. package/dist/cli/skillCheck.js +22 -1
  85. package/dist/cli/skillCheck.js.map +1 -1
  86. package/dist/cli/skillDirs.d.ts +5 -0
  87. package/dist/cli/skillDirs.js +13 -1
  88. package/dist/cli/skillDirs.js.map +1 -1
  89. package/dist/cli/skillSync.d.ts +4 -0
  90. package/dist/cli/skillSync.js +23 -0
  91. package/dist/cli/skillSync.js.map +1 -1
  92. package/dist/cli/sliceNew.d.ts +11 -7
  93. package/dist/cli/sliceNew.js +91 -18
  94. package/dist/cli/sliceNew.js.map +1 -1
  95. package/dist/cli/sliceSync.d.ts +50 -0
  96. package/dist/cli/sliceSync.js +170 -0
  97. package/dist/cli/sliceSync.js.map +1 -0
  98. package/dist/cli/status.d.ts +24 -1
  99. package/dist/cli/status.js +20 -1
  100. package/dist/cli/status.js.map +1 -1
  101. package/dist/cli/systemInputs.d.ts +53 -10
  102. package/dist/cli/systemInputs.js +186 -11
  103. package/dist/cli/systemInputs.js.map +1 -1
  104. package/dist/cli/upgrade.d.ts +16 -3
  105. package/dist/cli/upgrade.js +366 -30
  106. package/dist/cli/upgrade.js.map +1 -1
  107. package/dist/cli/usageLog.d.ts +4 -2
  108. package/dist/cli/usageLog.js +4 -2
  109. package/dist/cli/usageLog.js.map +1 -1
  110. package/dist/cli.js +599 -94
  111. package/dist/cli.js.map +1 -1
  112. package/dist/emit/api.d.ts +29 -0
  113. package/dist/emit/api.js +220 -0
  114. package/dist/emit/api.js.map +1 -0
  115. package/dist/emit/apiCheckJson.d.ts +3 -0
  116. package/dist/emit/apiCheckJson.js +21 -0
  117. package/dist/emit/apiCheckJson.js.map +1 -0
  118. package/dist/emit/codeownersJson.d.ts +3 -0
  119. package/dist/emit/codeownersJson.js +19 -0
  120. package/dist/emit/codeownersJson.js.map +1 -0
  121. package/dist/emit/diffJson.d.ts +1 -1
  122. package/dist/emit/diffJson.js +8 -1
  123. package/dist/emit/diffJson.js.map +1 -1
  124. package/dist/emit/engagementJson.d.ts +8 -0
  125. package/dist/emit/engagementJson.js +46 -0
  126. package/dist/emit/engagementJson.js.map +1 -0
  127. package/dist/emit/glossaryJson.d.ts +1 -1
  128. package/dist/emit/glossaryJson.js +4 -1
  129. package/dist/emit/glossaryJson.js.map +1 -1
  130. package/dist/emit/json.d.ts +17 -1
  131. package/dist/emit/json.js +30 -1
  132. package/dist/emit/json.js.map +1 -1
  133. package/dist/emit/metricsJson.d.ts +1 -1
  134. package/dist/emit/metricsJson.js +4 -1
  135. package/dist/emit/metricsJson.js.map +1 -1
  136. package/dist/emit/queryJson.d.ts +1 -1
  137. package/dist/emit/queryJson.js +7 -1
  138. package/dist/emit/queryJson.js.map +1 -1
  139. package/dist/emit/scopeJson.d.ts +12 -0
  140. package/dist/emit/scopeJson.js +26 -0
  141. package/dist/emit/scopeJson.js.map +1 -0
  142. package/dist/emit/skillCheckJson.d.ts +3 -2
  143. package/dist/emit/skillCheckJson.js +10 -2
  144. package/dist/emit/skillCheckJson.js.map +1 -1
  145. package/dist/emit/statusJson.d.ts +1 -1
  146. package/dist/emit/statusJson.js +15 -1
  147. package/dist/emit/statusJson.js.map +1 -1
  148. package/dist/emit/systemJson.d.ts +15 -8
  149. package/dist/emit/systemJson.js +28 -13
  150. package/dist/emit/systemJson.js.map +1 -1
  151. package/dist/emit/validateJson.d.ts +3 -3
  152. package/dist/emit/validateJson.js +10 -4
  153. package/dist/emit/validateJson.js.map +1 -1
  154. package/dist/mcp/server.d.ts +1 -1
  155. package/dist/mcp/server.js +163 -31
  156. package/dist/mcp/server.js.map +1 -1
  157. package/dist/model/diff.d.ts +4 -1
  158. package/dist/model/diff.js +44 -8
  159. package/dist/model/diff.js.map +1 -1
  160. package/dist/model/glossary.d.ts +2 -0
  161. package/dist/model/glossary.js +1 -0
  162. package/dist/model/glossary.js.map +1 -1
  163. package/dist/model/model.d.ts +55 -2
  164. package/dist/model/model.js +57 -0
  165. package/dist/model/model.js.map +1 -1
  166. package/dist/model/qualifiedRef.d.ts +18 -0
  167. package/dist/model/qualifiedRef.js +26 -0
  168. package/dist/model/qualifiedRef.js.map +1 -1
  169. package/dist/model/queryIndex.d.ts +9 -1
  170. package/dist/model/queryIndex.js +18 -2
  171. package/dist/model/queryIndex.js.map +1 -1
  172. package/dist/model/rules.d.ts +143 -2
  173. package/dist/model/rules.js +162 -3
  174. package/dist/model/rules.js.map +1 -1
  175. package/dist/model/validate.d.ts +40 -0
  176. package/dist/model/validate.js +147 -1
  177. package/dist/model/validate.js.map +1 -1
  178. package/dist/parser/ast.d.ts +31 -3
  179. package/dist/parser/parser.js +148 -14
  180. package/dist/parser/parser.js.map +1 -1
  181. package/dist/query/format.js +1 -1
  182. package/dist/query/format.js.map +1 -1
  183. package/dist/query/verbs.d.ts +6 -0
  184. package/dist/query/verbs.js +6 -2
  185. package/dist/query/verbs.js.map +1 -1
  186. package/dist/system/adaptation.d.ts +14 -0
  187. package/dist/system/adaptation.js +49 -0
  188. package/dist/system/adaptation.js.map +1 -0
  189. package/dist/system/codeowners.d.ts +77 -0
  190. package/dist/system/codeowners.js +242 -0
  191. package/dist/system/codeowners.js.map +1 -0
  192. package/dist/system/manifest.d.ts +10 -5
  193. package/dist/system/manifest.js +54 -26
  194. package/dist/system/manifest.js.map +1 -1
  195. package/dist/system/migrateManifest.d.ts +28 -0
  196. package/dist/system/migrateManifest.js +155 -0
  197. package/dist/system/migrateManifest.js.map +1 -0
  198. package/dist/system/scope.d.ts +46 -0
  199. package/dist/system/scope.js +132 -0
  200. package/dist/system/scope.js.map +1 -0
  201. package/dist/system/verify.d.ts +50 -13
  202. package/dist/system/verify.js +179 -58
  203. package/dist/system/verify.js.map +1 -1
  204. package/dist/templates.d.ts +2 -2
  205. package/dist/templates.js +23 -2
  206. package/dist/templates.js.map +1 -1
  207. package/package.json +5 -2
  208. package/plugin/.claude-plugin/plugin.json +18 -0
  209. package/plugin/agents/em-critic.md +27 -0
  210. package/plugin/agents/em-implementer.md +35 -0
  211. package/plugin/agents/em-reviewer.md +32 -0
  212. package/plugin/agents/em-validator.md +28 -0
  213. package/plugin/shared/reference/em-dsl.md +871 -0
  214. package/plugin/shared/reference/methodology.md +329 -0
  215. package/plugin/shared/reference/operating-principles.md +222 -0
  216. package/plugin/shared/reference/slice-doc-schema.md +574 -0
  217. package/plugin/shared/templates/conformance-report.md +85 -0
  218. package/plugin/shared/templates/constitution.md +136 -0
  219. package/plugin/shared/templates/model-readme.md +46 -0
  220. package/plugin/shared/templates/slice.md +251 -0
  221. package/plugin/shared/templates/state.md +77 -0
  222. package/plugin/skills/conform/SKILL.md +93 -0
  223. package/plugin/skills/conform/reference/conform.md +428 -0
  224. package/plugin/skills/design/SKILL.md +298 -0
  225. package/plugin/skills/discover/SKILL.md +90 -0
  226. package/plugin/skills/discover/reference/extract.md +147 -0
  227. package/plugin/skills/engagement/SKILL.md +193 -0
  228. package/plugin/skills/engagement/reference/engagement.md +144 -0
  229. package/plugin/skills/event-modeling/SKILL.md +132 -0
  230. package/plugin/skills/implement/SKILL.md +61 -0
  231. package/plugin/skills/implement/reference/implement.md +439 -0
  232. package/plugin/skills/review/SKILL.md +74 -0
  233. package/dist/emit/typespec.d.ts +0 -26
  234. package/dist/emit/typespec.js +0 -356
  235. package/dist/emit/typespec.js.map +0 -1
@@ -0,0 +1,85 @@
1
+ <!-- GENERATED FILE from .claude/skills/event-modeling-shared/templates/conformance-report.md by scripts/build-plugin.ts — do not hand-edit; run npm run docs:generate -->
2
+ <!--
3
+ Conformance report skeleton. One per conform run, stored at
4
+ <model-name>/conformance/<YYYY-MM-DD>-report.md (see reference/conform.md).
5
+ Fill every section; leave "none" rather than deleting a section with nothing to report.
6
+ Replace bracketed placeholders; delete guidance comments before finishing.
7
+ -->
8
+
9
+ # Conformance Report — {{Model Name}} — {{YYYY-MM-DD}}
10
+
11
+ - **Model:** `{{model-name}}.em`
12
+ - **Target repo:** {{repo path or URL}} @ `{{revision}}`
13
+ - **Previous conformance revision:** {{prior target-repo revision, or "never (first run)"}}
14
+ - **Scope:** {{full | diff-scoped since <prior revision>}}
15
+ - **Slices checked:** {{comma-separated slice names, or "all implemented slices"}}
16
+ - **Slices skipped (not yet implemented):** {{list, or "none"}}
17
+
18
+ ## Summary
19
+
20
+ | Surface | Real drift | Model gap | Internal inconsistency | Accepted divergence | Unpropagated delta | Uncertainty |
21
+ |---|---|---|---|---|---|---|
22
+ | Structural | {{n}} | {{n}} | — | {{n}} | {{n}} | {{n}} |
23
+ | Spec | {{n}} | {{n}} | — | {{n}} | {{n}} | {{n}} |
24
+ | Internal | — | — | {{n}} | {{n}} | — | {{n}} |
25
+
26
+ **Unpropagated delta** — a slice re-ratified past its shipped version (`slice.doc.driftSignal:
27
+ "unpropagated-delta"` in `em export --json`): a known state, not a code defect. See
28
+ `reference/conform.md` step 4.
29
+
30
+ {{One or two sentences: overall read — clean, mostly clean with N items, or notably drifted.}}
31
+
32
+ ## Findings
33
+
34
+ <!-- One subsection per finding. Group however reads clearest (by slice, or by surface) but keep
35
+ every field below for every finding. Order doesn't matter; classification does.
36
+
37
+ MIL-214: this section's structured twin is `conformance/{{YYYY-MM-DD}}-findings.json`,
38
+ written ALONGSIDE this report (not after it) — one JSON entry per `### n.` finding below,
39
+ `id` matching `{{n}}`. See reference/conform.md step 5 for the exact shape and the write-then-
40
+ `em conform-findings check`-it discipline. A later `em conform-supersede --locus --by` call
41
+ records the ruling on both the JSON (locus/resolvedBy/resolvedOn) and this report's banner
42
+ in one call. -->
43
+
44
+ ### {{n}}. {{Short finding title}}
45
+
46
+ - **Surface:** {{structural | spec | internal}}
47
+ - **Classification:** {{real drift | model gap | internal inconsistency | accepted divergence | unpropagated delta}}
48
+ - **Slice:** {{slice name}}
49
+ - **Evidence:** {{file path(s) and line/symbol, or the `em diff --json` entry (type + name) —
50
+ for accepted divergence, the `divergence "..."` annotation text itself; for unpropagated
51
+ delta, `slice.doc.driftSignal` and `slice.doc.version` from `em export --json`}}
52
+ - **Claim:** {{what the model/doc says vs. what the code/doc shows — the actual disagreement}}
53
+ - **Proposed red note:** `issue "conformance: {{text}}"` on {{element}} (slice "{{slice}}")
54
+ <!-- Omit this line entirely for internal-inconsistency findings with no clear side to flag,
55
+ for any accepted-divergence or unpropagated-delta finding (already ratified, or already
56
+ a known pending-ship state — don't propose re-ratifying either), or when the finding
57
+ doesn't warrant a red note (say why instead). -->
58
+
59
+ ## Scenario / invariant coverage
60
+
61
+ <!-- Per in-scope slice: every named invariant and every GWT scenario the doc claims, mapped to
62
+ its enforcement/test site. Leave a cell explicitly blank/"none found" rather than omitting
63
+ the row — gaps are the point of this table. -->
64
+
65
+ ### {{Slice Name}}
66
+
67
+ | Claim | Type | Enforcement site | Test site | Status |
68
+ |---|---|---|---|---|
69
+ | {{INV-XXX-1 or scenario title}} | {{invariant \| scenario}} | {{file path / symbol, or "none found"}} | {{file path / symbol, or "none found"}} | {{covered \| gap \| uncertain}} |
70
+
71
+ ## Uncertainties
72
+
73
+ <!-- Listed separately from Findings — these are NOT drift. No evidence either way; say what was
74
+ missing (time, clarity, an ambiguous test) so a follow-up run can pick it up. -->
75
+
76
+ - **{{structural | spec | internal}}** — {{what's uncertain}} — {{slice}} — {{why: e.g. "couldn't locate the test for INV-CHK-3, only its enforcement site"}}
77
+
78
+ <!-- Tag each with its surface so these reconcile against the Summary table's Uncertainty column. -->
79
+
80
+ ## Applied this run
81
+
82
+ <!-- Filled in AFTER the user reviews Findings and says what to apply. Leave "none yet — awaiting
83
+ ratification" until that conversation happens. -->
84
+
85
+ {{List of ratified proposals actually applied to the `.em`/slice docs, or "none yet — awaiting ratification".}}
@@ -0,0 +1,136 @@
1
+ <!-- GENERATED FILE from .claude/skills/event-modeling-shared/templates/constitution.md by scripts/build-plugin.ts — do not hand-edit; run npm run docs:generate -->
2
+ <!--
3
+ The implementation constitution: the house rules an implementing agent follows on EVERY slice —
4
+ stack, code style, testing norms, NFR baselines, review norms. It answers "how do we build things
5
+ here" once, so no slice doc has to repeat it and no agent has to invent it. Slice docs say WHAT to
6
+ build; this says HOW it gets built here.
7
+
8
+ Where this document lives:
9
+ - No SDD tool: `constitution.md` beside the model — `em scaffold` writes it there.
10
+ - spec-kit project (a `.specify/` directory exists anywhere above the model): the document IS
11
+ `.specify/memory/constitution.md`. em writes no second copy; the sections below merge into
12
+ that file under these same headings, never overwriting text already there, and ratification is
13
+ recorded in spec-kit's own `**Ratified**:` footer line instead of the frontmatter below.
14
+
15
+ How it gets filled: not by an agent guessing. Each section opens with the question a short
16
+ facilitated conversation asks before the first slice is implemented — the procedure is "Before the
17
+ first slice: the constitution" in the `em:implement` skill's `reference/implement.md`
18
+ (`em contract` prints it). Replace each `{{...}}` block with the real answers; delete the guidance
19
+ comments and any row that doesn't apply.
20
+
21
+ Ratification: `ratifiedBy:`/`ratifiedOn:` are the same identity discipline slice docs use — a
22
+ NAMED human and an ISO date, hand-filled at sign-off (no `em` command writes this file).
23
+ **A constitution with an empty `ratifiedBy:` is a draft**: an implementing agent treats it as
24
+ unratified, says so, and does not proceed on unilateral style or stack decisions for a first slice.
25
+
26
+ `em status` reports this document as present or absent per model — existence only. em never reads
27
+ or validates its content, and the CLI parses nothing here. Three lines are read as plain text by
28
+ the engagement skill and its sub-agents, so keep their exact shape: `- **Test command:**` (the
29
+ validator), `- **Merge strategy:**` and `- **Agent models:**` (the engagement skill). In a spec-kit
30
+ project they merge under the same headings in `.specify/memory/constitution.md`.
31
+ -->
32
+
33
+ ---
34
+ schemaVersion: 1
35
+ ratifiedBy:
36
+ ratifiedOn:
37
+ ---
38
+ # {{Project Name}} — implementation constitution
39
+
40
+ The house rules for how implementation happens in this project. They bound every "purely
41
+ technical choice" an implementing agent would otherwise make alone.
42
+
43
+ ## Stack and architectural shape
44
+
45
+ > **What do we build on, what shape does the code take, and which implementation skill or
46
+ > approach does each slice pattern route to?**
47
+
48
+ - **Languages / runtimes:** {{e.g. Kotlin 2.x on JVM 21; TypeScript 5 on Node 24}}
49
+ - **Frameworks / platform:** {{web framework, persistence, messaging, build tool}}
50
+ - **Architectural pattern:** {{e.g. event-sourced CQRS with vertical slices; layered service over
51
+ a relational store; functional core / imperative shell}}
52
+ - **Where a slice's code lives:** {{one package per slice, per context, ...}}
53
+ - **Interface conventions:** {{resource style — REST/RPC/GraphQL, etc.; error/rejection mapping;
54
+ versioning; auth at the edge — the shape every `ui`-triggered command or `ui`-consumed view's
55
+ endpoint follows, decided once here rather than invented per slice}}
56
+
57
+ Routing — which implementation skill or approach each of the four slice patterns uses:
58
+
59
+ | Pattern | Skill / approach |
60
+ |---|---|
61
+ | State Change | {{e.g. the `axon-*` skill set — axon-entity-patterns, then axon-entity-testing}} |
62
+ | State View | {{e.g. the `axon-*` skill set — axon-projection-patterns, then axon-projection-testing}} |
63
+ | Automation | {{e.g. the `axon-*` skill set — axon-policy-patterns, then axon-policy-testing}} |
64
+ | Translation | {{e.g. the `axon-*` skill set — axon-translation-patterns}} |
65
+
66
+ An agent implementing a slice reads the doc's `pattern:` frontmatter and follows that row — this
67
+ table is the only routing rule.
68
+
69
+ ## Code style
70
+
71
+ > **What does "idiomatic" mean in this codebase — formatting, naming, module layout?**
72
+
73
+ - **Formatter / linter:** {{the tool and the command that runs it — never hand-format against it}}
74
+ - **Naming:** {{commands, events, handlers, files, test names}}
75
+ - **Module layout:** {{what lives in which file/package, and what may not import what}}
76
+ - **Idiomatic here means:** {{the two or three habits a new contributor most often gets wrong}}
77
+
78
+ ## Testing norms
79
+
80
+ > **What must be tested for each slice pattern, where do those tests live, and how are they named
81
+ > so `em coverage` can trace invariant IDs?**
82
+
83
+ - **Levels required per pattern:** {{e.g. State Change — decider unit tests plus a
84
+ given/when/then fixture test; State View — projection tests; Automation / Translation —
85
+ reaction tests, including a negative case}}
86
+ - **Invariant tests:** {{where they live}} — every `INV-<MNEMONIC>-n` in a slice doc needs at least
87
+ one test **citing that exact ID** in its name or a comment, so
88
+ `em coverage <model>.em --tests <dir>` can trace it.
89
+ - **Scenario tests:** {{where they live}} — one per `## Scenarios (Given / When / Then)` entry,
90
+ with rejection scenarios asserting the doc's named rejection reason.
91
+ - **Test naming convention:** {{the exact pattern, e.g. `INV-ORD-3: rejects a second submit`}}
92
+ - **What "green" means:** {{the command CI runs}}
93
+ - **Test command:** `{{the one command that runs the tests, e.g. ./gradlew test}}`
94
+ What the `em-validator` sub-agent runs. Keep exactly this shape: one line, the command in
95
+ backticks. Absent, the validator reports "no test command in the constitution" and runs only the
96
+ em checks.
97
+
98
+ ## NFR baselines
99
+
100
+ > **What standing non-functional defaults does every slice inherit — authz, PII, performance,
101
+ > observability?**
102
+
103
+ - **Authorization model:** {{who may issue which commands, how it's enforced, and where}}
104
+ - **PII / data handling:** {{what is sensitive, what may be logged, retention}}
105
+ - **Performance defaults:** {{latency / throughput budgets that apply unless a slice says otherwise}}
106
+ - **Observability:** {{logging, metrics, tracing every slice is expected to emit}}
107
+
108
+ A slice doc's own `## Non-Functional Requirements` section overrides these for that slice; where
109
+ it is silent, these apply.
110
+
111
+ ## Review and merge norms
112
+
113
+ > **Who reviews an implementation PR, what blocks a merge, and how does the slice doc's status
114
+ > flip fit in?**
115
+
116
+ - **Reviewers:** {{who — a team, a CODEOWNERS rule, the slice's ratifier}}
117
+ - **What blocks a merge:** {{e.g. a failing suite, an uncovered invariant, a gap that belongs back
118
+ at the model}}
119
+ - **Branch / commit conventions:** {{...}} — name only branch naming and commit-message style
120
+ here. **One slice doc = one PR is the implement contract's rule, not this document's to
121
+ amend** — a `covers:` doc ships as one PR for both keys; a read model is one doc, so a later
122
+ `again` instance is a continuation of the doc that first declared it, not a PR of its own. See
123
+ the agent guide's §5/§10.
124
+ - **Merge strategy:** merge-commits-when-stacked
125
+ {{**How do PRs merge, and what happens when one PR depends on another?** Merge commits whenever
126
+ a dependent PR is open; squash only a PR with no open dependent (implement contract §8 rule 2a).
127
+ Keep this exact line: it is the only value the engagement skill accepts, and it refuses to run
128
+ without it.}}
129
+ - **Agent models:** implementer=sonnet, validator=sonnet, reviewer=sonnet, critic=opus
130
+ {{**Which model runs each em sub-agent?** Keep this exact line shape, with the defaults shown or
131
+ your own choices. The critic must run on a different model from the implementer; `critic=codex`
132
+ selects the Codex critic. Absent, the engagement skill states these defaults once and
133
+ proceeds.}}
134
+ - **At merge:** run `em slice mark-implemented <model>.em <slice-key> <pr-url>` — the one edit an
135
+ implementing agent makes to a ratified slice doc, run by {{the PR author | CI}}. Never bump
136
+ `version:`; that moves only when a delta is ratified.
@@ -0,0 +1,46 @@
1
+ <!-- GENERATED FILE from .claude/skills/event-modeling-shared/templates/model-readme.md by scripts/build-plugin.ts — do not hand-edit; run npm run docs:generate -->
2
+ # {{Model Name}}
3
+
4
+ {{One-paragraph description of the business process(es) this event model covers.}}
5
+
6
+ ## Live view
7
+ While modeling, run the live view so the team can watch the diagram update:
8
+
9
+ ```bash
10
+ em watch {{model-name}}.em -o {{model-name}}.svg --serve # re-render + instant push-reload
11
+ # then open the URL it prints (http://localhost:5173/?svg={{model-name}}.svg) and share the screen
12
+ ```
13
+
14
+ Pan/zoom to navigate the diagram (drag, scroll; **Fit** resets), and click **Review mode** in
15
+ the header for a slice-by-slice walkthrough. If a save fails to render, the viewer keeps the
16
+ last good diagram and shows an error banner until the next successful load.
17
+
18
+ Static render: `em render {{model-name}}.em -o {{model-name}}.svg`
19
+
20
+ ## Patterns legend
21
+ - **State Change** — UI → Command → Event
22
+ - **State View** — Event(s) → Read Model → UI
23
+ - **Automation** — Read Model (slice before) → Processor + Command → Event, together
24
+ - **Translation** — External input (or Read Model, slice before) → Translation + Command → Event, together
25
+
26
+ Between them these are the only legal connections: `ui → command`, `command → event`,
27
+ `event → read model`, `read model → ui`, `read model → reaction`, `reaction → command`. A command
28
+ never reaches a read model directly — the event goes between them. Every slice is joined up at
29
+ both ends: something triggers each command (the screen it's issued from, or the reaction that
30
+ triggers it, also in this slice), and every event a command records is read by some read model — so each State
31
+ Change slice is paired with the State View slice that projects its event. A read model repeated
32
+ along the timeline (`view X again`) shows the same projection at a later point; the instances are
33
+ never connected to one another.
34
+
35
+ ## Slices
36
+ <!-- The canonical slice index — the ONE place slices are enumerated (the state file
37
+ points here rather than keeping its own copy). Generated — run
38
+ `em slice index {{model-name}}.em` to (re)write the table below from the model and its
39
+ slice docs; never hand-edit between the markers. -->
40
+ <!-- GENERATED:slices:start -->
41
+ | # | Slice | Pattern | Status | Reviewed by | Ratified by | Owner | Tracking | Implemented in | Design doc |
42
+ |---|-------|---------|--------|-------------|-------------|-------|----------|----------------|------------|
43
+ <!-- GENERATED:slices:end -->
44
+
45
+ ## Status
46
+ See [`.event-modeling.md`](.event-modeling.md) for current phase, decisions, and open questions.
@@ -0,0 +1,251 @@
1
+ <!-- GENERATED FILE from .claude/skills/event-modeling-shared/templates/slice.md by scripts/build-plugin.ts — do not hand-edit; run npm run docs:generate -->
2
+ <!--
3
+ Rich slice design document. One per slice, stored in <model>/slices/<slice-name>.md and
4
+ linked from the .em model with: note "slices/<slice-name>.md" on the slice's defining element.
5
+ Fill every section through Socratic questioning. Leave "Open Questions" rather than guessing.
6
+ Replace the bracketed placeholders; delete guidance comments before finishing.
7
+
8
+ The frontmatter below is the canonical, machine-read metadata dialect — `em`'s own parser
9
+ (src/catalog/sliceDoc.ts) reads `status:`, `version:`, `pattern:`, and the lineage keys
10
+ (`split-from:`/`merged-from:`/`superseded-by:`) from it. `pattern` is kebab-case
11
+ (state-change/state-view/automation/translation) even though the skill's prose always says
12
+ "State Change"/"State View"/etc. — the frontmatter value is a machine key, not a display label.
13
+ Older docs using a `- **Status:** ...` bullet line instead of frontmatter still parse (legacy/
14
+ accepted input), but new docs should always use this frontmatter form; `version` and lineage
15
+ have no legacy form — frontmatter-only from day one.
16
+
17
+ `version` is this slice's own ratified-content version — starts at `1`, bumps when a delta is
18
+ ratified — distinct from `schemaVersion`, which versions the frontmatter dialect itself, not
19
+ this slice. When a ratified change lands on an already-`implemented` slice: bump `version`,
20
+ flip `status` back to `ready-to-implement` (it tracks the CURRENT version's implementation
21
+ state — `implementedIn` legitimately keeps naming the PRIOR version's PR until the new version
22
+ ships; that mismatch is an intended drift signal, not a bug), and fill in the `## Delta` section
23
+ below with this hop's change, replacing whatever it held before (it always shows only the latest
24
+ hop — full history lives in git, same-commit-ratification convention). Full grammar — the fixed
25
+ heading, the four operation subsections, why the heading never varies, the replace-not-accumulate
26
+ lifecycle — is documented in ../reference/slice-doc-schema.md#delta-section-grammar-and-lifecycle; treat
27
+ it the same Socratic way as every other section here, don't generate it mechanically.
28
+
29
+ The three lineage keys only apply when this doc was produced by a split, merge, or rename —
30
+ delete them otherwise; most slices never carry them. Grammar: `<slice-key>@v<N>`, where
31
+ `<slice-key>` is the referenced slice's kebab-case filename stem.
32
+
33
+ `covers` only applies when this doc is also the ratified doc for a DIFFERENT slice — typically
34
+ the bare `view` half of the two-slice Automation/Translation shape, which has nothing of its own
35
+ to write up. Delete it otherwise; most docs never carry it. Requires a matching
36
+ `note "slices/{{this-slice-name}}.md"` on an element in the OTHER slice — this key alone doesn't
37
+ bind anything. Plain slice keys, comma-separated — not the `<slice-key>@v<N>` ref grammar above.
38
+
39
+ `ratifiedBy`/`ratifiedOn` record who ratified this doc's current `status`/`version`, and when —
40
+ don't hand-fill these; run `em slice ratify <model> <key> --by <name>` at the
41
+ handoff gate instead (docs/process.md#what-ratified-means), which flips `status` to
42
+ `ready-to-implement` and writes both in one edit.
43
+ public-touching slice: add --meaning-unchanged, or --contract-change "<why>"; run em api generate first.
44
+
45
+ `owner`/`tracking` are optional and, unlike `ratifiedBy`/`ratifiedOn`, hand-filled — no `em`
46
+ command writes either. `owner` is free text naming who (a person or team) holds this slice;
47
+ `tracking` is a URL into an external tracker (Jira, Linear, ...) mirroring it — the exact field
48
+ `em-tracker-bridge` reads to find the mirrored ticket. `em` only stores and displays both; it
49
+ never talks to a tracker itself. Delete both otherwise; most docs never carry them.
50
+
51
+ Full machine schema — required-vs-optional keys per `status`, value types/enums, the
52
+ unknown-key policy — is documented in ../reference/slice-doc-schema.md.
53
+
54
+ The diagram below is generated, not hand-drawn: `em render <model>.em --slice "{{Slice Name}}"
55
+ -o slices/{{slice-name}}.svg` (kebab-case the slice name to match this doc's own filename).
56
+ -->
57
+
58
+ ---
59
+ schemaVersion: 1
60
+ pattern: {{state-change | state-view | automation | translation}}
61
+ swimlane: {{Persona/Actor}} → {{Context/Aggregate}}
62
+ status: {{draft | reviewed | ready-to-implement | implemented}}
63
+ version: 1
64
+ implementedIn: {{PR/commit link — fill in once status is `implemented`}}
65
+ # Lineage — only when this doc exists because of a split, merge, or rename (delete these three
66
+ # lines otherwise). Grammar: <slice-key>@v<N>. See
67
+ # ../reference/slice-doc-schema.md#lineage-grammar-and-cardinality.
68
+ # split-from: <slice-key>@v<N>
69
+ # merged-from: <slice-key>@v<N>, <slice-key>@v<N>
70
+ # superseded-by: <slice-key>@v<N>, <slice-key>@v<N>
71
+ # Cross-slice coverage — only when this doc also covers another slice with no doc of its own
72
+ # (e.g. the view-only half of a two-slice Automation/Translation, MIL-121); delete otherwise.
73
+ # Plain slice keys, comma-separated. See ../reference/slice-doc-schema.md#cross-slice-coverage-covers.
74
+ # covers: <slice-key>, <slice-key>
75
+ # Ownership / tracking — optional, hand-filled (no `em` command writes either); delete otherwise.
76
+ # owner: <person or team>
77
+ # tracking: <ticket URL>
78
+ ---
79
+ # Slice: {{Slice Name}}
80
+
81
+ ![Diagram](./{{slice-name}}.svg)
82
+
83
+ <!-- Only on re-ratification of an already-`implemented` slice — omit this whole section on a
84
+ slice's first version (v1 has no delta yet). The heading is always the literal `## Delta`,
85
+ never `## Delta: vX → vY` — hop metadata is a display line inside the section instead (see
86
+ ../reference/slice-doc-schema.md#delta-section-grammar-and-lifecycle for why). Replace this
87
+ section's content wholesale on the next re-ratification — it shows only the latest hop, not
88
+ an accumulating log. Omit any of the four subsections below with no entries this hop; keep
89
+ the remaining ones in this order (Added/Modified/Removed/Renamed). `Renamed` is for a
90
+ requirement/invariant renamed within this slice, not a substitute for the frontmatter
91
+ `split-from`/`merged-from`/`superseded-by` lineage keys above, which record the slice-doc
92
+ itself splitting, merging, or being renamed. -->
93
+ ## Delta
94
+ **v{{X}} → v{{Y}}, ratified {{date}}** — {{one-line summary of the ratified change}}
95
+
96
+ ### Added
97
+ #### Requirement: {{title}} ({{stable ID, e.g. an INV-{{MNEMONIC}}-n from Invariants below}})
98
+ {{requirement text — same voice as an Invariants entry}}
99
+ ##### Scenario: {{name}}
100
+ - **Given:** {{...}}
101
+ - **When:** {{...}}
102
+ - **Then:** {{...}}
103
+
104
+ ### Modified
105
+ <!-- Same shape as Added — the stable ID names the requirement that changed. -->
106
+
107
+ ### Removed
108
+ #### Requirement: {{title}} ({{stable ID}})
109
+ {{why it was removed}}
110
+
111
+ ### Renamed
112
+ - {{old title}} ({{old ID}}) → {{new title}} ({{new ID}})
113
+
114
+ ## Intent
115
+ {{Why this slice exists — the user or business goal it serves, in one or two sentences. Note the
116
+ originating ticket/conversation link here if one exists.}}
117
+
118
+ ## Trigger & Actor
119
+ {{Who or what initiates this slice and under what circumstances. For automations, the watched
120
+ read model and the triggering condition. For translations, state the trigger form: externally
121
+ triggered (the external system/source feeding us) or internally triggered (the read model whose
122
+ state we react to). Either way, name the command this reaction triggers — reactions never record
123
+ an event directly.}}
124
+
125
+ ## Command / Input
126
+ <!-- GENERATED region (MIL-266): the table between the markers is written from the model —
127
+ `em slice new` fills it, `em slice sync <model>.em` refreshes it after any model edit. Never
128
+ hand-edit inside the markers: change the `.em` and re-run `em slice sync`. Required = `no`
129
+ for a field written `name?: Type`. A slice with several commands gets one region per command
130
+ (`em-slice-command-<command-slug>`); a pure State View slice's region says it has none. -->
131
+ <!-- GENERATED:em-slice-command:start — generated from the model by `em slice sync`; do not hand-edit -->
132
+ **Command:** `{{Command Name}}`
133
+
134
+ | Field | Type | Required | Rules / Validation |
135
+ |-------|------|----------|--------------------|
136
+ | {{field}} | {{Type}} | {{yes/no}} | {{constraints, formats, ranges}} |
137
+ <!-- GENERATED:em-slice-command:end -->
138
+
139
+ ## Trigger
140
+ <!-- What issues this slice's command. Required: a command nothing points at is a write nobody
141
+ can start. Either the screen the user acts on (a `ui` in this slice), or the reaction that
142
+ issues it (an automation/processor/translation, also in this slice). -->
143
+ **Triggered by:** {{screen `X` @Persona | processor `Y`, also in this slice}}
144
+
145
+ ## Event(s) Emitted
146
+ <!-- The immutable facts recorded. The marker line and payload table are a GENERATED region (one
147
+ per event; `em-slice-event-<event-slug>` when the slice records several): Source / Notes
148
+ names the command field a value is copied from, `assigned` for a system-assigned field, or
149
+ `{{ }}` where the model cannot tell. `**Read by:**` below the region is authored. -->
150
+ <!-- GENERATED:em-slice-event:start — generated from the model by `em slice sync`; do not hand-edit -->
151
+ **Event:** `{{Event Name}}` → context `{{Context}}`
152
+
153
+ | Field | Type | Immutable Fact? | Source / Notes |
154
+ |-------|------|-----------------|----------------|
155
+ | {{field}} | {{Type}} | {{yes/no}} | {{where the value comes from}} |
156
+ <!-- GENERATED:em-slice-event:end -->
157
+ **Read by:** {{which read model projects this event, and in which slice}}
158
+ <!-- Required, not optional. Every event must be read by a read model — an event nothing
159
+ projects is a write nobody can see, and `em validate` warns on it. A reaction consuming
160
+ it does NOT count: reactions read views, not events. If the honest answer is "nothing
161
+ reads it", that's a question for the business, not a field to leave blank. -->
162
+
163
+ ## Read Model / View
164
+ <!-- For State View slices, and any read model this slice produces or feeds. The `- **View:**`
165
+ line and field table are a GENERATED region (one per read model; `em-slice-view-<view-slug>`
166
+ when there are several): Source / Notes names the source event a field is copied from, or
167
+ `Derived` for a field marked `derived` in the `.em` (docs/dsl.md#derived-fields) — say how
168
+ it is derived in prose below the region. `{{ }}` marks a field the model cannot trace. -->
169
+ <!-- GENERATED:em-slice-view:start — generated from the model by `em slice sync`; do not hand-edit -->
170
+ - **View:** `{{View Name}}` built from events: {{"Event A", "Event B"}}
171
+
172
+ | Field | Type | Source / Notes |
173
+ |-------|------|----------------|
174
+ | {{field}} | {{Type}} | {{which event field it's copied from, or `Derived: <rule>`}} |
175
+ <!-- GENERATED:em-slice-view:end -->
176
+ - **Consumed by:** {{which UI screen (or API-caller persona), or reaction}}
177
+ <!-- "Consumed by" is required, not optional. A read model nothing displays or watches is
178
+ information projected out of the system and then dropped, and `em validate` warns. Every
179
+ instance of a repeated view needs its own consumer, not just the last one. -->
180
+ - **Freshness / consistency expectation:** {{real-time | eventual | on-demand}}
181
+
182
+ ## Invariants / Business Rules
183
+ <!-- IDs and rule sentences are declared in the MODEL (MIL-265): an `invariant INV-<MNEMONIC>-<n>
184
+ "rule"` line after the command or event it guards (docs/dsl.md#invariants). The list between
185
+ the markers is GENERATED from those lines (`em slice sync`); never edit it. Below it, cite
186
+ each ID as a plain mention and elaborate — `- INV-CHK-1 — why it holds, edge cases, the error
187
+ a violation returns` — never re-declare it with the `**INV-CHK-1:**` label
188
+ (`invariants/declared-in-both`). A rule not (yet) in the model may still be declared below
189
+ with that label; em reads it as the fallback. -->
190
+ <!-- What must ALWAYS hold. Give each a stable ID so tests and code can reference it:
191
+ `INV-<MNEMONIC>-<n>`, where `<MNEMONIC>` is a short (2-4 letter/digit), slice-unique
192
+ abbreviation of this slice's key (e.g. slice `checkout` -> `INV-CHK-1`) — see
193
+ ../reference/slice-doc-schema.md. Keep the rule statement itself to one line. If it needs
194
+ more — why the rule exists, what "violation" looks like in practice, an edge case worth
195
+ calling out — add that as a nested bullet under the elaboration line instead of one long
196
+ run-on sentence: this section renders as HTML (`em catalog`/`em render`/`em watch`), and a
197
+ nested bullet stays visually distinct where a wrapped sentence collapses into a wall of
198
+ text. The ID must stay on the top-level bullet line — `em coverage` extracts INV IDs from
199
+ that line only, never from a nested elaboration bullet underneath it. -->
200
+ <!-- GENERATED:em-slice-invariants:start — generated from the model by `em slice sync`; do not hand-edit -->
201
+ - **INV-{{MNEMONIC}}-1** — {{rule, as declared by `invariant INV-{{MNEMONIC}}-1 "rule"` in the model}}
202
+ <!-- GENERATED:em-slice-invariants:end -->
203
+ <!-- elaborate below this list; IDs are declared in the model -->
204
+ - INV-{{MNEMONIC}}-1 — {{elaboration of the model-declared rule: why it holds, what a violation looks like, the error returned}}
205
+ - {{optional: edge-case detail — its own bullet}}
206
+ - **INV-{{MNEMONIC}}-2:** {{a rule not yet in the model, declared here as the fallback — move it into the model when you can}}
207
+
208
+ ## Scenarios (Given / When / Then)
209
+ <!-- The executable specification — authored, in a constrained shape `em` reads back (`em export
210
+ --json` → slice.doc.scenarios). Cover the happy path AND the key rule boundaries, one block
211
+ per case: a `### Scenario: <title>` heading, then exactly the three column-0 bullets
212
+ `- **Given:**`, `- **When:**`, `- **Then:**`, each with its beats as nested ` - ` bullets.
213
+ A block missing any of the three is flagged `slice-doc/structured-section-malformed`. -->
214
+ ### Scenario: Happy path
215
+ - **Given:**
216
+ - {{starting state / prior events}}
217
+ - **When:**
218
+ - {{command/trigger}}
219
+ - **Then:**
220
+ - {{event(s) recorded}}
221
+ - {{resulting read-model change}}
222
+
223
+ ## Alternate & Error Flows
224
+ <!-- Failure paths, retries, compensations, timeouts, idempotency. -->
225
+ - {{e.g. external call fails → retry policy / compensating event}}
226
+ - {{idempotency: what happens if the command/event arrives twice?}}
227
+
228
+ ## Non-Functional Requirements
229
+ <!-- Short checklist. Idempotency is covered above under Alternate & Error Flows — not repeated
230
+ here. -->
231
+ - **Security / authz:** {{who may invoke this; role/permission checks — or "none"}}
232
+ - **PII & compliance:** {{personal data touched, retention/consent constraints — or "none"}}
233
+ - **Performance / SLA:** {{latency/throughput expectation — or "none"}}
234
+
235
+ ## Dependencies & Read Models Affected
236
+ - **Upstream events this slice relies on:** {{...}}
237
+ - **Downstream read models / slices affected:** {{...}}
238
+
239
+ ## Open Questions
240
+ <!-- Park unresolved items here instead of guessing. Mirror them into .event-modeling.md.
241
+
242
+ Lifecycle across versions: while THIS version is still being worked, a resolved item
243
+ (`- [x]`) can stay checked here as a visible record of what's already been decided this
244
+ round. On the same commit that ratifies the NEXT version (bumps `version`, rewrites
245
+ `## Delta` above) — prune every already-checked item from this list; keep only what's still
246
+ open, plus anything new the delta itself surfaced. Same "replace, never accumulate" stance
247
+ as `## Delta`, for the same reason: an ever-growing scroll of resolved questions goes stale
248
+ exactly like an accumulating Delta log would, and full history already lives in git
249
+ (`git log -p slices/<name>.md`) — this section is a live worklist, not an audit trail. See
250
+ ../reference/slice-doc-schema.md#open-questions-section-lifecycle. -->
251
+ - [ ] {{question}}
@@ -0,0 +1,77 @@
1
+ <!-- GENERATED FILE from .claude/skills/event-modeling-shared/templates/state.md by scripts/build-plugin.ts — do not hand-edit; run npm run docs:generate -->
2
+ <!--
3
+ Resumable progress state for an event model. Stored as <model>/.event-modeling.md
4
+ The skill reads this on `/em:event-modeling` (no arg) to resume where you left off.
5
+ Keep it current at the end of every working session.
6
+ -->
7
+
8
+ # Event Modeling Progress — {{Model Name}}
9
+
10
+ - **Model file:** `{{model-name}}.em`
11
+ - **Em version:** {{X.Y.Z}}
12
+ - **Current phase:** {{discover | extract | model | slice | implement | conform | review | validate}}
13
+ - **Current step:** {{1–7, see methodology; or extraction round R1–R7}}
14
+ - **Last updated:** {{YYYY-MM-DD}}
15
+ - **Last conformance:** {{YYYY-MM-DD @ <target-repo revision> — report: conformance/<date>-report.md | never}}
16
+ - **Model version:** {{N | none}}
17
+ - **Certified:** {{v<N> @ <target-repo revision> (YYYY-MM-DD) | never}}
18
+ - **Last stakeholder review:** {{YYYY-MM-DD — attendees: see Participants | never}}
19
+
20
+ ## Session inputs
21
+ - **Scope line:** {{one-line description of what's in/out of bounds for this model}}
22
+ - **PRD / spec reference:** {{path, link, or "none"}}
23
+ - **Headless/API model:** {{yes | no}}
24
+ - **Source mode:** {{greenfield | extract-event-driven | extract-procedural}}
25
+ - **Existing system refs:** {{repo paths, event-schema/topic locations, docs — or "n/a"}}
26
+
27
+ ## Participants
28
+ <!-- Populate at session start. Live workshop: one human proxy relays questions to the room;
29
+ attribute every answer/decision in the Decisions log to a named participant here. -->
30
+ - {{Name}} — {{role}} — {{domain area}}
31
+
32
+ ## Extraction progress (existing-system models only — delete for greenfield)
33
+ - [ ] R1. Candidate events (extracted/synthesized, filtered, confirmed)
34
+ - [ ] R2. Timeline order (as-is narrative, actors/callers, first render)
35
+ - [ ] R3. Commands / inputs
36
+ - [ ] R4. Read models / outputs (validate from here)
37
+ - [ ] R5. Boundaries & reactions (reaction shares its slice with the command it triggers)
38
+ - [ ] R6. Gap & TBD reconciliation
39
+ - [ ] R7. Convergence (render + validate clean, user confirmed as-is)
40
+
41
+ ## Steps completed
42
+ - [ ] 1. Brainstorm events
43
+ - [ ] 2. Plot / storyboard (personas + UI)
44
+ - [ ] 3. Inputs (commands)
45
+ - [ ] 4. Outputs (read models)
46
+ - [ ] 5. Swimlanes & apply patterns
47
+ - [ ] 6. Elaborate scenarios
48
+ - [ ] 7. Evaluate completeness (`em validate` clean)
49
+
50
+ ## Decisions log
51
+ <!-- Resolved choices, with the reasoning, so they aren't re-litigated. In a live workshop,
52
+ attribute each entry to the participant who made the call (see Participants above).
53
+ Every entry is a dated bullet ("- YYYY-MM-DD: ..."); em changelog skips any other line.
54
+ Seam change request (a needed change to another model's public element; never edit that
55
+ model, keep the open question blocked on its owners):
56
+ - YYYY-MM-DD: seam change request → <producerKey>:<kind>.<slug> — <what> — <why> -->
57
+ - {{YYYY-MM-DD}}: {{decision}} — {{why}} — by {{participant, if a live workshop}}
58
+
59
+ ## Usage log
60
+ <!-- The team's only usage signal today (see docs/usage-data.md) — cheap and coarse on purpose.
61
+ One line per session: phase(s) touched, and validate diagnostic *categories* hit (one of
62
+ the exact fixed strings in docs/usage-data.md#categories, e.g. "read model has no
63
+ consumer" — never the full instance message or any domain content). Append, never edit
64
+ past entries. -->
65
+ - {{YYYY-MM-DD}}: phases: {{discover | extract | model | slice | implement | conform | review | validate | watch, ...}} — validate: {{diagnostic category (docs/usage-data.md#categories), ... | none}}
66
+
67
+ ## Open questions / parking lot
68
+ <!-- Unresolved items to bring back to the user. Never guess these. Metadata is optional and
69
+ flat — add only what's known: source (ticket/conversation that spawned it), blocked on
70
+ (who/what), revisit (when). -->
71
+ - [ ] {{question}} — source: {{ticket/conversation link, optional}} — blocked on: {{who/what, optional}} — revisit: {{when, optional}}
72
+
73
+ ## Slice inventory
74
+ <!-- Deliberately NOT a table: the canonical slice index (slice, pattern, status, doc link)
75
+ lives in README.md's "Slices" section — one source of truth, updated there. This file
76
+ only tracks resumable session state. -->
77
+ See `README.md` → **Slices** for the slice index and per-slice doc status.