@milehimikey/em 1.7.2 → 1.8.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.
- package/.claude/skills/event-modeling/SKILL.md +92 -65
- package/.claude/skills/event-modeling/reference/conform.md +45 -20
- package/.claude/skills/event-modeling/reference/em-dsl.md +120 -55
- package/.claude/skills/event-modeling/reference/extract.md +5 -4
- package/.claude/skills/event-modeling/reference/implement.md +34 -22
- package/.claude/skills/event-modeling/templates/model-readme.md +8 -5
- package/.claude/skills/event-modeling/templates/slice.md +19 -5
- package/README.md +6 -4
- package/dist/catalog/docJoin.d.ts +28 -3
- package/dist/catalog/docJoin.js +82 -13
- package/dist/catalog/docJoin.js.map +1 -1
- package/dist/catalog/docModelConsistencyValidate.d.ts +8 -0
- package/dist/catalog/docModelConsistencyValidate.js +335 -0
- package/dist/catalog/docModelConsistencyValidate.js.map +1 -0
- package/dist/catalog/noteBindingValidate.d.ts +8 -0
- package/dist/catalog/noteBindingValidate.js +133 -0
- package/dist/catalog/noteBindingValidate.js.map +1 -0
- package/dist/catalog/pages.js +3 -3
- package/dist/catalog/pages.js.map +1 -1
- package/dist/catalog/sliceDoc.d.ts +14 -0
- package/dist/catalog/sliceDoc.js +22 -0
- package/dist/catalog/sliceDoc.js.map +1 -1
- package/dist/catalog/sliceReadyValidate.d.ts +18 -0
- package/dist/catalog/sliceReadyValidate.js +25 -1
- package/dist/catalog/sliceReadyValidate.js.map +1 -1
- package/dist/cli/agentsMd.d.ts +15 -0
- package/dist/cli/agentsMd.js +72 -0
- package/dist/cli/agentsMd.js.map +1 -0
- package/dist/cli/conformScope.d.ts +86 -0
- package/dist/cli/conformScope.js +156 -0
- package/dist/cli/conformScope.js.map +1 -0
- package/dist/cli/contract.d.ts +7 -0
- package/dist/cli/contract.js +27 -0
- package/dist/cli/contract.js.map +1 -0
- package/dist/cli/coverage.d.ts +69 -0
- package/dist/cli/coverage.js +157 -0
- package/dist/cli/coverage.js.map +1 -0
- package/dist/cli/markImplemented.d.ts +34 -0
- package/dist/cli/markImplemented.js +180 -0
- package/dist/cli/markImplemented.js.map +1 -0
- package/dist/cli/migrateReactionShape.d.ts +62 -0
- package/dist/cli/migrateReactionShape.js +283 -0
- package/dist/cli/migrateReactionShape.js.map +1 -0
- package/dist/cli/sliceIndex.d.ts +49 -0
- package/dist/cli/sliceIndex.js +115 -0
- package/dist/cli/sliceIndex.js.map +1 -0
- package/dist/cli/sliceNew.d.ts +18 -0
- package/dist/cli/sliceNew.js +53 -0
- package/dist/cli/sliceNew.js.map +1 -0
- package/dist/cli/stateFile.d.ts +74 -0
- package/dist/cli/stateFile.js +191 -0
- package/dist/cli/stateFile.js.map +1 -0
- package/dist/cli.js +535 -43
- package/dist/cli.js.map +1 -1
- package/dist/emit/coverageJson.d.ts +8 -0
- package/dist/emit/coverageJson.js +30 -0
- package/dist/emit/coverageJson.js.map +1 -0
- package/dist/emit/dot.js +41 -10
- package/dist/emit/dot.js.map +1 -1
- package/dist/emit/json.d.ts +72 -4
- package/dist/emit/json.js +73 -4
- package/dist/emit/json.js.map +1 -1
- package/dist/emit/validateJson.d.ts +52 -0
- package/dist/emit/validateJson.js +120 -0
- package/dist/emit/validateJson.js.map +1 -0
- package/dist/mcp/main.d.ts +2 -0
- package/dist/mcp/main.js +20 -0
- package/dist/mcp/main.js.map +1 -0
- package/dist/mcp/server.d.ts +11 -0
- package/dist/mcp/server.js +260 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/model/model.d.ts +30 -1
- package/dist/model/model.js +26 -0
- package/dist/model/model.js.map +1 -1
- package/dist/model/rules.d.ts +114 -0
- package/dist/model/rules.js +116 -4
- package/dist/model/rules.js.map +1 -1
- package/dist/model/validate.js +83 -7
- package/dist/model/validate.js.map +1 -1
- package/dist/parser/ast.d.ts +41 -0
- package/dist/parser/lexer.d.ts +16 -0
- package/dist/parser/lexer.js +44 -2
- package/dist/parser/lexer.js.map +1 -1
- package/dist/parser/parser.js +340 -20
- package/dist/parser/parser.js.map +1 -1
- package/dist/render/drawNotes.js +8 -1
- package/dist/render/drawNotes.js.map +1 -1
- package/dist/render/render.js +85 -17
- package/dist/render/render.js.map +1 -1
- package/dist/render/serve.d.ts +4 -0
- package/dist/render/serve.js +23 -239
- package/dist/render/serve.js.map +1 -1
- package/dist/render/sliceStatus.d.ts +1 -1
- package/dist/render/sliceStatus.js +35 -6
- package/dist/render/sliceStatus.js.map +1 -1
- package/dist/render/viewerHtml.d.ts +1 -0
- package/dist/render/viewerHtml.js +5 -0
- package/dist/render/viewerHtml.js.map +1 -0
- package/dist/render/watch.d.ts +10 -0
- package/dist/render/watch.js +29 -0
- package/dist/render/watch.js.map +1 -1
- package/dist/templates.d.ts +19 -0
- package/dist/templates.js +169 -0
- package/dist/templates.js.map +1 -1
- package/dist/util/markers.d.ts +13 -0
- package/dist/util/markers.js +30 -0
- package/dist/util/markers.js.map +1 -0
- package/dist/util/walkDir.d.ts +10 -1
- package/dist/util/walkDir.js +11 -7
- package/dist/util/walkDir.js.map +1 -1
- package/package.json +12 -3
- package/.claude/skills/event-modeling/templates/live.html +0 -117
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: event-modeling
|
|
3
|
-
em-version: 1.
|
|
3
|
+
em-version: 1.8.0
|
|
4
4
|
description: >-
|
|
5
5
|
Use when the user wants to event-model a business process or system: building, editing,
|
|
6
6
|
updating, or maintaining a model — extending or detailing an existing one into slices,
|
|
@@ -77,21 +77,23 @@ vendored alongside this skill.
|
|
|
77
77
|
is missing an **element**, not an arrow.
|
|
78
78
|
- **Validate continuously.** Run `em validate` and fix errors/warnings as you go (see DSL ref).
|
|
79
79
|
- **Save state at the end of every session** so work resumes cleanly. Also append one line to
|
|
80
|
-
the Usage log: the phase(s) touched and the
|
|
81
|
-
|
|
82
|
-
never the full message or domain content). This is the team's only usage signal today
|
|
83
|
-
and habitual, not a task to skip.
|
|
80
|
+
the Usage log: the phase(s) touched and the diagnostic *categories* that fired — run `em
|
|
81
|
+
validate <model>.em --json` and dedupe each diagnostic's `usageCategory` field directly
|
|
82
|
+
(never the full message or domain content). This is the team's only usage signal today
|
|
83
|
+
(`docs/usage-data.md`) — keep it cheap and habitual, not a task to skip.
|
|
84
84
|
|
|
85
85
|
## Preconditions (run first)
|
|
86
86
|
|
|
87
87
|
1. Check the tool: `em --version`. If missing, tell the user to run `npm i -g @milehimikey/em`
|
|
88
88
|
and stop until installed.
|
|
89
89
|
2. Locate the model. Look for an existing `<dir>/.event-modeling.md` and `*.em` in the working
|
|
90
|
-
directory (or a `models/` subfolder). If found,
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
90
|
+
directory (or a `models/` subfolder). If found, run `em state read <dir>` to read the state
|
|
91
|
+
file's mechanical fields (model path, phase, step, last updated, last conformance, last
|
|
92
|
+
review) as JSON — don't parse the bullets by hand. If not, and the phase needs one, ask the
|
|
93
|
+
user for the model name and where to create it.
|
|
94
|
+
3. Parse the argument (`$ARGUMENTS`) to pick the phase below. With **no argument**, use
|
|
95
|
+
`em state read <dir>`'s `phase`/`step` to resume the recorded phase/step; if no model exists,
|
|
96
|
+
propose starting `discover` (greenfield) or `extract` (modeling an existing system).
|
|
95
97
|
4. Populate the state file's Participants section at session start. For a live workshop, ask for
|
|
96
98
|
a single human proxy to relay questions to the room, and attribute every answer/decision in
|
|
97
99
|
the Decisions log to a named participant.
|
|
@@ -102,7 +104,6 @@ vendored alongside this skill.
|
|
|
102
104
|
<model-name>/
|
|
103
105
|
<model-name>.em # the model (slice docs linked via note "...")
|
|
104
106
|
<model-name>.svg # render target for em watch
|
|
105
|
-
live.html # file:// auto-refresh viewer (copy of templates/live.html, verbatim)
|
|
106
107
|
README.md # overview + slice index (from templates/model-readme.md)
|
|
107
108
|
.event-modeling.md # resumable state (from templates/state.md)
|
|
108
109
|
slices/<slice-name>.md # one rich slice doc per slice (from templates/slice.md)
|
|
@@ -111,14 +112,19 @@ vendored alongside this skill.
|
|
|
111
112
|
<model-name>-asis.em # conform-phase scratch model, regenerated per run — git-ignore this
|
|
112
113
|
```
|
|
113
114
|
|
|
114
|
-
When creating a new model,
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
it
|
|
115
|
+
When creating a new model, run `em scaffold <model-name>` — it creates `<model-name>/` and
|
|
116
|
+
writes all three starter files in one step (`<model-name>.em`, `README.md`,
|
|
117
|
+
`.event-modeling.md`), filling the Model Name/model-name placeholders and the state file's
|
|
118
|
+
mechanical fields (model path, `Current phase: discover`, `Current step: 1`, dates) for you, so
|
|
119
|
+
there's nothing left to hand-copy or fill in. Refuses if `<model-name>/` already exists; pass
|
|
120
|
+
`--force` to overwrite. You'll
|
|
121
|
+
usually replace the scaffolded `.em`'s content as the discovery conversation builds up the real
|
|
122
|
+
model — it starts out as the same starter model `em init` writes, titled from `<model-name>`.
|
|
123
|
+
`slices/*.md` and `conformance/` aren't part of `em scaffold`; they come from the `slice` and
|
|
124
|
+
`conform` phases below. The `conformance/` directory
|
|
125
|
+
and `<model-name>-asis.em` only appear once the `conform` phase runs; `em conform-scope
|
|
126
|
+
--seed-asis` creates `<model-name>-asis.em` and gitignores `*-asis.em` for you (see
|
|
127
|
+
`reference/conform.md`) — it's scratch, never committed.
|
|
122
128
|
|
|
123
129
|
---
|
|
124
130
|
|
|
@@ -160,8 +166,10 @@ phase applies to field tables, below.
|
|
|
160
166
|
both are worth raising with the user rather than leaving dangling.
|
|
161
167
|
|
|
162
168
|
End of phase: write/refresh the `.em`, render it, update `.event-modeling.md` (steps done,
|
|
163
|
-
decisions, open questions
|
|
164
|
-
|
|
169
|
+
decisions, open questions — run `em state set-phase model` rather than hand-editing `Current
|
|
170
|
+
phase:`), and run `em slice index <model-name>.em` to seed `README.md`'s Slices table (every
|
|
171
|
+
slice already reads "no doc yet" — no slice docs exist until the `slice` phase writes them).
|
|
172
|
+
Tell the user they can stop here and resume with `/event-modeling model`.
|
|
165
173
|
|
|
166
174
|
## Phase: `extract` — current-state model of an existing system
|
|
167
175
|
|
|
@@ -181,8 +189,9 @@ state).
|
|
|
181
189
|
- **Current-state-only:** park unknowns as `# TBD` comments in the `.em`, mirrored in the state
|
|
182
190
|
file's Open Questions — never guess intended design.
|
|
183
191
|
|
|
184
|
-
End of phase: validated as-is model; state file updated (source mode, rounds, decisions
|
|
185
|
-
`
|
|
192
|
+
End of phase: validated as-is model; state file updated (source mode, rounds, decisions; `em
|
|
193
|
+
state set-phase model` for `Current phase:`); run `em slice index <model-name>.em` to seed
|
|
194
|
+
`README.md`'s Slices table; then chain to `/event-modeling model` (steps 5-7).
|
|
186
195
|
|
|
187
196
|
## Phase: `model` — steps 5-7
|
|
188
197
|
|
|
@@ -211,12 +220,14 @@ Goal: a structurally complete, **validated** model with correct patterns and swi
|
|
|
211
220
|
this fact and what they do with it. The honest answers are "here's the read model we missed" or
|
|
212
221
|
"nobody — so why are we recording it", and both improve the model.
|
|
213
222
|
|
|
214
|
-
End of phase: render, update state, suggest `/event-modeling slice`
|
|
223
|
+
End of phase: render, update state (`em state set-phase slice`), suggest `/event-modeling slice`
|
|
224
|
+
to write implementation specs.
|
|
215
225
|
|
|
216
226
|
## Phase: `slice` — deep slice documents
|
|
217
227
|
|
|
218
228
|
Goal: implementation-ready specs. Go slice by slice (let the user pick order, or follow the
|
|
219
|
-
timeline). Check `README.md`'s
|
|
229
|
+
timeline). Check `README.md`'s Slices table for what's already done (run `em slice index
|
|
230
|
+
<model-name>.em` first if it looks stale).
|
|
220
231
|
|
|
221
232
|
This is also where **branch / unhappy-path events** are discovered and added to the model — as a
|
|
222
233
|
slice's alternate/error flows surface (a rejection, removal, cancellation, decline, expiry), add
|
|
@@ -245,27 +256,36 @@ For each slice:
|
|
|
245
256
|
adjacent real sources (OpenAPI specs, DB migrations, existing DTOs/event classes in sibling
|
|
246
257
|
contexts) before finalizing field names/types or invariants — don't guess a shape that's
|
|
247
258
|
already defined elsewhere.
|
|
248
|
-
2.
|
|
249
|
-
frontmatter
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
+
2. **First-time authoring:** scaffold the doc mechanically rather than hand-writing the
|
|
260
|
+
frontmatter — `em slice new "<slice name>" --pattern <state-change|state-view|automation|
|
|
261
|
+
translation> --swimlane "<Persona> → <Context>"` writes `slices/<slice-name>.md`
|
|
262
|
+
(kebab-cased to match, via the same slugging `em` uses everywhere else) with the canonical
|
|
263
|
+
`schemaVersion`/`pattern`/`swimlane`/`status: draft`/`version: 1` frontmatter — exactly the
|
|
264
|
+
five keys `em export` and the readiness gate require, no more — and the `# Slice:` heading +
|
|
265
|
+
diagram-image stub already in place. Both `--pattern` and `--swimlane` are required; an
|
|
266
|
+
invalid `--pattern` is refused with the valid choices listed. Never hand-type this block, and
|
|
267
|
+
never fall back to a placeholder pattern/swimlane to dodge the flags. Then fill in every
|
|
268
|
+
judgment section below the stub from step 1 (Intent, Command, Event(s), Invariants,
|
|
269
|
+
Scenarios, ...) — the doc's prose is still entirely hand-authored, only the frontmatter/
|
|
270
|
+
heading scaffold is mechanized. Record the originating need (ticket/conversation link) in the
|
|
271
|
+
Intent section when one exists. When this doc exists because of a split, merge, or rename,
|
|
272
|
+
add the matching lineage key(s) by hand (`split-from`/`merged-from`/`superseded-by`,
|
|
273
|
+
`<slice-key>@v<N>` grammar — see `docs/slice-doc-schema.md` for the full schema).
|
|
274
|
+
**Re-ratification (step 0):** the doc already exists, so `em slice new` doesn't apply here
|
|
275
|
+
(it refuses to overwrite an existing file without `--force`, and forcing would blow away the
|
|
276
|
+
doc's authored body) — bump `version` and flip `status` back to `ready-to-implement` by hand
|
|
277
|
+
in the existing frontmatter instead.
|
|
259
278
|
3. Render the slice's own diagram: `em render <model>.em --slice "<slice name>" -o
|
|
260
|
-
slices/<slice-name>.svg` (kebab-case, matching the doc's filename
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
279
|
+
slices/<slice-name>.svg` (kebab-case, matching the doc's filename and the `![Diagram]` stub
|
|
280
|
+
`em slice new` already wrote) — redraws just this slice in its own canonical pattern shape.
|
|
281
|
+
4. Wire it into the `.em`: `em slice new` (step 2) printed the exact `note
|
|
282
|
+
"slices/<slice-name>.md"` line to add to the slice's primary element (the command for State
|
|
283
|
+
Change, the view for State View, the processor for Automation, the translation for
|
|
284
|
+
Translation) — `em slice new` only writes the new doc file, never edits the `.em` source
|
|
285
|
+
itself, so add that line by hand.
|
|
286
|
+
5. Run `em slice index <model-name>.em` to regenerate `README.md`'s Slices table — the one
|
|
287
|
+
canonical slice index — from the model and the doc frontmatter you just wrote (status,
|
|
288
|
+
`implementedIn` once shipped). Never hand-edit the table; it's a generated block.
|
|
269
289
|
6. Re-render and `em validate`.
|
|
270
290
|
|
|
271
291
|
When a slice is **ratified** — a human flips its `status` to `ready-to-implement` with every
|
|
@@ -282,13 +302,14 @@ where the agent builds rather than facilitates.
|
|
|
282
302
|
contract.** In short: gate on `em validate <model>.em --slice-ready <key>` (stop and hand
|
|
283
303
|
back if it fails — never edit the doc to make the gate pass); treat the slice doc as the
|
|
284
304
|
spec (read-only, except the merge-time `status`/`implementedIn` flip); surface every gap to
|
|
285
|
-
the user instead of deciding it silently; cover every INV
|
|
305
|
+
the user instead of deciding it silently; cover every INV-<MNEMONIC>-n and every scenario with tests;
|
|
286
306
|
in spec-kit projects, allocate via em-sdd-bridge (redirect mode) and never run
|
|
287
307
|
`/speckit.specify`.
|
|
288
308
|
|
|
289
309
|
End of phase: PR merged, slice doc flipped to `status: implemented` with `implementedIn`
|
|
290
|
-
filled, `
|
|
291
|
-
once per ratified slice; `conform` later checks the
|
|
310
|
+
filled, `em slice index <model-name>.em` run to refresh `README.md`'s Slices table. Implement
|
|
311
|
+
doesn't chain to another phase — run it once per ratified slice; `conform` later checks the
|
|
312
|
+
result against the model.
|
|
292
313
|
|
|
293
314
|
## Phase: `conform` — drift check against the codebase
|
|
294
315
|
|
|
@@ -300,31 +321,35 @@ and report where they've drifted — advisory only, never a gate, never an unpro
|
|
|
300
321
|
stance guardrails (evidence-first, uncertainty is never drift, propose-don't-edit). It reuses
|
|
301
322
|
`extract`'s sourcing/mode rules for reading the target codebase rather than duplicating them.
|
|
302
323
|
|
|
303
|
-
In short:
|
|
304
|
-
|
|
305
|
-
|
|
324
|
+
In short: run `em conform-scope <model-name>.em --repo <target-repo-path> --seed-asis` to
|
|
325
|
+
compute the in-scope slice set (diff-scoped by default, via `Last conformance:` + the target
|
|
326
|
+
repo's changed paths mapped through each slice doc's `implementedIn:`) and seed the scratch
|
|
327
|
+
model in one step; for each in-scope slice, gather code evidence *before* comparing to the model
|
|
328
|
+
or doc; write the as-is picture into that scratch model (`<model-name>-asis.em`, reusing the
|
|
329
|
+
canonical model's names wherever the code matches them); run `em diff <model-name>.em
|
|
306
330
|
<model-name>-asis.em --json` and let `em` decide the structural deltas; classify every finding
|
|
307
331
|
(real drift / model gap / internal inconsistency / uncertainty) with cited evidence; write
|
|
308
332
|
`conformance/<date>-report.md` with proposed `issue "conformance: …"` red notes; apply only the
|
|
309
|
-
proposals the user ratifies, then re-render and validate;
|
|
310
|
-
`Last conformance:` marker.
|
|
333
|
+
proposals the user ratifies, then re-render and validate; run `em state set-conformance
|
|
334
|
+
<revision> --report <path>` to update the state file's `Last conformance:` marker.
|
|
311
335
|
|
|
312
|
-
End of phase: state file's `Last conformance:` marker updated
|
|
336
|
+
End of phase: state file's `Last conformance:` marker updated (via `em state set-conformance`),
|
|
337
|
+
Decisions log entry if any
|
|
313
338
|
proposals were applied. Conform doesn't chain to another phase — it's a recurring loop, run
|
|
314
339
|
again whenever the codebase has moved.
|
|
315
340
|
|
|
316
341
|
## Phase: `watch` — live team view
|
|
317
342
|
|
|
318
|
-
|
|
343
|
+
Start the watcher with `--serve` in the background:
|
|
319
344
|
`em watch <model-name>.em -o <model-name>.svg --serve` (run_in_background). It re-renders on every
|
|
320
345
|
save and pushes an instant reload to the browser over Server-Sent Events. Tell the user to open the
|
|
321
346
|
URL it prints (e.g. `http://localhost:5173/?svg=<model-name>.svg`) and share their screen — updates
|
|
322
|
-
appear the moment you save, with no idle churn between edits.
|
|
347
|
+
appear the moment you save, with no polling and no idle churn between edits.
|
|
323
348
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
349
|
+
The viewer navigates like a map — drag to pan, scroll/pinch to zoom, **Fit** to reset — and its
|
|
350
|
+
**Review mode** steps through slices one at a time (see the `review` phase). A save that fails to
|
|
351
|
+
render never blanks the shared screen: the last good diagram stays up, an error banner explains
|
|
352
|
+
what went wrong, and the viewer recovers on its own at the next successful render.
|
|
328
353
|
|
|
329
354
|
## Phase: `review` — stakeholder walkthrough
|
|
330
355
|
|
|
@@ -349,8 +374,8 @@ losing the current slice or resetting review mode.
|
|
|
349
374
|
|
|
350
375
|
Wrap-up: run `em validate --list-issues` to sweep everything captured during the session and
|
|
351
376
|
walk each one with the user, same as any open issue. Update the state file's Participants
|
|
352
|
-
section with who attended, and
|
|
353
|
-
conformance:`).
|
|
377
|
+
section with who attended, and run `em state set-review <date>` to set the `Last stakeholder
|
|
378
|
+
review:` marker (mirrors `Last conformance:`).
|
|
354
379
|
|
|
355
380
|
End of phase: state file's `Last stakeholder review:` marker updated, every issue captured
|
|
356
381
|
live triaged (resolved on the spot, moved to Open questions / parking lot, or left open on
|
|
@@ -393,16 +418,18 @@ command instead.
|
|
|
393
418
|
```bash
|
|
394
419
|
em --version
|
|
395
420
|
em init <name>.em # optional starter scaffold
|
|
421
|
+
em scaffold <name> # full project: <slug>/<slug>.em, README.md, .event-modeling.md
|
|
396
422
|
em validate <name>.em # check rules; exit 0 if clean/warnings only
|
|
397
423
|
em render <name>.em -o <name>.svg # render (svg/png/pdf by extension)
|
|
398
424
|
em render <name>.em --emit-dot # inspect generated Graphviz DOT
|
|
399
425
|
em render <name>.em --slice "<slice-name>" -o slices/<slug>.svg # this slice's own diagram
|
|
400
426
|
em watch <name>.em -o <name>.svg # re-render on save (run in background)
|
|
401
|
-
em watch <name>.em -o <name>.svg --serve # + live viewer
|
|
427
|
+
em watch <name>.em -o <name>.svg --serve # + the live browser viewer: instant push-reload, pan/zoom (--port N)
|
|
402
428
|
# click "Review mode" for a slice-by-slice storyboard walkthrough
|
|
403
429
|
```
|
|
404
430
|
<!-- GENERATED:cli-quick:end -->
|
|
405
431
|
|
|
406
432
|
Always finish a working session by: re-rendering, running `em validate`, and updating
|
|
407
|
-
`.event-modeling.md`
|
|
408
|
-
entry (phases touched + validate
|
|
433
|
+
`.event-modeling.md` — `em state set-phase <phase> [--step <n>]` for the current phase/step,
|
|
434
|
+
decisions and open questions by hand, and a Usage log entry (phases touched + validate
|
|
435
|
+
diagnostic categories hit).
|
|
@@ -72,12 +72,34 @@ authoritative.
|
|
|
72
72
|
|
|
73
73
|
### 1. Scope
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
75
|
+
Run `em conform-scope <model-name>.em --repo <target-repo-path>` — it mechanizes everything
|
|
76
|
+
about scoping that's deterministic: parsing `Last conformance:` (via the same state-file reader
|
|
77
|
+
`em state read` uses), running `git diff --name-only <revision>..HEAD` in the target repo, and
|
|
78
|
+
mapping each changed path to a slice via that slice doc's `implementedIn:` link (a bare/embedded
|
|
79
|
+
repo-relative path that's a prefix of or equal to the changed path — a URL-only `implementedIn`,
|
|
80
|
+
e.g. a PR link, deterministically matches nothing). It prints one JSON document
|
|
81
|
+
(`docs/cli.md`'s conform-scope section documents the envelope):
|
|
82
|
+
|
|
83
|
+
```json
|
|
84
|
+
{ "lastConformance": { "date": "...", "revision": "..." } | null,
|
|
85
|
+
"changedPaths": ["..."],
|
|
86
|
+
"candidateSlices": [ { "key": "checkout", "matchedBy": "implementedIn", "paths": ["..."] } ],
|
|
87
|
+
"unmappedPaths": ["..."] }
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Default: **diff-scoped** — `lastConformance` set, `--full` not passed — `candidateSlices` is
|
|
91
|
+
your in-scope set for step 2. If `lastConformance` is `null` (first run) or you pass `--full`,
|
|
92
|
+
`em conform-scope` scopes every `implemented` slice instead (`matchedBy: "full"`,
|
|
93
|
+
`changedPaths`/`unmappedPaths` both empty) — the tool makes this call for you, no need to
|
|
94
|
+
special-case it yourself.
|
|
95
|
+
|
|
96
|
+
**`unmappedPaths` is your judgment queue, not a dead end.** A changed path the tool couldn't
|
|
97
|
+
place mechanically (`implementedIn` stale, a URL-only link, code that moved) still might belong
|
|
98
|
+
to an in-scope slice — a quick Grep for the path's obvious symbols against the slice docs/model
|
|
99
|
+
vocabulary is exactly the judgment call this phase reserves for you (`em conform-scope` never
|
|
100
|
+
guesses on purpose). Fold anything you place this way into your in-scope set alongside
|
|
101
|
+
`candidateSlices`; leave genuinely unplaceable paths out of scope but note them in the report's
|
|
102
|
+
run metadata rather than silently dropping them.
|
|
81
103
|
|
|
82
104
|
Cost containment here is cadence, not a trigger condition — diff-scoped-by-default is what
|
|
83
105
|
keeps a recurring conform run cheap; don't invent a smarter trigger.
|
|
@@ -125,9 +147,11 @@ For each slice in scope:
|
|
|
125
147
|
without-link"` (status: implemented, no link at all) is a genuine coherence problem, but
|
|
126
148
|
it's already surfaced by `em validate`'s `frontmatter-coherence-implemented-without-link`
|
|
127
149
|
warning — don't re-raise it here as a separate conform finding.
|
|
128
|
-
3. Write what you found into the scratch model (`<model-name>-asis.em`, see below)
|
|
129
|
-
|
|
130
|
-
|
|
150
|
+
3. Write what you found into the scratch model (`<model-name>-asis.em`, see below) — start it
|
|
151
|
+
with `em conform-scope <model-name>.em --repo <target-repo-path> --seed-asis`, which
|
|
152
|
+
byte-copies the canonical `.em` to `<model-name>-asis.em` and ensures `*-asis.em` is
|
|
153
|
+
gitignored (idempotent — safe to pass on every run). **Then replace only the in-scope
|
|
154
|
+
slices** with the as-is picture, leaving out-of-scope slices byte-identical. This is not an optimization:
|
|
131
155
|
`em diff` matches slices by name, so a scratch model containing *only* the in-scope slices
|
|
132
156
|
reports every other canonical slice as `slice-removed` plus one `element-removed` per
|
|
133
157
|
element — a phantom-removal flood on every diff-scoped run, which is the exact false drift
|
|
@@ -215,26 +239,27 @@ stays auditable) but don't ask the user to ratify what's already ratified. **You
|
|
|
215
239
|
canonical model or a slice doc unprompted** — walk the report with the user, apply only the
|
|
216
240
|
proposals they approve, then re-render and `em validate`.
|
|
217
241
|
|
|
218
|
-
End of run: update the state file's `Last conformance:` marker
|
|
242
|
+
End of run: update the state file's `Last conformance:` marker with
|
|
219
243
|
|
|
220
244
|
```
|
|
221
|
-
|
|
245
|
+
em state set-conformance <target-repo revision> --report conformance/YYYY-MM-DD-report.md
|
|
222
246
|
```
|
|
223
247
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
in the loop**: in an interactive session,
|
|
227
|
-
headless/scheduled run writes the report but never
|
|
228
|
-
so the next run re-walks the same span — see
|
|
229
|
-
applied, log a Decisions entry noting what
|
|
248
|
+
— the revision is the one you just diffed against, so the next run's scope starts from here.
|
|
249
|
+
The command writes the exact format step 1 parses back out; never hand-edit the bullet.
|
|
250
|
+
**The marker only advances with the human in the loop**: in an interactive session, run it
|
|
251
|
+
after walking the report with the user; a headless/scheduled run writes the report but never
|
|
252
|
+
the marker (nobody ratified the outcome), so the next run re-walks the same span — see
|
|
253
|
+
`docs/ci.md`. If any proposals were ratified and applied, log a Decisions entry noting what
|
|
254
|
+
changed and why.
|
|
230
255
|
|
|
231
256
|
## Conventions
|
|
232
257
|
|
|
233
258
|
- **Scratch model:** `<model-name>-asis.em`, written **next to** the canonical model (same
|
|
234
259
|
directory as `.event-modeling.md`). Always seeded as a copy of the canonical model with only
|
|
235
|
-
the in-scope slices rewritten (step 2)
|
|
236
|
-
|
|
237
|
-
|
|
260
|
+
the in-scope slices rewritten (step 2) — `em conform-scope --seed-asis` does the seeding and
|
|
261
|
+
the gitignoring (`*-asis.em`, idempotent) mechanically, never built up from nothing and never
|
|
262
|
+
hand-maintained. It's regenerated every conform run.
|
|
238
263
|
- **Report location:** `conformance/<YYYY-MM-DD>-report.md` in the model directory. One file
|
|
239
264
|
per run; don't overwrite a prior date's report.
|
|
240
265
|
- **Red note wording:** `issue "conformance: <what's wrong, plainly>"` — plain enough that
|