@milehimikey/em 1.12.0 → 1.13.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.
- package/.claude/skills/event-modeling/SKILL.md +5 -2
- package/.claude/skills/event-modeling-conform/SKILL.md +20 -9
- package/.claude/skills/event-modeling-conform/reference/conform.md +107 -10
- package/.claude/skills/event-modeling-design/SKILL.md +26 -4
- package/.claude/skills/event-modeling-discover/SKILL.md +1 -1
- package/.claude/skills/event-modeling-implement/SKILL.md +7 -4
- package/.claude/skills/event-modeling-implement/reference/implement.md +26 -8
- package/.claude/skills/event-modeling-review/SKILL.md +5 -1
- package/.claude/skills/event-modeling-shared/reference/em-dsl.md +45 -6
- package/.claude/skills/event-modeling-shared/reference/operating-principles.md +13 -3
- package/.claude/skills/event-modeling-shared/reference/slice-doc-schema.md +39 -0
- package/.claude/skills/event-modeling-shared/templates/conformance-report.md +8 -1
- package/.claude/skills/event-modeling-shared/templates/state.md +3 -0
- package/README.md +1 -0
- package/dist/catalog/docJoin.d.ts +9 -0
- package/dist/catalog/docJoin.js +6 -0
- package/dist/catalog/docJoin.js.map +1 -1
- package/dist/catalog/driftSignal.d.ts +11 -5
- package/dist/catalog/driftSignal.js +18 -4
- package/dist/catalog/driftSignal.js.map +1 -1
- package/dist/catalog/modelVersionValidate.d.ts +9 -0
- package/dist/catalog/modelVersionValidate.js +38 -0
- package/dist/catalog/modelVersionValidate.js.map +1 -0
- package/dist/catalog/sliceDoc.d.ts +12 -0
- package/dist/catalog/sliceDoc.js +15 -0
- package/dist/catalog/sliceDoc.js.map +1 -1
- package/dist/cli/ciInit.d.ts +24 -0
- package/dist/cli/ciInit.js +85 -15
- package/dist/cli/ciInit.js.map +1 -1
- package/dist/cli/conformScope.d.ts +1 -0
- package/dist/cli/conformScope.js +3 -1
- package/dist/cli/conformScope.js.map +1 -1
- package/dist/cli/conformSupersede.d.ts +24 -2
- package/dist/cli/conformSupersede.js +44 -3
- package/dist/cli/conformSupersede.js.map +1 -1
- package/dist/cli/coverage.d.ts +16 -2
- package/dist/cli/coverage.js +26 -4
- package/dist/cli/coverage.js.map +1 -1
- package/dist/cli/findings.d.ts +134 -0
- package/dist/cli/findings.js +355 -0
- package/dist/cli/findings.js.map +1 -0
- package/dist/cli/metrics.d.ts +93 -0
- package/dist/cli/metrics.js +331 -0
- package/dist/cli/metrics.js.map +1 -0
- package/dist/cli/modelVersion.d.ts +139 -0
- package/dist/cli/modelVersion.js +256 -0
- package/dist/cli/modelVersion.js.map +1 -0
- package/dist/cli/reratify.d.ts +24 -1
- package/dist/cli/reratify.js +73 -17
- package/dist/cli/reratify.js.map +1 -1
- package/dist/cli/skillCheck.js +2 -2
- package/dist/cli/skillCheck.js.map +1 -1
- package/dist/cli/sliceConform.d.ts +50 -0
- package/dist/cli/sliceConform.js +206 -0
- package/dist/cli/sliceConform.js.map +1 -0
- package/dist/cli/sliceIndex.d.ts +2 -0
- package/dist/cli/sliceIndex.js +15 -3
- package/dist/cli/sliceIndex.js.map +1 -1
- package/dist/cli/sliceNew.d.ts +12 -0
- package/dist/cli/sliceNew.js +23 -0
- package/dist/cli/sliceNew.js.map +1 -1
- package/dist/cli/sliceStubAll.d.ts +76 -0
- package/dist/cli/sliceStubAll.js +189 -0
- package/dist/cli/sliceStubAll.js.map +1 -0
- package/dist/cli/stateFile.d.ts +63 -7
- package/dist/cli/stateFile.js +179 -18
- package/dist/cli/stateFile.js.map +1 -1
- package/dist/cli/status.d.ts +79 -1
- package/dist/cli/status.js +134 -15
- package/dist/cli/status.js.map +1 -1
- package/dist/cli/upgrade.d.ts +132 -0
- package/dist/cli/upgrade.js +524 -0
- package/dist/cli/upgrade.js.map +1 -0
- package/dist/cli.js +609 -50
- package/dist/cli.js.map +1 -1
- package/dist/emit/coverageJson.d.ts +5 -2
- package/dist/emit/coverageJson.js +6 -2
- package/dist/emit/coverageJson.js.map +1 -1
- package/dist/emit/freshnessJson.d.ts +1 -1
- package/dist/emit/freshnessJson.js +3 -1
- package/dist/emit/freshnessJson.js.map +1 -1
- package/dist/emit/json.d.ts +11 -1
- package/dist/emit/json.js +35 -1
- package/dist/emit/json.js.map +1 -1
- package/dist/emit/metricsJson.d.ts +7 -0
- package/dist/emit/metricsJson.js +27 -0
- package/dist/emit/metricsJson.js.map +1 -0
- package/dist/emit/statusJson.d.ts +1 -1
- package/dist/emit/statusJson.js +17 -1
- package/dist/emit/statusJson.js.map +1 -1
- package/dist/emit/upgradeJson.d.ts +5 -0
- package/dist/emit/upgradeJson.js +29 -0
- package/dist/emit/upgradeJson.js.map +1 -0
- package/dist/emit/validateJson.d.ts +6 -2
- package/dist/emit/validateJson.js +12 -5
- package/dist/emit/validateJson.js.map +1 -1
- package/dist/mcp/server.d.ts +1 -1
- package/dist/mcp/server.js +137 -9
- package/dist/mcp/server.js.map +1 -1
- package/dist/model/rules.d.ts +7 -0
- package/dist/model/rules.js +12 -0
- package/dist/model/rules.js.map +1 -1
- package/dist/model/validate.d.ts +20 -0
- package/dist/model/validate.js +94 -45
- package/dist/model/validate.js.map +1 -1
- package/dist/templates.d.ts +2 -2
- package/dist/templates.js +7 -1
- package/dist/templates.js.map +1 -1
- package/dist/util/semver.d.ts +19 -0
- package/dist/util/semver.js +54 -0
- package/dist/util/semver.js.map +1 -0
- package/package.json +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: event-modeling
|
|
3
|
-
em-version: 1.
|
|
3
|
+
em-version: 1.13.1
|
|
4
4
|
description: >-
|
|
5
5
|
Use when the user runs `/event-modeling` (with or without a phase name), or wants to resume an
|
|
6
6
|
event-modeling session without specifying which part of the process applies. Reads the model's
|
|
@@ -30,7 +30,10 @@ phase lives in.
|
|
|
30
30
|
## Routing logic
|
|
31
31
|
|
|
32
32
|
1. Check the tool: `em --version`. If missing, tell the user to run `npm i -g @milehimikey/em`
|
|
33
|
-
and stop until installed.
|
|
33
|
+
and stop until installed. Then check this vendored bundle's own currency against it — see
|
|
34
|
+
`../event-modeling-shared/reference/operating-principles.md`'s Preconditions step 2: a bundle
|
|
35
|
+
even one minor version behind the installed em is a STOP, not a warning — only a patch-only
|
|
36
|
+
gap proceeds normally.
|
|
34
37
|
2. Parse `$ARGUMENTS` for a phase name.
|
|
35
38
|
- **A recognized phase name** (`discover`, `extract`, `model`, `slice`, `implement`,
|
|
36
39
|
`conform`, `validate`, `watch`, `review`): look it up in the table above and invoke that
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: event-modeling-conform
|
|
3
|
-
em-version: 1.
|
|
3
|
+
em-version: 1.13.1
|
|
4
4
|
description: >-
|
|
5
5
|
Use when checking a ratified event model (and its slice docs) for drift against the codebase
|
|
6
6
|
that implements it — advisory only, never a gate, never an unprompted edit — or when walking
|
|
@@ -33,18 +33,29 @@ or doc; write the as-is picture into that scratch model (`<model-name>-asis.em`,
|
|
|
33
33
|
canonical model's names wherever the code matches them); run `em diff <model-name>.em
|
|
34
34
|
<model-name>-asis.em --json` and let `em` decide the structural deltas; classify every finding
|
|
35
35
|
(real drift / model gap / internal inconsistency / uncertainty) with cited evidence; write
|
|
36
|
-
`conformance/<date>-report.md`
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
`conformance/<date>-report.md` **and its structured twin `conformance/<date>-findings.json`**
|
|
37
|
+
(one entry per finding, `em conform-findings check <path>` to verify) with proposed `issue
|
|
38
|
+
"conformance: …"` red notes; apply only the proposals the user ratifies, then re-render and
|
|
39
|
+
validate; run `em state set-conformance <revision> --report <path>` to update the state file's
|
|
40
|
+
`Last conformance:` marker.
|
|
39
41
|
|
|
40
42
|
Ruling on a finding is a human gate, like ratifying a slice
|
|
41
43
|
(docs/process.md#the-slice-lifecycle-gates): the sweep gathers evidence and proposes, a person
|
|
42
|
-
decides, and `em
|
|
44
|
+
decides, and `em conform-supersede ... --locus <model|doc|code|none> --by <name>` records the
|
|
45
|
+
ruling on the findings record (and stamps the report) — never rule on your own judgment. Once
|
|
46
|
+
every finding touching a slice is ruled, `em slice conform <model-name>.em <key> --at <rev>`
|
|
47
|
+
certifies that version of the slice.
|
|
43
48
|
|
|
44
|
-
End of phase: state file's `Last conformance:` marker updated (via `em state set-conformance`
|
|
45
|
-
|
|
46
|
-
proposals were applied. Conform doesn't chain to
|
|
47
|
-
again whenever the codebase has moved.
|
|
49
|
+
End of phase: state file's `Last conformance:` marker updated (via `em state set-conformance` —
|
|
50
|
+
refuses while any `implemented` slice still has an unruled finding; `--partial` escapes with a
|
|
51
|
+
loud notice), Decisions log entry if any proposals were applied. Conform doesn't chain to
|
|
52
|
+
another phase — it's a recurring loop, run again whenever the codebase has moved.
|
|
53
|
+
|
|
54
|
+
A full (non-`--partial`) `em state set-conformance` also **certifies the model's current design
|
|
55
|
+
version** (MIL-218, `docs/process.md#model-versions`) — it refuses if no design version has ever
|
|
56
|
+
been bumped ("bump a model version first") or if the model changed during this run without a
|
|
57
|
+
re-bump; run `em model version bump <model-name>.em --by <name>` before the final `em state
|
|
58
|
+
set-conformance` call if either applies.
|
|
48
59
|
|
|
49
60
|
## Phase: `validate`
|
|
50
61
|
|
|
@@ -234,10 +234,22 @@ step 2 — sorts into exactly one class:
|
|
|
234
234
|
which finding. Cite `slice.doc.driftSignal` and `slice.doc.version` together as evidence.
|
|
235
235
|
- **Extraction uncertainty** — no evidence either way. Never reported as drift or a gap.
|
|
236
236
|
|
|
237
|
+
**Read-model exposure (MIL-215).** Two rulings apply the classes above to a `view`'s exposure —
|
|
238
|
+
whether it ships a query endpoint — instead of leaving each case to fresh judgment:
|
|
239
|
+
|
|
240
|
+
- An **internal view** (no `ui` reads it, and it isn't marked `public`) implemented as
|
|
241
|
+
criteria-sourced state (a reaction's own read, no materialized projection — the general idiom
|
|
242
|
+
step 2 already names) or as an unexposed projection is **Conformant, never dead code to
|
|
243
|
+
flag**. It's the read operation the model draws to say an automation or translation *must*
|
|
244
|
+
read, not an endpoint promise; don't propose deleting it.
|
|
245
|
+
- An **endpoint in code on a view the model shows no `ui` reading and no `public` marking** is a
|
|
246
|
+
**Model gap** — "add the `ui` or remove the endpoint" — **never Real drift to delete**.
|
|
247
|
+
Nobody decided whether that view is exposed; deleting the code decides it for them.
|
|
248
|
+
|
|
237
249
|
Every classification must cite the evidence recorded in step 2 (or the `em diff` entry, for
|
|
238
250
|
structural findings) — a finding with no citation isn't ready to report.
|
|
239
251
|
|
|
240
|
-
### 5. Report + proposals
|
|
252
|
+
### 5. Report + findings record + proposals
|
|
241
253
|
|
|
242
254
|
Write `conformance/<YYYY-MM-DD>-report.md` in the model directory, from
|
|
243
255
|
`../../event-modeling-shared/templates/conformance-report.md`. For a real-drift or model-gap finding, propose a
|
|
@@ -250,6 +262,71 @@ stays auditable) but don't ask the user to ratify what's already ratified. **You
|
|
|
250
262
|
canonical model or a slice doc unprompted** — walk the report with the user, apply only the
|
|
251
263
|
proposals they approve, then re-render and `em validate`.
|
|
252
264
|
|
|
265
|
+
**Also write the findings JSON (MIL-214).** Alongside the report, write
|
|
266
|
+
`conformance/<YYYY-MM-DD>-findings.json` — one entry per `### n.` finding, ids matching the
|
|
267
|
+
report's own numbering. Shape (`findingsSchemaVersion: "1.0"`, additive-only, 2-space indent,
|
|
268
|
+
keys sorted, findings sorted by `id`, trailing newline):
|
|
269
|
+
|
|
270
|
+
```json
|
|
271
|
+
{
|
|
272
|
+
"findingsSchemaVersion": "1.0",
|
|
273
|
+
"model": "checkout.em",
|
|
274
|
+
"report": "conformance/YYYY-MM-DD-report.md",
|
|
275
|
+
"revision": "<target-repo revision>",
|
|
276
|
+
"findings": [
|
|
277
|
+
{
|
|
278
|
+
"id": 1,
|
|
279
|
+
"surface": "structural",
|
|
280
|
+
"class": "Real drift",
|
|
281
|
+
"slice": "checkout",
|
|
282
|
+
"evidence": "code shows X at path/to/File.kt:42",
|
|
283
|
+
"locus": null,
|
|
284
|
+
"resolvedBy": null,
|
|
285
|
+
"resolvedOn": null
|
|
286
|
+
}
|
|
287
|
+
]
|
|
288
|
+
}
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
`surface` is one of `structural` (`.em` <-> code — step 3's diff), `spec` (slice doc <-> code —
|
|
292
|
+
step 2's invariant/scenario walk), `internal` (slice doc <-> `.em` — step 2's `doc-model-*`
|
|
293
|
+
diagnostics), or `other`. `class` is the step-4 classification verbatim (Real drift, Model gap,
|
|
294
|
+
Internal inconsistency, Accepted divergence, Unpropagated delta, Extraction uncertainty). `slice`
|
|
295
|
+
is the concerned slice's export key, or `null` for a finding that isn't attributable to one
|
|
296
|
+
(counts as in-scope for every slice's unruled-findings check). `locus`/`resolvedBy`/`resolvedOn`
|
|
297
|
+
start `null` — a later `em conform-supersede --locus --by` call fills them in once a human rules.
|
|
298
|
+
Run `em conform-findings check conformance/YYYY-MM-DD-findings.json` before ending the session —
|
|
299
|
+
a headless run's mechanical proof it wrote a valid record.
|
|
300
|
+
|
|
301
|
+
**Ruling on a finding (MIL-214) — once the user decides.** Run, per finding or batch of findings
|
|
302
|
+
ruled the same way:
|
|
303
|
+
|
|
304
|
+
```
|
|
305
|
+
em conform-supersede <model-name>.em conformance/YYYY-MM-DD-report.md --as-of <target-repo revision> \
|
|
306
|
+
--findings <spec> --locus <model|doc|code|none> --by <name>
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
— this records `locus`/`resolvedBy`/`resolvedOn` on the named findings in the JSON (refusing to
|
|
310
|
+
silently overwrite an already-different `locus`) AND stamps the report's "superseded as of `<rev>`"
|
|
311
|
+
banner in the same call (see below). `locus: code` on an unresolved finding is the carrier for
|
|
312
|
+
"the spec is right, the code is wrong" — no doc delta required for that case any more; `locus:
|
|
313
|
+
model` means fix the `.em` (apply the proposed red note, or a stronger edit the user chose
|
|
314
|
+
instead); `locus: doc` means the slice doc needs a delta/re-ratification; `locus: none` covers
|
|
315
|
+
Accepted divergence/Unpropagated delta/Extraction uncertainty, where nothing needs to change.
|
|
316
|
+
|
|
317
|
+
**Certifying a slice, once every finding touching it is ruled (MIL-214).** For each in-scope
|
|
318
|
+
slice with no unruled findings left:
|
|
319
|
+
|
|
320
|
+
```
|
|
321
|
+
em slice conform <model-name>.em <slice-key> --at <target-repo revision>
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
— records `conformedVersion`/`conformedAt`/`conformedOn` on that slice's doc, so
|
|
325
|
+
`driftSignal` reads `in-sync` again (it reads `uncertified` for an implemented slice that's never
|
|
326
|
+
been through this) instead of just trusting `implementedIn`. Legal only for `status: implemented`
|
|
327
|
+
with a link, and itself refuses if an unruled finding for that slice still exists at this
|
|
328
|
+
revision — the mechanical proof this step comes only after rulings, not before.
|
|
329
|
+
|
|
253
330
|
End of run: update the state file's `Last conformance:` marker with
|
|
254
331
|
|
|
255
332
|
```
|
|
@@ -258,14 +335,21 @@ em state set-conformance <target-repo revision> --report conformance/YYYY-MM-DD-
|
|
|
258
335
|
|
|
259
336
|
— the revision is the one you just diffed against, so the next run's scope starts from here.
|
|
260
337
|
The command writes the exact format step 1 parses back out; never hand-edit the bullet.
|
|
338
|
+
**Refuses (MIL-214) while any `implemented` slice still has an unruled finding** in the findings
|
|
339
|
+
JSON beside the report — rule on every finding first (or certify what's already ruled via `em
|
|
340
|
+
slice conform` above), or pass `--partial` to record the marker with a loud notice instead
|
|
341
|
+
(`notice: conformance marker recorded as PARTIAL — N finding(s) unruled`) when the team
|
|
342
|
+
deliberately wants to advance the marker without finishing every ruling this session.
|
|
261
343
|
**The marker only advances with the human in the loop**: in an interactive session, run it
|
|
262
|
-
after walking the report with the user; a headless/scheduled run writes the report
|
|
263
|
-
the marker (nobody ratified the outcome), so the next run re-walks the same span —
|
|
264
|
-
`docs/ci.md`. If any proposals were ratified and applied, log a Decisions entry noting what
|
|
344
|
+
after walking the report with the user; a headless/scheduled run writes the report and findings
|
|
345
|
+
JSON but never the marker (nobody ratified the outcome), so the next run re-walks the same span —
|
|
346
|
+
see `docs/ci.md`. If any proposals were ratified and applied, log a Decisions entry noting what
|
|
265
347
|
changed and why.
|
|
266
348
|
|
|
267
|
-
**Superseding the report you just walked (MIL-164).**
|
|
268
|
-
|
|
349
|
+
**Superseding the report you just walked (MIL-164).** The `--locus`/`--by` call above already
|
|
350
|
+
stamps the report's banner in the same call when a ruling was recorded; if a finding's ruling
|
|
351
|
+
doesn't need `--locus`/`--by` recorded (a migration-path report predating the findings JSON, or
|
|
352
|
+
a ruling you're only banner-stamping after the fact), run the same command without them:
|
|
269
353
|
|
|
270
354
|
```
|
|
271
355
|
em conform-supersede <model-name>.em conformance/YYYY-MM-DD-report.md --as-of <target-repo revision> --findings <spec>
|
|
@@ -298,10 +382,23 @@ each call adds its own stamp rather than overwriting the last.
|
|
|
298
382
|
## Completion & handoff
|
|
299
383
|
|
|
300
384
|
Conform is complete when: every in-scope slice has been walked (step 2), the scratch model has
|
|
301
|
-
been diffed (step 3), every finding is classified with cited evidence (step 4), the report
|
|
302
|
-
written (step 5), the state file's `Last conformance:` marker is updated
|
|
303
|
-
|
|
304
|
-
|
|
385
|
+
been diffed (step 3), every finding is classified with cited evidence (step 4), the report AND
|
|
386
|
+
its findings JSON are written (step 5), the state file's `Last conformance:` marker is updated
|
|
387
|
+
(or deliberately left as `--partial`), and the user has seen the report and said which proposals
|
|
388
|
+
(if any) to apply and which findings resolve to which locus. Applied proposals get re-rendered
|
|
389
|
+
and re-validated before you call the run done.
|
|
390
|
+
|
|
391
|
+
A full (non-`--partial`) `em state set-conformance` does one more thing (MIL-218): it also
|
|
392
|
+
**certifies** the model's current design version — writes `certified: { at, on, report,
|
|
393
|
+
findings }` into that version's `model-versions/v<N>.json` manifest, and rewrites the state
|
|
394
|
+
file's `Certified:` bullet. This is the "conform ran clean against version N" fact a
|
|
395
|
+
stakeholder or a release note can point at. It only works on an already-**bumped** design
|
|
396
|
+
version — `em state set-conformance` refuses (pointing at `em model version bump`) if no
|
|
397
|
+
manifest exists yet, or if the model has drifted since the last bump (the certification would
|
|
398
|
+
otherwise name a version that isn't what conform actually walked). If the model changed during
|
|
399
|
+
this conform run (a slice's `version:` moved, or the `.em` file itself changed), bump a new
|
|
400
|
+
design version (`em model version bump --by <name>`) before the final `em state
|
|
401
|
+
set-conformance` call. `--partial` never certifies. See `docs/process.md#model-versions`.
|
|
305
402
|
|
|
306
403
|
Conform doesn't chain to another phase automatically — it's a recurring loop, not a step in
|
|
307
404
|
building the model. Suggest running it again next time the target codebase has moved, at
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: event-modeling-design
|
|
3
|
-
em-version: 1.
|
|
3
|
+
em-version: 1.13.1
|
|
4
4
|
description: >-
|
|
5
5
|
Use when structuring a draft event model into swimlanes and the four patterns (State Change,
|
|
6
6
|
State View, Automation, Translation), evaluating a model's structural completeness, or writing
|
|
@@ -51,7 +51,11 @@ Goal: a structurally complete, **validated** model with correct patterns and swi
|
|
|
51
51
|
deep-dive in the `slice` phase below); the docs are the home for everything collected from
|
|
52
52
|
here on, not yet implementation-ready specs. Because every doc already exists by the time the
|
|
53
53
|
`slice` phase begins, its own step 2 scaffolding call is then a no-op — that phase picks up
|
|
54
|
-
at its step 1's deeper pass.
|
|
54
|
+
at its step 1's deeper pass. For a purely exploratory/backbone-mapping model that only needs
|
|
55
|
+
status coloring right now (not a full spec per slice yet), `em slice stub-all <model>.em` is
|
|
56
|
+
the one-command fast path: a near-free stub per undocumented slice, wired, in slice order
|
|
57
|
+
(MIL-184) — skip the per-slice `em slice new` calls above and deepen individual docs later
|
|
58
|
+
when the team is ready.
|
|
55
59
|
3. **Evaluate completeness (step 7).** Walk the model: every slice is a **complete** pattern, not a
|
|
56
60
|
half-slice — **every command has something that triggers it**, every command emits an event,
|
|
57
61
|
**every event is read by a read model**, **every read model has a consumer**, every view has a
|
|
@@ -63,6 +67,10 @@ Goal: a structurally complete, **validated** model with correct patterns and swi
|
|
|
63
67
|
For an unread event, don't just bolt on a view to silence the warning: ask the user who looks at
|
|
64
68
|
this fact and what they do with it. The honest answers are "here's the read model we missed" or
|
|
65
69
|
"nobody — so why are we recording it", and both improve the model.
|
|
70
|
+
**Per `view`, also ask who reads it (MIL-215):** a person or client reads it → draw the `ui`
|
|
71
|
+
that reads it; another model/system reads it → mark it `public`; only an automation reads
|
|
72
|
+
it → nothing, it's internal by design. No new keyword — reachability is already what `ui` and
|
|
73
|
+
`public` mean.
|
|
66
74
|
|
|
67
75
|
End of phase: render, update state (`em state set-phase slice` — the mechanical marker the state
|
|
68
76
|
machine expects), and stop. Every slice already has a draft doc ready to receive the deep spec,
|
|
@@ -107,7 +115,16 @@ For each slice:
|
|
|
107
115
|
anything unresolved rather than guessing. If the slice lives in an existing codebase, Grep/Read
|
|
108
116
|
adjacent real sources (OpenAPI specs, DB migrations, existing DTOs/event classes in sibling
|
|
109
117
|
contexts) before finalizing field names/types or invariants — don't guess a shape that's
|
|
110
|
-
already defined elsewhere.
|
|
118
|
+
already defined elsewhere. Before finalizing an invariant, also compare it with the slices in
|
|
119
|
+
**this same model** — never another `.em` model — that make the same kind of change (other
|
|
120
|
+
`Archive*` or `Create*` state changes on different entities, say). If one of them already
|
|
121
|
+
states an analogous rule, either state the same rule here — written out in this doc under
|
|
122
|
+
this slice's own `INV-<MNEMONIC>-n` ID, not by pointing at the sibling's — or record why this
|
|
123
|
+
slice's case differs. If this slice has a rule those siblings lack, raise that with the user
|
|
124
|
+
as an open question against each of them; a ratified sibling changes only through its own
|
|
125
|
+
re-ratification, never as a side effect of this slice. Repeating a rule across slice docs is
|
|
126
|
+
correct: each doc is a self-contained spec, and whether the code behind those rules is shared
|
|
127
|
+
is the constitution's call, not this doc's.
|
|
111
128
|
2. **First-time authoring:** scaffold the doc mechanically rather than hand-writing the
|
|
112
129
|
frontmatter — `em slice new "<slice name>" --pattern <state-change|state-view|automation|
|
|
113
130
|
translation> --swimlane "<Persona> → <Context>" --wire <model>.em` writes `slices/<slice-name>.md`
|
|
@@ -136,7 +153,12 @@ For each slice:
|
|
|
136
153
|
doc's authored body) — run `em slice reratify <model>.em <slice-key>` instead: it bumps
|
|
137
154
|
`version` and flips `status` back to `ready-to-implement` in the existing frontmatter,
|
|
138
155
|
clearing any stale `ratifiedBy:`/`ratifiedOn:` from the prior version so a follow-up
|
|
139
|
-
`em slice ratify --by <name>` (if the team records that) applies cleanly.
|
|
156
|
+
`em slice ratify --by <name>` (if the team records that) applies cleanly. The same command
|
|
157
|
+
changes a ratified doc that **never shipped** (`ready-to-implement` with `ratifiedBy` set — a
|
|
158
|
+
gap answered mid-build, MIL-258): it bumps `version` and clears the sign-off but leaves
|
|
159
|
+
`status` alone. Either way the doc is not ratified until `em slice ratify --by <name>` records
|
|
160
|
+
the new sign-off. A `ready-to-implement` doc with no `ratifiedBy` is already awaiting that
|
|
161
|
+
sign-off and refuses a second `reratify`; a `draft`/`reviewed` doc is simply edited.
|
|
140
162
|
3. Render the slice's own diagram: `em render <model>.em --slice "<slice name>" -o
|
|
141
163
|
slices/<slice-name>.svg` (kebab-case, matching the doc's filename and the `![Diagram]` stub
|
|
142
164
|
`em slice new` already wrote) — redraws just this slice in its own canonical pattern shape.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: event-modeling-discover
|
|
3
|
-
em-version: 1.
|
|
3
|
+
em-version: 1.13.1
|
|
4
4
|
description: >-
|
|
5
5
|
Use when starting a brand-new event model from scratch — greenfield discovery: brainstorming
|
|
6
6
|
past-tense events, storyboarding the happy path, finding the commands and read models — or when
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: event-modeling-implement
|
|
3
|
-
em-version: 1.
|
|
3
|
+
em-version: 1.13.1
|
|
4
4
|
description: >-
|
|
5
5
|
Use when building a single ratified event-modeling slice (status: ready-to-implement) into
|
|
6
6
|
merged, tested code — the one phase where the agent builds rather than facilitates. Gates on
|
|
@@ -21,11 +21,14 @@ land a one-time foundation PR holding every model event (plus the shared interfa
|
|
|
21
21
|
slices only ever import contracts, never invent or reach into a sibling's; build in dependency
|
|
22
22
|
order from `em query upstream`, not timeline order; treat the slice doc as
|
|
23
23
|
the spec (read-only, except the merge-time `status`/`implementedIn` flip); implement exactly one
|
|
24
|
-
slice doc per PR — a `covers:` doc's two keys ship together in that one PR, an `again` view
|
|
25
|
-
instance
|
|
24
|
+
slice doc per PR — a `covers:` doc's two keys ship together in that one PR, and an `again` view
|
|
25
|
+
instance is a continuation of its originating slice (no doc, status, or PR of its own — it
|
|
26
|
+
ships in the originating doc's PR); ship the endpoint a
|
|
26
27
|
`ui`-triggered command or `ui`-consumed view obligates, and surface — never invent — one the
|
|
27
28
|
model doesn't show; surface every gap to the user instead of deciding it silently; cover every
|
|
28
|
-
`INV-<MNEMONIC>-n` and every scenario with tests
|
|
29
|
+
`INV-<MNEMONIC>-n` and every scenario with tests, proving the citations before merge with
|
|
30
|
+
`em coverage <model>.em --slice <key> --tests <dir> --strict` (the default form skips a
|
|
31
|
+
`ready-to-implement` slice); in spec-kit projects, allocate via
|
|
29
32
|
em-sdd-bridge (redirect mode) and never run `/speckit.specify`.
|
|
30
33
|
|
|
31
34
|
**Gate: no constitution, no first slice.** The constitution is the project's ratified house rules
|
|
@@ -35,9 +35,10 @@ every `## Open Questions` checkbox is checked, and no status/version/link incohe
|
|
|
35
35
|
`statusReady`/`noUncheckedOpenQuestions`) if you need to say which one is blocking.
|
|
36
36
|
|
|
37
37
|
**`ready: false` means stop** — with one named exception: a slice already `status: implemented`
|
|
38
|
-
with `driftSignal: in-sync` also reads `ready: false` (its
|
|
39
|
-
nothing is newly ratified), and that specific case is
|
|
40
|
-
see §3's third mode before treating it as one. For
|
|
38
|
+
with `driftSignal: in-sync` or `uncertified` (MIL-214) also reads `ready: false` (its
|
|
39
|
+
`statusReady` gate fails because nothing is newly ratified), and that specific case is
|
|
40
|
+
re-implementation/repair, not a blocker — see §3's third mode before treating it as one. For
|
|
41
|
+
every other `false`, report which `gates`
|
|
41
42
|
entries are `false` (and any `diagnostics` entries concerning this slice) and hand the slice
|
|
42
43
|
back to the humans. Never make the gate pass yourself — checking an open-question box, flipping
|
|
43
44
|
`status`, or editing frontmatter are ratification decisions, and ratification happens in a
|
|
@@ -86,7 +87,9 @@ section — and the routing from it is mechanical, not a technical choice you ma
|
|
|
86
87
|
translation, a view read only by a reaction) means internal-only: no endpoint. If one seems
|
|
87
88
|
needed anyway, that's a gap to surface (§4), not a technical choice to make mid-implementation
|
|
88
89
|
— adding a route the model doesn't show is exactly the kind of silent divergence §4 exists to
|
|
89
|
-
catch.
|
|
90
|
+
catch. An endpoint on a view the model shows no `ui` reading is a gap to surface the same way
|
|
91
|
+
(MIL-215) — conform will classify it as a **model gap**, never drift to delete, once you flag
|
|
92
|
+
it (`../../event-modeling-conform/reference/conform.md`, Flow step 4).
|
|
90
93
|
- **`public` events and views** are the model's published integration surface: their shape is a
|
|
91
94
|
contract, not an implementation detail. `em validate --list-public` lists them; `em typespec`
|
|
92
95
|
is the POC generator for a downstream schema. Changing a public element's shape is a ratified
|
|
@@ -122,8 +125,11 @@ Check the doc's `version:` and `## Delta` section (or `em export`'s `slice.doc.d
|
|
|
122
125
|
the people who've edited it (generated-then-owned); regeneration is legal only for slices
|
|
123
126
|
whose code never merged.
|
|
124
127
|
- **Re-implementation / repair** (`status: implemented`, `implementedIn` set, `driftSignal:
|
|
125
|
-
in-sync`
|
|
126
|
-
|
|
128
|
+
in-sync` **or** `uncertified` (MIL-214 — certification status is orthogonal to whether the doc
|
|
129
|
+
changed; most shipped slices sit at `uncertified` until a conform sweep certifies them, which
|
|
130
|
+
doesn't change which mode this is) — `--slice-ready` reports `ready: false` purely because
|
|
131
|
+
`statusReady` fails, with no other gate false and no doc content changed): the doc hasn't
|
|
132
|
+
changed, but the shipped code
|
|
127
133
|
needs rebuilding or fixing — deleted code, a reverted PR, a bug in behavior the doc already
|
|
128
134
|
specifies. **The doc is still the spec.** The gate's `false` here means "nothing new is
|
|
129
135
|
ratified," not "stop" — it is not license to self-initiate: proceed only when a human has
|
|
@@ -151,6 +157,12 @@ undocumented ordering, a contradiction with adjacent code. The discipline:
|
|
|
151
157
|
your recommendation. The human resolves it — at the model, where the resolution lands as an
|
|
152
158
|
answered open question or a small ratified delta alongside your fix, so the decision is
|
|
153
159
|
recorded instead of buried in an implementation diff.
|
|
160
|
+
- **How a delta is ratified on a doc that never shipped** (it is `ready-to-implement` with
|
|
161
|
+
`ratifiedBy` set): once the human has answered, the doc changes by `em slice reratify
|
|
162
|
+
<model>.em <slice-key>` (bumps `version:`, clears the old sign-off, leaves `status` alone),
|
|
163
|
+
the answer is written into the doc, and the human re-signs with `em slice ratify <model>.em
|
|
164
|
+
<slice-key> --by <name>`. That is the human's step, not yours — you never run `ratify`, and
|
|
165
|
+
the doc is not ratified again until they do; resume the build after that.
|
|
154
166
|
- **Never edit the ratified doc to record your own answer**, and never quietly pick a behavior
|
|
155
167
|
a business person could have an opinion on. Silent divergence is the failure mode the whole
|
|
156
168
|
conformance loop exists to catch — don't manufacture it.
|
|
@@ -177,8 +189,14 @@ or seem small — see §10.
|
|
|
177
189
|
- The PR description cites exactly one slice doc (plus its `covers:` keys, if any) and lists
|
|
178
190
|
that doc's invariants alongside the tests that cover them.
|
|
179
191
|
- Every `INV-<MNEMONIC>-n` invariant has at least one test that cites its ID — checked mechanically by
|
|
180
|
-
`em coverage <model>.em --tests <dir
|
|
181
|
-
eyeballing citations by hand.
|
|
192
|
+
`em coverage <model>.em --slice <slice-key> --tests <dir> --strict` (MIL-130, MIL-255); run it
|
|
193
|
+
before merge rather than eyeballing citations by hand. `--slice` is what makes this check the
|
|
194
|
+
slice under build: the default form, `em coverage <model>.em --tests <dir>`, counts only slices
|
|
195
|
+
already flipped to `implemented` (MIL-207), and your slice is still `ready-to-implement` until
|
|
196
|
+
the §6 flip — so the default form reports it `inScope: false`, checks nothing, and exits 0. It
|
|
197
|
+
is a regression check for shipped slices, not the definition-of-done check. (`--include-ready`
|
|
198
|
+
is no substitute: it counts every ratified slice, so `--strict` fails on slices nobody has
|
|
199
|
+
started.) A continuation key resolves to its originating slice's doc. If it exits 1 with "not in scope", the slice's doc is not `ready-to-implement`/`implemented` — nothing was checked, so stop and surface it rather than treating the run as a pass.
|
|
182
200
|
- Every scenario in `## Scenarios (Given / When / Then)` exists as a passing test; rejection
|
|
183
201
|
scenarios assert the doc's named rejection reason.
|
|
184
202
|
- Alternate/error flows (idempotency included) are covered by tests.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: event-modeling-review
|
|
3
|
-
em-version: 1.
|
|
3
|
+
em-version: 1.13.1
|
|
4
4
|
description: >-
|
|
5
5
|
Use when starting em's live browser viewer (`em watch --serve`) so a team can watch a model
|
|
6
6
|
update in real time, or facilitating a SCHEDULED stakeholder walkthrough that steps through
|
|
@@ -39,6 +39,10 @@ screen. Use Prev/Next (or the left/right arrow keys) to step through slices in d
|
|
|
39
39
|
order — each one pans/zooms into view with everything else dimmed, so the room's attention
|
|
40
40
|
tracks one slice at a time.
|
|
41
41
|
|
|
42
|
+
**When a State View slice is on screen, ask who reads it (MIL-215):** a person or client in the
|
|
43
|
+
room → the `ui` should draw it; another system → `public`; only an automation → nothing, it's
|
|
44
|
+
internal by design and needs no endpoint.
|
|
45
|
+
|
|
42
46
|
**Live capture:** when a stakeholder raises something unresolved, add `issue "..."` to the
|
|
43
47
|
relevant element in the `.em` file and save — exactly the same mechanism `event-modeling-conform`
|
|
44
48
|
uses for any other issue. The browser updates over the existing SSE push within moments, without
|
|
@@ -49,17 +49,27 @@ em slice new <name> --pattern <pattern> # slice pattern: s
|
|
|
49
49
|
em slice new <name> --swimlane <swimlane> # swimlane, e.g. "Persona → Context"
|
|
50
50
|
em slice new <name> -f, --force # overwrite the file if it already exists
|
|
51
51
|
em slice new <name> --wire <model-file> # also insert the `note "slices/<key>.md"` line onto the slice's primary element in this .em file (matched by export key), instead of just printing it to paste by hand (MIL-161)
|
|
52
|
+
em slice new <name> --stub # write a near-free stub instead: same 5 frontmatter keys, but a one-line placeholder body instead of the diagram-image stub and every judgment section (MIL-184) — deepen it later by re-running without --stub and -f
|
|
53
|
+
em slice stub-all <file> # scaffold + wire a near-free stub (`em slice new --stub`'s content, MIL-184) for every slice in <file> with no resolvable doc — the fast path to status coloring for an exploratory/backbone model without hand-running `slice new` per slice. Skips a continuation slice (MIL-208, it has no doc of its own), an already-documented slice, and a slice whose pattern can't be classified
|
|
54
|
+
em slice stub-all <file> --status <status> # target status for every stub: draft | reviewed | ready-to-implement | implemented
|
|
55
|
+
em slice stub-all <file> --by <name> # identity for reviewedBy/ratifiedBy — required unless --status draft
|
|
56
|
+
em slice stub-all <file> --implemented-in <url> # PR/commit URL for implementedIn — required with --status implemented
|
|
57
|
+
em slice stub-all <file> --dry-run # list what would be stubbed/wired without writing anything
|
|
52
58
|
em slice index <file> # rewrite the model's sibling README.md's GENERATED Slices table from `em export`'s slice facts (key, pattern, doc status/implementedIn) — the hand-maintained table is deprecated
|
|
53
59
|
em slice index <file> --check # verify the table is current; exit non-zero on drift without writing (CI)
|
|
54
60
|
em slice mark-implemented <file> <slice-key> <pr-url> # flip a slice doc's frontmatter to `status: implemented` / `implementedIn: <pr-url>` — the one edit an implementing agent makes to a ratified doc at merge (MIL-103, replaces the em-sdd-bridge `em-sdd-mark-implemented` script; see reference/implement.md §6). Idempotent on the same URL; refuses to overwrite a different one; never touches `version:` or the doc body
|
|
55
61
|
em slice review <file> <slice-key> # flip a slice doc's frontmatter to `status: reviewed` and record `reviewedBy:`/`reviewedOn:` — the FIRST of the two human gates (MIL-201, docs/process.md#the-slice-lifecycle-gates): the room walked this slice and every open question it raised is resolved. Ratification is a separate, later gate (`em slice ratify`). Legal from `status: draft`; idempotent on the same --by/--on pair; refuses to overwrite a different one already recorded; refuses a doc already `ready-to-implement`/`implemented`; never touches `version:` or the doc body
|
|
56
62
|
em slice review <file> <slice-key> --by <name> # the reviewer's (or facilitator's) name
|
|
57
63
|
em slice review <file> <slice-key> --on <date> # review date, YYYY-MM-DD (default: today, local date)
|
|
58
|
-
em slice ratify <file> <slice-key> # flip a slice doc's frontmatter to `status: ready-to-implement` and record `ratifiedBy:`/`ratifiedOn:` — the handoff sign-off (MIL-165, docs/process.md#the-slice-lifecycle-gates) that makes who ratified, and when, a first-class recorded fact.
|
|
64
|
+
em slice ratify <file> <slice-key> # flip a slice doc's frontmatter to `status: ready-to-implement` and record `ratifiedBy:`/`ratifiedOn:` — the handoff sign-off (MIL-165, docs/process.md#the-slice-lifecycle-gates) that makes who ratified, and when, a first-class recorded fact. The review gate is a check on the doc's current `status:`, not on whether `reviewedBy:`/`reviewedOn:` are populated: a doc at `reviewed` or `ready-to-implement` passes (the latter is where `em slice reratify` leaves a doc, so the follow-up ratify needs no --skip-review); any other status — a `draft` that never went through `em slice review` — is refused unless --skip-review is passed. Idempotent on the same --by/--on pair; refuses to overwrite a different one already recorded; never touches `version:` or the doc body
|
|
59
65
|
em slice ratify <file> <slice-key> --by <name> # the ratifier's name
|
|
60
66
|
em slice ratify <file> <slice-key> --on <date> # ratification date, YYYY-MM-DD (default: today, local date)
|
|
61
67
|
em slice ratify <file> <slice-key> --skip-review # ratify without a recorded review — prints a loud notice on stderr
|
|
62
|
-
em slice reratify <file> <slice-key> # bump `version:` and flip a shipped slice doc's frontmatter back to `status: ready-to-implement` — the re-ratification mechanical edit (MIL-161, mirrors `em slice mark-implemented`).
|
|
68
|
+
em slice reratify <file> <slice-key> # bump `version:` and flip a shipped slice doc's frontmatter back to `status: ready-to-implement` — the re-ratification mechanical edit (MIL-161, mirrors `em slice mark-implemented`). Applies to a doc at `status: implemented`, or (MIL-258) to a `ready-to-implement` doc that is ratified but not yet shipped — there it bumps `version:` and clears the sign-off but leaves `status:` alone; a `ready-to-implement` doc with no `ratifiedBy:` refuses (awaiting `em slice ratify --by`). Clears any stale `ratifiedBy:`/`ratifiedOn:`/`reviewedBy:`/`reviewedOn:` (they describe the PRIOR version's review and sign-off) so a follow-up `em slice ratify --by` applies cleanly — and needs no fresh review; never touches `implementedIn:` or the doc body
|
|
69
|
+
em slice conform <file> <slice-key> # record per-slice-per-version conformance certification: sets `conformedVersion:`/`conformedAt:`/`conformedOn:` on a slice doc (MIL-214) — the fact `driftSignal: in-sync` now depends on. Legal only for `status: implemented` with an `implementedIn:` link. Idempotent on the same (version, --at) pair; a different --at simply overwrites (a later re-certification is normal — there's no way for em to tell 'later' from 'earlier' for an arbitrary revision string, so there's no --force to reach for). Refuses when the newest conformance/*-findings.json matching --at still has an unruled finding in scope for this slice; --skip-findings-check overrides with a loud notice.
|
|
70
|
+
em slice conform <file> <slice-key> --at <rev> # the target-repo revision this certification sweep diffed against
|
|
71
|
+
em slice conform <file> <slice-key> --on <date> # certification date, YYYY-MM-DD (default: today, local date)
|
|
72
|
+
em slice conform <file> <slice-key> --skip-findings-check # certify even with unruled findings in scope — prints a loud notice on stderr
|
|
63
73
|
em changelog <file> # render a model's git history as a business-readable ledger (see docs/cli.md)
|
|
64
74
|
em changelog <file> --from <rev> # start the walk at this revision (inclusive)
|
|
65
75
|
em changelog <file> --to <rev> # end the walk at this revision (inclusive; default HEAD)
|
|
@@ -67,21 +77,32 @@ em changelog <file> -o, --out <path> # write to a file
|
|
|
67
77
|
em state read [dir] # print the state file's mechanical fields as JSON
|
|
68
78
|
em state set-phase <phase> [dir] # rewrite Current phase: (and Last updated:); --step also rewrites Current step:
|
|
69
79
|
em state set-phase <phase> [dir] --step <n> # also set Current step: to this value
|
|
70
|
-
em state set-conformance <revision> [dir] # rewrite Last conformance: (and Last updated:) in the exact format reference/conform.md parses
|
|
80
|
+
em state set-conformance <revision> [dir] # rewrite Last conformance: (and Last updated:) in the exact format reference/conform.md parses. Refuses (MIL-214) while any `implemented` slice has an unruled conformance finding in the findings JSON beside --report (a `slice: null` finding blocks every slice); --partial records the marker with a ` (partial)` suffix instead, with a loud notice. Without a findings JSON beside --report: warns once and records the marker as given (migration path for a report predating `em conform-findings`)
|
|
71
81
|
em state set-conformance <revision> [dir] --report <path> # path to the conformance report just written
|
|
82
|
+
em state set-conformance <revision> [dir] --partial # record the marker as PARTIAL even though some in-scope findings are still unruled
|
|
72
83
|
em state set-review <date> [dir] # rewrite Last stakeholder review: (and Last updated:)
|
|
73
84
|
em state log-usage <file> # append one Usage log line — phase(s) touched + em validate's diagnostic categories hit, deduped and canonically formatted (MIL-161, docs/usage-data.md) — the mechanical half of 'save state at the end of every session' that used to be run-validate-then-hand-format; state file resolved next to <file>, same convention as em conform-scope
|
|
74
85
|
em state log-usage <file> --phases <list> # comma-separated phase(s) touched this session: discover, extract, model, slice, implement, conform, review, validate, watch
|
|
86
|
+
em model version bump <file> # bump the model's design version: write model-versions/v<N+1>.json (sibling of slices/, conformance/) and rewrite the state file's `Model version:` bullet (MIL-218). Refuses when the state file is missing (run `em scaffold` first), when --by is empty, and when nothing has changed since the current version (same model content hash AND same slice-version vector) unless --force — a no-op bump is the one case --force is right for.
|
|
87
|
+
em model version bump <file> --by <name> # the bumper's name
|
|
88
|
+
em model version bump <file> --on <date> # bump date, YYYY-MM-DD (default: today, local date)
|
|
89
|
+
em model version bump <file> --force # bump even though nothing has changed since the current version
|
|
90
|
+
em model version show <file> # print the model's current design version and the most recently certified version, if any (model-versions/*.json — MIL-218)
|
|
91
|
+
em model version show <file> --json # print a JSON document instead of text
|
|
75
92
|
em usage-report [root] # aggregate every .event-modeling.md's Usage log under [root] into phase/diagnostic-category tallies (MIL-161) — replaces docs/usage-data.md's hand-rolled grep/awk/sort pipeline; a logged line that doesn't match the canonical em state log-usage format is reported under unparseableLines rather than silently mistallied or dropped
|
|
76
93
|
em usage-report [root] --json # print a JSON document instead of the text report
|
|
77
94
|
em conform-scope <file> # mechanize conform phase step 1 (reference/conform.md): map the target repo's changed paths since Last conformance: to slices via each slice doc's implementedIn, JSON to stdout — --seed-asis also seeds the <model>-asis.em scratch model (see docs/cli.md)
|
|
78
95
|
em conform-scope <file> --repo <path> # path to (or inside) the target codebase's git repository
|
|
79
96
|
em conform-scope <file> --full # ignore Last conformance:/changed paths; scope every implemented slice
|
|
80
97
|
em conform-scope <file> --seed-asis # write <model>-asis.em as a byte copy of the canonical model and ensure it's gitignored
|
|
81
|
-
em conform-supersede <file> <report-path> # stamp a conformance report with a "superseded as of <rev>" banner once its findings have been ruled on (MIL-164, docs/process.md#what-ratified-means) — the companion step to run at ratification time so a reader following the report's file:line citations knows they describe an ancestor of the current model. Additive-only splice, never a rewrite of the report; idempotent on the same --as-of/--findings/--on stamp; refuses if the report doesn't exist
|
|
98
|
+
em conform-supersede <file> <report-path> # stamp a conformance report with a "superseded as of <rev>" banner once its findings have been ruled on (MIL-164, docs/process.md#what-ratified-means) — the companion step to run at ratification time so a reader following the report's file:line citations knows they describe an ancestor of the current model. Additive-only splice, never a rewrite of the report; idempotent on the same --as-of/--findings/--on stamp; refuses if the report doesn't exist. --locus/--by (MIL-214, both required together) additionally record the ruling itself — locus/resolvedBy/resolvedOn — on the findings named by --findings in the sibling conformance/<date>-findings.json, when one exists (warns once and stamps the banner only when it doesn't — the migration path for a report predating em conform-findings)
|
|
82
99
|
em conform-supersede <file> <report-path> --as-of <rev> # the revision this ruling was made against — same value passed to `em state set-conformance`
|
|
83
100
|
em conform-supersede <file> <report-path> --findings <spec> # which finding number(s) this stamps as ruled, e.g. "1-3" or "1,2,4"
|
|
84
101
|
em conform-supersede <file> <report-path> --on <date> # ruling date, YYYY-MM-DD (default: today, local date)
|
|
102
|
+
em conform-supersede <file> <report-path> --locus <locus> # who/what the named finding(s) say is wrong: model | doc | code | none (requires --by)
|
|
103
|
+
em conform-supersede <file> <report-path> --by <name> # who ruled on the named finding(s) (requires --locus)
|
|
104
|
+
em conform-findings check <path> # shape-validate a conformance/<date>-findings.json file (findingsSchemaVersion, required fields, enum values, ids sorted+unique, a ruled finding carries resolvedBy+resolvedOn) — exit 1 on shape errors. The conform skill writes this file directly alongside its report; this is how a headless run verifies what it just wrote.
|
|
105
|
+
em conform-findings check <path> --json # print a JSON document instead of the text report
|
|
85
106
|
em watch <file> # re-render on every save
|
|
86
107
|
em watch <file> -o, --out <path> # output path (extension picks the format)
|
|
87
108
|
em watch <file> -T, --format <fmt> # output format (svg, png, pdf, ...)
|
|
@@ -102,8 +123,9 @@ em ledger <file> --from <rev> # baseline revisio
|
|
|
102
123
|
em ledger <file> --to <rev> # compare revision (default: current working tree)
|
|
103
124
|
em ledger <file> --waive <slice-key> # excuse a doc-content-without-version-bump finding for this slice key (repeatable; MIL-185, see docs/cli.md) — never waives a version regression or bump-without-content-change
|
|
104
125
|
em ledger <file> --json # print a JSON document instead of the text report (see docs/cli.md)
|
|
105
|
-
em coverage <file> # check that every INV-* invariant ID cited in an implemented slice doc is cited by a test under --tests <dir> (MIL-130/MIL-207) — mechanizes reference/implement.md's definition-of-done citation check; advisory by default, --strict for CI; --include-ready also counts ready-to-implement docs (forward-looking report); a continuation slice (an `again` view instance with no doc of its own, MIL-208) is excluded from the report — its invariants, if any, live in the originating slice's own doc
|
|
126
|
+
em coverage <file> # check that every INV-* invariant ID cited in an implemented slice doc is cited by a test under --tests <dir> (MIL-130/MIL-207) — mechanizes reference/implement.md's definition-of-done citation check; advisory by default, --strict for CI; --include-ready also counts ready-to-implement docs (forward-looking report); a continuation slice (an `again` view instance with no doc of its own, MIL-208) is excluded from the report — its invariants, if any, live in the originating slice's own doc; --slice <key> scopes the report to one slice whatever its status (MIL-255), the pre-merge definition-of-done check
|
|
106
127
|
em coverage <file> --tests <dir> # directory to scan recursively for test files citing invariant IDs
|
|
128
|
+
em coverage <file> --slice <key> # only this slice (export key), whether ready-to-implement or implemented — no --include-ready needed; --strict then fails on this slice's uncited invariants, or if the slice is not in scope (draft/reviewed/unbound: nothing checked) (MIL-255)
|
|
107
129
|
em coverage <file> --strict # exit non-zero if any invariant ID has zero citations (CI)
|
|
108
130
|
em coverage <file> --include-ready # also count ready-to-implement docs, not just implemented (MIL-207)
|
|
109
131
|
em coverage <file> --json # print a JSON document instead of the text report (see docs/cli.md)
|
|
@@ -117,6 +139,10 @@ em status <files> -o, --out <path> # write output to
|
|
|
117
139
|
em freshness <file> # standalone freshness signal for one model's conformance record (MIL-164): "last conformed <rev> — N commits and M slice-PRs behind HEAD", computed from the same conform-scope machinery `em status`'s conformance clause uses — for when you want just this fact, no full state-of-the-system rollup (see docs/cli.md)
|
|
118
140
|
em freshness <file> --repo <path> # git repo to compute behind-HEAD in (default: the model's own directory)
|
|
119
141
|
em freshness <file> --json # print a JSON document instead of the text line
|
|
142
|
+
em metrics <file> # the pilot metrics named in advance by the register, computed from git history alone (MIL-170): ratification turnaround (reviewed -> ratified -> implemented), conform-cycle cadence + finding counts, and status-vs-reality disagreement over time — plus a fourth, reported as not computable from history (see docs/usage-data.md). `<file>` is an anchor .em file, used only to locate slices/, conformance/, and .event-modeling.md relative to it — same convention as em ledger; never parsed or compiled
|
|
143
|
+
em metrics <file> --from <rev> # baseline revision
|
|
144
|
+
em metrics <file> --to <rev> # compare revision (default: HEAD)
|
|
145
|
+
em metrics <file> --json # print a JSON document instead of the text report (see docs/cli.md)
|
|
120
146
|
em query consumers <files> # views/reactions consuming an event, plus their slices
|
|
121
147
|
em query consumers <files> --event <ref-or-name> # the event's export ref or display name
|
|
122
148
|
em query consumers <files> --json # print a JSON document instead of the text report
|
|
@@ -163,8 +189,12 @@ em skill check [path] # check the vendor
|
|
|
163
189
|
em skill check [path] --json # print a JSON document instead of the text report (see docs/cli.md)
|
|
164
190
|
em ci init <model> # install .github/workflows/em-ci.yml (PR gates: em validate, em slice index --check, em coverage --strict, em ledger, em skill check, em glossary --fail-on-conflicts, plus a push-triggered status-badge rebuild) and em-conform.yml (scheduled, advisory-only conformance cadence) — same install discipline as `em skill install`: marker-delimited, idempotent, --check for CI self-verification (MIL-166, see docs/ci.md)
|
|
165
191
|
em ci init <model> --tests <dir> # test directory the coverage/status steps scan for INV-* citations
|
|
166
|
-
em ci init <model> -f, --force # replace an existing workflow file that has no GENERATED markers
|
|
192
|
+
em ci init <model> -f, --force # replace an existing workflow file that has no GENERATED markers, or a managed block generated for a different model
|
|
167
193
|
em ci init <model> --check # verify both files match the current preset; exit non-zero on drift without writing (CI)
|
|
194
|
+
em upgrade <file> # bring a model repo authored under an older em (1.6 forward) up to the installed version: an ordered list of mechanical steps (skill bundle, reaction shape, state-file bullets, generated CI blocks, constitution scaffold) plus a human list of things no command can safely decide by itself (MIL-219, see docs/upgrading.md). Dry-run by default; --apply makes one git commit per applicable step, refusing on a dirty working tree
|
|
195
|
+
em upgrade <file> --apply # apply every applicable mechanical step, one git commit each, then a final `Em version:` commit
|
|
196
|
+
em upgrade <file> --check # exit non-zero only on a hard incompatibility (an existing but unparseable state file, an un-migratable .em shape) — writes nothing; what CI runs; the final line says why
|
|
197
|
+
em upgrade <file> --json # print a JSON document instead of text (dry-run/--check only, never with --apply)
|
|
168
198
|
```
|
|
169
199
|
<!-- GENERATED:cli:end -->
|
|
170
200
|
|
|
@@ -270,6 +300,14 @@ type Name { field: Type, ... } # named structured type, reusable from any f
|
|
|
270
300
|
this model). `em export` carries it as `public: true`/`false`; `em diff` reports a flip as
|
|
271
301
|
`event marked public`/`event unmarked public` (the entry cites the element's kind, so a
|
|
272
302
|
view flip reads `view "X"`); `em validate --list-public` audits the whole public surface.
|
|
303
|
+
**Exposure of a read model (MIL-215) is three cases, no dedicated keyword:** a person/client
|
|
304
|
+
reads it → draw the `ui` that reads it (ships the endpoint); another model/system reads it →
|
|
305
|
+
`public` (a cross-model contract, verified by `em system <manifest>`, not `em validate`); only
|
|
306
|
+
an automation reads it → nothing — internal by design, the read a reaction is required to
|
|
307
|
+
make, not an endpoint. `em validate --list-public` flags a `public` view with no `ui`/reaction
|
|
308
|
+
reading it anywhere in this model as an audit note ("no in-model reader"), not a warning — a
|
|
309
|
+
cross-model `public` view's reader legitimately lives outside this file (see "`em validate`
|
|
310
|
+
rules" below).
|
|
273
311
|
- **`tag`** (events only): declares a DCB (Dynamic Consistency Boundary) tag key. Three forms:
|
|
274
312
|
a trailing `tag` on a field line inside the event's `{ … }` block (`priceId: UUID tag`, or
|
|
275
313
|
typeless `priceId tag`) — an identity tag, key defaults to the field's own name; a bare field
|
|
@@ -681,6 +719,7 @@ not the prose above has caught up yet. `--slice-ready <key>`-only codes are excl
|
|
|
681
719
|
| `lineage-version-impossible` | error | Impossible lineage version | Fix the referenced version, or ratify the target slice first. |
|
|
682
720
|
| `loops-to-forward` | error | `loops-to` target not earlier on the timeline | Point `loops-to` at an earlier view, or use `from` on a later `view … again` instance instead. |
|
|
683
721
|
| `loops-to-unresolved` | error | `loops-to` target unresolved | Name a view that exists, or declare it before this event. |
|
|
722
|
+
| `model-version-stale` | warning | Model version stale | Run `em model version bump` to record the current model content/slice-version vector. |
|
|
684
723
|
| `note-binding-dangling` | warning | Dangling cross-slice note | Create the doc at that path, or fix/remove the note. |
|
|
685
724
|
| `note-binding-extra` | warning | Extra doc-binding note, ignored | Remove the note, or point it at the slice's actual bound doc. |
|
|
686
725
|
| `note-binding-unratified` | warning | Unratified cross-slice note | Add `covers: <this-slice-key>` to that doc's frontmatter, or correct the note's path. |
|
|
@@ -77,7 +77,17 @@ right here as `reference/slice-doc-schema.md` (kept in sync with the em repo's
|
|
|
77
77
|
|
|
78
78
|
1. Check the tool: `em --version`. If missing, tell the user to run `npm i -g @milehimikey/em`
|
|
79
79
|
and stop until installed.
|
|
80
|
-
2.
|
|
80
|
+
2. Check this vendored skill bundle's own currency (MIL-219): read this file's `em-version:`
|
|
81
|
+
frontmatter stamp (or any sibling skill's SKILL.md — they're stamped together) and compare it
|
|
82
|
+
to `em --version` from step 1. **If the installed em is ahead by a minor version or more
|
|
83
|
+
(1.9.x → 1.11.x, or any major bump), STOP** — don't proceed with discover/model/slice/
|
|
84
|
+
implement/conform/review work on this stamp. Tell the user the vendored bundle is stale and to
|
|
85
|
+
run `em skill sync` (refresh the bundle only) or `em upgrade` (the bundle plus the model
|
|
86
|
+
repo's other mechanical migrations, docs/upgrading.md) before continuing. A patch-only gap
|
|
87
|
+
(1.11.2 → 1.11.4) is never worth stopping over — proceed normally. This matters because a
|
|
88
|
+
stale bundle silently follows old rules: an agent reading superseded preconditions/gates
|
|
89
|
+
can hand back work that looks right by last week's contract and wrong by this week's.
|
|
90
|
+
3. Locate the model. Look for an existing `<dir>/.event-modeling.md` and `*.em` in the working
|
|
81
91
|
directory, or — for a multi-model project laid out per the convention below — one level down
|
|
82
92
|
inside a `models/` subfolder (each model gets its own `models/<slug>/` directory; check each
|
|
83
93
|
candidate for its own `.event-modeling.md`/`*.em` pair). If found, run `em state read <dir>`
|
|
@@ -85,12 +95,12 @@ right here as `reference/slice-doc-schema.md` (kept in sync with the em repo's
|
|
|
85
95
|
conformance, last review) as JSON — don't parse the bullets by hand. If not, and the phase
|
|
86
96
|
needs one, ask the user for the model name and where to create it (a lone model goes at the
|
|
87
97
|
project root; one of several goes under `models/`, per "Multi-model projects" below).
|
|
88
|
-
|
|
98
|
+
4. If you're not sure which phase applies, or the user gave no phase, use `em state read <dir>`'s
|
|
89
99
|
`phase`/`step` to resume the recorded phase/step — or invoke the `event-modeling` skill, which
|
|
90
100
|
does exactly this and routes to the right skill. If no model exists, propose starting
|
|
91
101
|
`discover` (greenfield, `event-modeling-discover`) or `extract` (modeling an existing system,
|
|
92
102
|
also `event-modeling-discover`).
|
|
93
|
-
|
|
103
|
+
5. Populate the state file's Participants section at session start. For a live workshop, ask for
|
|
94
104
|
a single human proxy to relay questions to the room, and attribute every answer/decision in
|
|
95
105
|
the Decisions log to a named participant.
|
|
96
106
|
|