@milehimikey/em 1.10.0 → 1.11.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 (85) hide show
  1. package/.claude/skills/event-modeling/SKILL.md +1 -1
  2. package/.claude/skills/event-modeling-conform/SKILL.md +5 -1
  3. package/.claude/skills/event-modeling-design/SKILL.md +31 -12
  4. package/.claude/skills/event-modeling-discover/SKILL.md +1 -1
  5. package/.claude/skills/event-modeling-implement/SKILL.md +14 -3
  6. package/.claude/skills/event-modeling-implement/reference/implement.md +73 -6
  7. package/.claude/skills/event-modeling-review/SKILL.md +14 -3
  8. package/.claude/skills/event-modeling-shared/reference/em-dsl.md +64 -10
  9. package/.claude/skills/event-modeling-shared/reference/slice-doc-schema.md +4 -1
  10. package/.claude/skills/event-modeling-shared/templates/constitution.md +111 -0
  11. package/.claude/skills/event-modeling-shared/templates/model-readme.md +2 -2
  12. package/.claude/skills/event-modeling-shared/templates/slice.md +4 -0
  13. package/dist/catalog/docJoin.d.ts +8 -0
  14. package/dist/catalog/docJoin.js +4 -0
  15. package/dist/catalog/docJoin.js.map +1 -1
  16. package/dist/catalog/sliceDoc.d.ts +8 -0
  17. package/dist/catalog/sliceDoc.js +2 -0
  18. package/dist/catalog/sliceDoc.js.map +1 -1
  19. package/dist/cli/ledgerCheck.d.ts +72 -0
  20. package/dist/cli/ledgerCheck.js +122 -1
  21. package/dist/cli/ledgerCheck.js.map +1 -1
  22. package/dist/cli/ratify.d.ts +37 -5
  23. package/dist/cli/ratify.js +106 -9
  24. package/dist/cli/ratify.js.map +1 -1
  25. package/dist/cli/reratify.js +14 -5
  26. package/dist/cli/reratify.js.map +1 -1
  27. package/dist/cli/review.d.ts +38 -0
  28. package/dist/cli/review.js +160 -0
  29. package/dist/cli/review.js.map +1 -0
  30. package/dist/cli/sliceIndex.d.ts +3 -0
  31. package/dist/cli/sliceIndex.js +5 -4
  32. package/dist/cli/sliceIndex.js.map +1 -1
  33. package/dist/cli/stateFile.d.ts +10 -0
  34. package/dist/cli/stateFile.js +14 -0
  35. package/dist/cli/stateFile.js.map +1 -1
  36. package/dist/cli/status.d.ts +44 -3
  37. package/dist/cli/status.js +75 -18
  38. package/dist/cli/status.js.map +1 -1
  39. package/dist/cli.js +142 -18
  40. package/dist/cli.js.map +1 -1
  41. package/dist/emit/freshnessJson.d.ts +1 -1
  42. package/dist/emit/freshnessJson.js +5 -1
  43. package/dist/emit/freshnessJson.js.map +1 -1
  44. package/dist/emit/json.d.ts +22 -1
  45. package/dist/emit/json.js +33 -2
  46. package/dist/emit/json.js.map +1 -1
  47. package/dist/emit/ledgerJson.d.ts +1 -1
  48. package/dist/emit/ledgerJson.js +6 -1
  49. package/dist/emit/ledgerJson.js.map +1 -1
  50. package/dist/emit/queryJson.d.ts +1 -1
  51. package/dist/emit/queryJson.js +5 -1
  52. package/dist/emit/queryJson.js.map +1 -1
  53. package/dist/emit/statusJson.d.ts +1 -1
  54. package/dist/emit/statusJson.js +5 -1
  55. package/dist/emit/statusJson.js.map +1 -1
  56. package/dist/mcp/server.js +10 -3
  57. package/dist/mcp/server.js.map +1 -1
  58. package/dist/model/edges.d.ts +18 -3
  59. package/dist/model/edges.js +34 -0
  60. package/dist/model/edges.js.map +1 -1
  61. package/dist/model/model.d.ts +4 -0
  62. package/dist/model/model.js +1 -0
  63. package/dist/model/model.js.map +1 -1
  64. package/dist/model/queryIndex.d.ts +5 -2
  65. package/dist/model/queryIndex.js +4 -1
  66. package/dist/model/queryIndex.js.map +1 -1
  67. package/dist/model/rules.d.ts +19 -0
  68. package/dist/model/rules.js +19 -0
  69. package/dist/model/rules.js.map +1 -1
  70. package/dist/model/validate.js +82 -1
  71. package/dist/model/validate.js.map +1 -1
  72. package/dist/parser/ast.d.ts +21 -0
  73. package/dist/parser/parser.js +96 -32
  74. package/dist/parser/parser.js.map +1 -1
  75. package/dist/render/drawEdges.js +7 -0
  76. package/dist/render/drawEdges.js.map +1 -1
  77. package/dist/render/drawNotes.d.ts +13 -3
  78. package/dist/render/drawNotes.js +96 -20
  79. package/dist/render/drawNotes.js.map +1 -1
  80. package/dist/render/render.js +6 -5
  81. package/dist/render/render.js.map +1 -1
  82. package/dist/templates.d.ts +14 -1
  83. package/dist/templates.js +134 -5
  84. package/dist/templates.js.map +1 -1
  85. package/package.json +1 -1
package/dist/templates.js CHANGED
@@ -56,9 +56,9 @@ slice "Show Receipt" {
56
56
  // mirroring STARTER_EM above — the compiled CLI never reads .claude/skills/ at runtime to
57
57
  // produce these, so `em scaffold` behaves identically whether em is run from a checkout or
58
58
  // installed from npm. test/scaffoldTemplatesSync.test.ts asserts each constant below stays
59
- // byte-identical to its source file in .claude/skills/event-modeling/templates/, so the two
60
- // copies can't silently drift — regenerate by hand (or re-run the one-off script noted there)
61
- // whenever a template file changes.
59
+ // byte-identical to its source file in .claude/skills/event-modeling-shared/templates/, so the
60
+ // two copies can't silently drift — regenerate by hand (or re-run the one-off script noted
61
+ // there) whenever a template file changes.
62
62
  /** Raw copy of templates/model-readme.md, \`{{...}}\` placeholders intact — see scaffoldReadme(). */
63
63
  export const MODEL_README_TEMPLATE = `# {{Model Name}}
64
64
 
@@ -99,8 +99,8 @@ never connected to one another.
99
99
  \`em slice index {{model-name}}.em\` to (re)write the table below from the model and its
100
100
  slice docs; never hand-edit between the markers. -->
101
101
  <!-- GENERATED:slices:start -->
102
- | # | Slice | Pattern | Status | Ratified by | Owner | Tracking | Implemented in | Design doc |
103
- |---|-------|---------|--------|-------------|-------|----------|----------------|------------|
102
+ | # | Slice | Pattern | Status | Reviewed by | Ratified by | Owner | Tracking | Implemented in | Design doc |
103
+ |---|-------|---------|--------|-------------|-------------|-------|----------|----------------|------------|
104
104
  <!-- GENERATED:slices:end -->
105
105
 
106
106
  ## Status
@@ -177,6 +177,120 @@ Keep it current at the end of every working session.
177
177
  only tracks resumable session state. -->
178
178
  See \`README.md\` → **Slices** for the slice index and per-slice doc status.
179
179
  `;
180
+ /** Raw copy of templates/constitution.md, \`{{...}}\` placeholders intact — see
181
+ * scaffoldConstitution(). */
182
+ export const CONSTITUTION_TEMPLATE = `<!--
183
+ The implementation constitution: the house rules an implementing agent follows on EVERY slice —
184
+ stack, code style, testing norms, NFR baselines, review norms. It answers "how do we build things
185
+ here" once, so no slice doc has to repeat it and no agent has to invent it. Slice docs say WHAT to
186
+ build; this says HOW it gets built here.
187
+
188
+ Where this document lives:
189
+ - No SDD tool: \`constitution.md\` beside the model — \`em scaffold\` writes it there.
190
+ - spec-kit project (a \`.specify/\` directory exists anywhere above the model): the document IS
191
+ \`.specify/memory/constitution.md\`. em writes no second copy; the sections below merge into
192
+ that file under these same headings, never overwriting text already there, and ratification is
193
+ recorded in spec-kit's own \`**Ratified**:\` footer line instead of the frontmatter below.
194
+
195
+ How it gets filled: not by an agent guessing. Each section opens with the question a short
196
+ facilitated conversation asks before the first slice is implemented — the procedure is "Before the
197
+ first slice: the constitution" in the \`event-modeling-implement\` skill's \`reference/implement.md\`
198
+ (\`em contract\` prints it). Replace each \`{{...}}\` block with the real answers; delete the guidance
199
+ comments and any row that doesn't apply.
200
+
201
+ Ratification: \`ratifiedBy:\`/\`ratifiedOn:\` are the same identity discipline slice docs use — a
202
+ NAMED human and an ISO date, hand-filled at sign-off (no \`em\` command writes this file).
203
+ **A constitution with an empty \`ratifiedBy:\` is a draft**: an implementing agent treats it as
204
+ unratified, says so, and does not proceed on unilateral style or stack decisions for a first slice.
205
+
206
+ \`em status\` reports this document as present or absent per model — existence only. em never reads
207
+ or validates its content, and nothing here is machine-parsed.
208
+ -->
209
+
210
+ ---
211
+ schemaVersion: 1
212
+ ratifiedBy:
213
+ ratifiedOn:
214
+ ---
215
+ # {{Project Name}} — implementation constitution
216
+
217
+ The house rules for how implementation happens in this project. They bound every "purely
218
+ technical choice" an implementing agent would otherwise make alone.
219
+
220
+ ## Stack and architectural shape
221
+
222
+ > **What do we build on, what shape does the code take, and which implementation skill or
223
+ > approach does each slice pattern route to?**
224
+
225
+ - **Languages / runtimes:** {{e.g. Kotlin 2.x on JVM 21; TypeScript 5 on Node 24}}
226
+ - **Frameworks / platform:** {{web framework, persistence, messaging, build tool}}
227
+ - **Architectural pattern:** {{e.g. event-sourced CQRS with vertical slices; layered service over
228
+ a relational store; functional core / imperative shell}}
229
+ - **Where a slice's code lives:** {{one package per slice, per context, ...}}
230
+
231
+ Routing — which implementation skill or approach each of the four slice patterns uses:
232
+
233
+ | Pattern | Skill / approach |
234
+ |---|---|
235
+ | State Change | {{e.g. the \`axon-*\` skill set — axon-entity-patterns, then axon-entity-testing}} |
236
+ | State View | {{e.g. the \`axon-*\` skill set — axon-projection-patterns, then axon-projection-testing}} |
237
+ | Automation | {{e.g. the \`axon-*\` skill set — axon-policy-patterns, then axon-policy-testing}} |
238
+ | Translation | {{e.g. the \`axon-*\` skill set — axon-translation-patterns}} |
239
+
240
+ An agent implementing a slice reads the doc's \`pattern:\` frontmatter and follows that row — this
241
+ table is the only routing rule.
242
+
243
+ ## Code style
244
+
245
+ > **What does "idiomatic" mean in this codebase — formatting, naming, module layout?**
246
+
247
+ - **Formatter / linter:** {{the tool and the command that runs it — never hand-format against it}}
248
+ - **Naming:** {{commands, events, handlers, files, test names}}
249
+ - **Module layout:** {{what lives in which file/package, and what may not import what}}
250
+ - **Idiomatic here means:** {{the two or three habits a new contributor most often gets wrong}}
251
+
252
+ ## Testing norms
253
+
254
+ > **What must be tested for each slice pattern, where do those tests live, and how are they named
255
+ > so \`em coverage\` can trace invariant IDs?**
256
+
257
+ - **Levels required per pattern:** {{e.g. State Change — decider unit tests plus a
258
+ given/when/then fixture test; State View — projection tests; Automation / Translation —
259
+ reaction tests, including a negative case}}
260
+ - **Invariant tests:** {{where they live}} — every \`INV-<MNEMONIC>-n\` in a slice doc needs at least
261
+ one test **citing that exact ID** in its name or a comment, so
262
+ \`em coverage <model>.em --tests <dir>\` can trace it.
263
+ - **Scenario tests:** {{where they live}} — one per \`## Scenarios (Given / When / Then)\` entry,
264
+ with rejection scenarios asserting the doc's named rejection reason.
265
+ - **Test naming convention:** {{the exact pattern, e.g. \`INV-ORD-3: rejects a second submit\`}}
266
+ - **What "green" means:** {{the command CI runs}}
267
+
268
+ ## NFR baselines
269
+
270
+ > **What standing non-functional defaults does every slice inherit — authz, PII, performance,
271
+ > observability?**
272
+
273
+ - **Authorization model:** {{who may issue which commands, how it's enforced, and where}}
274
+ - **PII / data handling:** {{what is sensitive, what may be logged, retention}}
275
+ - **Performance defaults:** {{latency / throughput budgets that apply unless a slice says otherwise}}
276
+ - **Observability:** {{logging, metrics, tracing every slice is expected to emit}}
277
+
278
+ A slice doc's own \`## Non-Functional Requirements\` section overrides these for that slice; where
279
+ it is silent, these apply.
280
+
281
+ ## Review and merge norms
282
+
283
+ > **Who reviews an implementation PR, what blocks a merge, and how does the slice doc's status
284
+ > flip fit in?**
285
+
286
+ - **Reviewers:** {{who — a team, a CODEOWNERS rule, the slice's ratifier}}
287
+ - **What blocks a merge:** {{e.g. a failing suite, an uncovered invariant, a gap that belongs back
288
+ at the model}}
289
+ - **Branch / commit conventions:** {{...}}
290
+ - **At merge:** run \`em slice mark-implemented <model>.em <slice-key> <pr-url>\` — the one edit an
291
+ implementing agent makes to a ratified slice doc, run by {{the PR author | CI}}. Never bump
292
+ \`version:\`; that moves only when a delta is ratified.
293
+ `;
180
294
  /** Same STARTER_EM content `em init` writes, titled from an arbitrary display name — used by
181
295
  * `em scaffold`, which (unlike `em init`) knows a name to title the model with. */
182
296
  export function starterEmFor(title) {
@@ -219,4 +333,19 @@ export function scaffoldStateFile(displayName, slugName, today) {
219
333
  .filter((line) => !line.includes("{{"))
220
334
  .join("\n");
221
335
  }
336
+ /** Fill CONSTITUTION_TEMPLATE's project-name placeholder for `em scaffold` (MIL-202).
337
+ *
338
+ * Unlike `scaffoldReadme`/`scaffoldStateFile`, this one **deliberately leaves every other
339
+ * \`{{...}}\` block intact**: they are the unanswered questions of the elicitation conversation
340
+ * the implement skill runs before the first slice ("Before the first slice: the constitution"),
341
+ * not mechanical fields em could fill. An unanswered constitution must read as unanswered — the
342
+ * placeholders are the todo list, and the empty `ratifiedBy:` frontmatter says it's still a
343
+ * draft. Nothing in `em` ever parses this file's body; only its existence is reported
344
+ * (`em status`'s `constitution` field). */
345
+ export function scaffoldConstitution(displayName) {
346
+ // Replacer function, not a string pattern — a string replacement would let `$&`/`$$`/etc. in
347
+ // displayName expand against the match instead of being inserted literally (the CLI layer
348
+ // separately rejects `{{` in the name).
349
+ return CONSTITUTION_TEMPLATE.replace("{{Project Name}}", () => displayName);
350
+ }
222
351
  //# sourceMappingURL=templates.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"templates.js","sourceRoot":"","sources":["../src/templates.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,mCAAmC;AAEnC,MAAM,CAAC,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiDzB,CAAC;AAEF,wDAAwD;AACxD,EAAE;AACF,2FAA2F;AAC3F,0FAA0F;AAC1F,2FAA2F;AAC3F,2FAA2F;AAC3F,4FAA4F;AAC5F,8FAA8F;AAC9F,oCAAoC;AAEpC,qGAAqG;AACrG,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6CpC,CAAC;AAEF,iGAAiG;AACjG,MAAM,CAAC,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqE7B,CAAC;AAEF;oFACoF;AACpF,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,0FAA0F;IAC1F,yFAAyF;IACzF,6FAA6F;IAC7F,OAAO,UAAU,CAAC,OAAO,CAAC,2BAA2B,EAAE,GAAG,EAAE,CAAC,UAAU,KAAK,GAAG,CAAC,CAAC;AACnF,CAAC;AAED;;;;4DAI4D;AAC5D,MAAM,UAAU,cAAc,CAAC,WAAmB,EAAE,QAAgB;IAClE,6FAA6F;IAC7F,4EAA4E;IAC5E,OAAO,qBAAqB,CAAC,OAAO,CAAC,qBAAqB,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC;SAC3E,OAAO,CAAC,qBAAqB,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC;SAC9C,OAAO,CACN,oFAAoF,EACpF,yFAAyF,CAC1F,CAAC;AACN,CAAC;AAED;;;;8FAI8F;AAC9F,MAAM,UAAU,iBAAiB,CAAC,WAAmB,EAAE,QAAgB,EAAE,KAAa;IACpF,qFAAqF;IACrF,wFAAwF;IACxF,4BAA4B;IAC5B,MAAM,MAAM,GAAG,cAAc,CAAC,OAAO,CAAC,gBAAgB,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC;SACvE,OAAO,CAAC,gBAAgB,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC;SACzC,OAAO,CAAC,kFAAkF,EAAE,UAAU,CAAC;SACvG,OAAO,CAAC,+DAA+D,EAAE,GAAG,CAAC;SAC7E,OAAO,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC,8DAA8D;QAChG,oEAAoE;SACnE,OAAO,CAAC,6FAA6F,EAAE,OAAO,CAAC;SAC/G,OAAO,CAAC,2DAA2D,EAAE,OAAO,CAAC,CAAC;IAEjF,OAAO,MAAM;SACV,KAAK,CAAC,IAAI,CAAC;SACX,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;SACtC,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"templates.js","sourceRoot":"","sources":["../src/templates.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,mCAAmC;AAEnC,MAAM,CAAC,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiDzB,CAAC;AAEF,wDAAwD;AACxD,EAAE;AACF,2FAA2F;AAC3F,0FAA0F;AAC1F,2FAA2F;AAC3F,2FAA2F;AAC3F,+FAA+F;AAC/F,2FAA2F;AAC3F,2CAA2C;AAE3C,qGAAqG;AACrG,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6CpC,CAAC;AAEF,iGAAiG;AACjG,MAAM,CAAC,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqE7B,CAAC;AAEF;8BAC8B;AAC9B,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+GpC,CAAC;AAEF;oFACoF;AACpF,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,0FAA0F;IAC1F,yFAAyF;IACzF,6FAA6F;IAC7F,OAAO,UAAU,CAAC,OAAO,CAAC,2BAA2B,EAAE,GAAG,EAAE,CAAC,UAAU,KAAK,GAAG,CAAC,CAAC;AACnF,CAAC;AAED;;;;4DAI4D;AAC5D,MAAM,UAAU,cAAc,CAAC,WAAmB,EAAE,QAAgB;IAClE,6FAA6F;IAC7F,4EAA4E;IAC5E,OAAO,qBAAqB,CAAC,OAAO,CAAC,qBAAqB,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC;SAC3E,OAAO,CAAC,qBAAqB,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC;SAC9C,OAAO,CACN,oFAAoF,EACpF,yFAAyF,CAC1F,CAAC;AACN,CAAC;AAED;;;;8FAI8F;AAC9F,MAAM,UAAU,iBAAiB,CAAC,WAAmB,EAAE,QAAgB,EAAE,KAAa;IACpF,qFAAqF;IACrF,wFAAwF;IACxF,4BAA4B;IAC5B,MAAM,MAAM,GAAG,cAAc,CAAC,OAAO,CAAC,gBAAgB,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC;SACvE,OAAO,CAAC,gBAAgB,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC;SACzC,OAAO,CAAC,kFAAkF,EAAE,UAAU,CAAC;SACvG,OAAO,CAAC,+DAA+D,EAAE,GAAG,CAAC;SAC7E,OAAO,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC,8DAA8D;QAChG,oEAAoE;SACnE,OAAO,CAAC,6FAA6F,EAAE,OAAO,CAAC;SAC/G,OAAO,CAAC,2DAA2D,EAAE,OAAO,CAAC,CAAC;IAEjF,OAAO,MAAM;SACV,KAAK,CAAC,IAAI,CAAC;SACX,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;SACtC,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED;;;;;;;;4CAQ4C;AAC5C,MAAM,UAAU,oBAAoB,CAAC,WAAmB;IACtD,6FAA6F;IAC7F,0FAA0F;IAC1F,wCAAwC;IACxC,OAAO,qBAAqB,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,CAAC;AAC9E,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@milehimikey/em",
3
- "version": "1.10.0",
3
+ "version": "1.11.0",
4
4
  "description": "AI-friendly Event Modeling — a slice-first text DSL rendered to a strict, self-contained Graphviz grid (SVG/PNG)",
5
5
  "type": "module",
6
6
  "bin": {