@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.
- package/.claude/skills/event-modeling/SKILL.md +1 -1
- package/.claude/skills/event-modeling-conform/SKILL.md +5 -1
- package/.claude/skills/event-modeling-design/SKILL.md +31 -12
- package/.claude/skills/event-modeling-discover/SKILL.md +1 -1
- package/.claude/skills/event-modeling-implement/SKILL.md +14 -3
- package/.claude/skills/event-modeling-implement/reference/implement.md +73 -6
- package/.claude/skills/event-modeling-review/SKILL.md +14 -3
- package/.claude/skills/event-modeling-shared/reference/em-dsl.md +64 -10
- package/.claude/skills/event-modeling-shared/reference/slice-doc-schema.md +4 -1
- package/.claude/skills/event-modeling-shared/templates/constitution.md +111 -0
- package/.claude/skills/event-modeling-shared/templates/model-readme.md +2 -2
- package/.claude/skills/event-modeling-shared/templates/slice.md +4 -0
- package/dist/catalog/docJoin.d.ts +8 -0
- package/dist/catalog/docJoin.js +4 -0
- package/dist/catalog/docJoin.js.map +1 -1
- package/dist/catalog/sliceDoc.d.ts +8 -0
- package/dist/catalog/sliceDoc.js +2 -0
- package/dist/catalog/sliceDoc.js.map +1 -1
- package/dist/cli/ledgerCheck.d.ts +72 -0
- package/dist/cli/ledgerCheck.js +122 -1
- package/dist/cli/ledgerCheck.js.map +1 -1
- package/dist/cli/ratify.d.ts +37 -5
- package/dist/cli/ratify.js +106 -9
- package/dist/cli/ratify.js.map +1 -1
- package/dist/cli/reratify.js +14 -5
- package/dist/cli/reratify.js.map +1 -1
- package/dist/cli/review.d.ts +38 -0
- package/dist/cli/review.js +160 -0
- package/dist/cli/review.js.map +1 -0
- package/dist/cli/sliceIndex.d.ts +3 -0
- package/dist/cli/sliceIndex.js +5 -4
- package/dist/cli/sliceIndex.js.map +1 -1
- package/dist/cli/stateFile.d.ts +10 -0
- package/dist/cli/stateFile.js +14 -0
- package/dist/cli/stateFile.js.map +1 -1
- package/dist/cli/status.d.ts +44 -3
- package/dist/cli/status.js +75 -18
- package/dist/cli/status.js.map +1 -1
- package/dist/cli.js +142 -18
- package/dist/cli.js.map +1 -1
- package/dist/emit/freshnessJson.d.ts +1 -1
- package/dist/emit/freshnessJson.js +5 -1
- package/dist/emit/freshnessJson.js.map +1 -1
- package/dist/emit/json.d.ts +22 -1
- package/dist/emit/json.js +33 -2
- package/dist/emit/json.js.map +1 -1
- package/dist/emit/ledgerJson.d.ts +1 -1
- package/dist/emit/ledgerJson.js +6 -1
- package/dist/emit/ledgerJson.js.map +1 -1
- package/dist/emit/queryJson.d.ts +1 -1
- package/dist/emit/queryJson.js +5 -1
- package/dist/emit/queryJson.js.map +1 -1
- package/dist/emit/statusJson.d.ts +1 -1
- package/dist/emit/statusJson.js +5 -1
- package/dist/emit/statusJson.js.map +1 -1
- package/dist/mcp/server.js +10 -3
- package/dist/mcp/server.js.map +1 -1
- package/dist/model/edges.d.ts +18 -3
- package/dist/model/edges.js +34 -0
- package/dist/model/edges.js.map +1 -1
- package/dist/model/model.d.ts +4 -0
- package/dist/model/model.js +1 -0
- package/dist/model/model.js.map +1 -1
- package/dist/model/queryIndex.d.ts +5 -2
- package/dist/model/queryIndex.js +4 -1
- package/dist/model/queryIndex.js.map +1 -1
- package/dist/model/rules.d.ts +19 -0
- package/dist/model/rules.js +19 -0
- package/dist/model/rules.js.map +1 -1
- package/dist/model/validate.js +82 -1
- package/dist/model/validate.js.map +1 -1
- package/dist/parser/ast.d.ts +21 -0
- package/dist/parser/parser.js +96 -32
- package/dist/parser/parser.js.map +1 -1
- package/dist/render/drawEdges.js +7 -0
- package/dist/render/drawEdges.js.map +1 -1
- package/dist/render/drawNotes.d.ts +13 -3
- package/dist/render/drawNotes.js +96 -20
- package/dist/render/drawNotes.js.map +1 -1
- package/dist/render/render.js +6 -5
- package/dist/render/render.js.map +1 -1
- package/dist/templates.d.ts +14 -1
- package/dist/templates.js +134 -5
- package/dist/templates.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: event-modeling
|
|
3
|
-
em-version: 1.
|
|
3
|
+
em-version: 1.11.0
|
|
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
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: event-modeling-conform
|
|
3
|
-
em-version: 1.
|
|
3
|
+
em-version: 1.11.0
|
|
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
|
|
@@ -37,6 +37,10 @@ canonical model's names wherever the code matches them); run `em diff <model-nam
|
|
|
37
37
|
proposals the user ratifies, then re-render and validate; run `em state set-conformance
|
|
38
38
|
<revision> --report <path>` to update the state file's `Last conformance:` marker.
|
|
39
39
|
|
|
40
|
+
Ruling on a finding is a human gate, like ratifying a slice
|
|
41
|
+
(docs/process.md#the-slice-lifecycle-gates): the sweep gathers evidence and proposes, a person
|
|
42
|
+
decides, and `em state set-conformance` records the decision — never run it on your own judgment.
|
|
43
|
+
|
|
40
44
|
End of phase: state file's `Last conformance:` marker updated (via `em state set-conformance`),
|
|
41
45
|
Decisions log entry if any
|
|
42
46
|
proposals were applied. Conform doesn't chain to another phase — it's a recurring loop, run
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: event-modeling-design
|
|
3
|
-
em-version: 1.
|
|
3
|
+
em-version: 1.11.0
|
|
4
4
|
description: >-
|
|
5
5
|
Use when structuring a draft event model into swimlanes and the four patterns (State Change,
|
|
6
6
|
State View, Automation, Translation), evaluating a model's structural completeness, or writing
|
|
@@ -36,9 +36,19 @@ Goal: a structurally complete, **validated** model with correct patterns and swi
|
|
|
36
36
|
directly**. Add `translation` slices for external inputs (externally triggered: external →
|
|
37
37
|
translation → command → event, no slice before) and for the system reacting to its own state
|
|
38
38
|
(internally triggered: read model in the slice before → translation → command → event).
|
|
39
|
-
2. **Elaborate scenarios — first pass (step 6).**
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
2. **Elaborate scenarios — first pass (step 6).** Scaffold every slice's doc now, one per
|
|
40
|
+
slice, none skipped: `em slice new "<slice name>" --pattern <state-change|state-view|
|
|
41
|
+
automation|translation> --swimlane "<Persona> → <Context>" --wire <model>.em` writes
|
|
42
|
+
`slices/<slice-name>.md` at `status: draft` (the same command, flags, and `--wire`
|
|
43
|
+
note-binding the `slice` phase's step 2 below documents in full). Then, for each freshly
|
|
44
|
+
scaffolded doc, hold a first-pass Socratic pass and write the happy-path Given/When/Then into
|
|
45
|
+
its `## Scenarios (Given / When / Then)` section and the obvious invariants known so far into
|
|
46
|
+
its `## Invariants / Business Rules` section — **into the doc, never into the state file.**
|
|
47
|
+
Keep this pass shallow (no field tables, alternate/error flows, or NFRs yet — that's the full
|
|
48
|
+
deep-dive in the `slice` phase below); the docs are the home for everything collected from
|
|
49
|
+
here on, not yet implementation-ready specs. Because every doc already exists by the time the
|
|
50
|
+
`slice` phase begins, its own step 2 scaffolding call is then a no-op — that phase picks up
|
|
51
|
+
at its step 1's deeper pass.
|
|
42
52
|
3. **Evaluate completeness (step 7).** Walk the model: every slice is a **complete** pattern, not a
|
|
43
53
|
half-slice — **every command has something that triggers it**, every command emits an event,
|
|
44
54
|
**every event is read by a read model**, **every read model has a consumer**, every view has a
|
|
@@ -51,13 +61,19 @@ Goal: a structurally complete, **validated** model with correct patterns and swi
|
|
|
51
61
|
this fact and what they do with it. The honest answers are "here's the read model we missed" or
|
|
52
62
|
"nobody — so why are we recording it", and both improve the model.
|
|
53
63
|
|
|
54
|
-
End of phase: render, update state (`em state set-phase slice`
|
|
55
|
-
|
|
64
|
+
End of phase: render, update state (`em state set-phase slice` — the mechanical marker the state
|
|
65
|
+
machine expects), and stop. Every slice already has a draft doc ready to receive the deep spec,
|
|
66
|
+
but slicing is deliberate work the team starts when it's ready for it, not this phase's automatic
|
|
67
|
+
next step.
|
|
56
68
|
|
|
57
69
|
## Phase: `slice` — deep slice documents
|
|
58
70
|
|
|
59
|
-
Goal: implementation-ready specs. Go slice by slice
|
|
60
|
-
|
|
71
|
+
Goal: implementation-ready specs. Go slice by slice **in timeline order, starting with the first
|
|
72
|
+
slice on the storyboard** — never ask the user which slice to spec first, and never propose
|
|
73
|
+
starting with whichever slice looks highest-risk or most uncertain instead. Ratification
|
|
74
|
+
proceeds in the same order: later slices' scenarios and invariants depend on earlier slices'
|
|
75
|
+
events already being settled, so working out of order means re-litigating an earlier slice's
|
|
76
|
+
contract mid-spec. Check `README.md`'s Slices table for what's already done (run `em slice index
|
|
61
77
|
<model-name>.em` first if it looks stale).
|
|
62
78
|
|
|
63
79
|
This is also where **branch / unhappy-path events** are discovered and added to the model — as a
|
|
@@ -130,10 +146,13 @@ For each slice:
|
|
|
130
146
|
`implementedIn` once shipped). Never hand-edit the table; it's a generated block.
|
|
131
147
|
6. Re-render and `em validate`.
|
|
132
148
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
`
|
|
136
|
-
|
|
149
|
+
A finished draft doesn't become implementable here: it goes through the review gate and then the
|
|
150
|
+
ratification gate, both human, both outside this phase — see
|
|
151
|
+
`docs/process.md#the-slice-lifecycle-gates` for who runs which and in what order.
|
|
152
|
+
|
|
153
|
+
Before the project's first slice is implemented it also needs a ratified implementation
|
|
154
|
+
constitution (stack, code style, testing norms, NFR baselines, review norms) — the
|
|
155
|
+
`event-modeling-implement` skill elicits it, see its `reference/implement.md` §7.
|
|
137
156
|
|
|
138
157
|
End of phase: every slice that should exist has a doc, `README.md`'s Slices table is current,
|
|
139
158
|
and the model validates clean. Suggest `event-modeling-implement` for each ratified slice.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: event-modeling-discover
|
|
3
|
-
em-version: 1.
|
|
3
|
+
em-version: 1.11.0
|
|
4
4
|
description: >-
|
|
5
5
|
Use when starting a brand-new event model from scratch — greenfield discovery: brainstorming
|
|
6
6
|
past-tense events, storyboarding the happy path, finding the commands and read models — or when
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: event-modeling-implement
|
|
3
|
-
em-version: 1.
|
|
3
|
+
em-version: 1.11.0
|
|
4
4
|
description: >-
|
|
5
5
|
Use when building a single ratified event-modeling slice (status: ready-to-implement) into
|
|
6
6
|
merged, tested code — the one phase where the agent builds rather than facilitates. Gates on
|
|
@@ -15,19 +15,30 @@ the agent builds rather than facilitates.
|
|
|
15
15
|
|
|
16
16
|
**Read `reference/implement.md` before doing any implement work and follow it as the
|
|
17
17
|
contract.** In short: gate on `em validate <model>.em --slice-ready <key>` (stop and hand
|
|
18
|
-
back if it fails — never edit the doc to make the gate pass);
|
|
18
|
+
back if it fails — never edit the doc to make the gate pass); read the project's implementation
|
|
19
|
+
constitution before writing code and stay inside its rules; treat the slice doc as the
|
|
19
20
|
spec (read-only, except the merge-time `status`/`implementedIn` flip); surface every gap to
|
|
20
21
|
the user instead of deciding it silently; cover every `INV-<MNEMONIC>-n` and every scenario with
|
|
21
22
|
tests; in spec-kit projects, allocate via em-sdd-bridge (redirect mode) and never run
|
|
22
23
|
`/speckit.specify`.
|
|
23
24
|
|
|
25
|
+
**Gate: no constitution, no first slice.** The constitution is the project's ratified house rules
|
|
26
|
+
— stack and architectural shape (including which implementation skill each slice pattern routes
|
|
27
|
+
to), code style, testing norms, NFR baselines, review/merge norms. It lives at
|
|
28
|
+
`.specify/memory/constitution.md` in a spec-kit project, otherwise `constitution.md` beside the
|
|
29
|
+
model; `em status` reports which, and whether it's there. If it's missing — or its `ratifiedBy:`
|
|
30
|
+
is empty, meaning nobody has signed it off — run `reference/implement.md` §7 ("Before the first
|
|
31
|
+
slice: the constitution") first: ask its questions conversationally, write the answers in, and
|
|
32
|
+
have a human ratify them. Don't decide the project's stack or style yourself to get moving.
|
|
33
|
+
|
|
24
34
|
That contract applies to any implementing agent, whether or not the session started from
|
|
25
35
|
`/event-modeling` — `em contract` prints it to stdout with no `.claude/` awareness required, for
|
|
26
36
|
an agent that can run a shell but isn't Claude Code.
|
|
27
37
|
|
|
28
38
|
If the project ships pattern-specific implementation skills (for example an Axon/DCB skill set
|
|
29
39
|
keyed on a slice doc's `pattern:` frontmatter), route by the slice's pattern and follow those —
|
|
30
|
-
`reference/implement.md` §2 explains where that hand-off happens
|
|
40
|
+
`reference/implement.md` §2 explains where that hand-off happens, and the constitution's
|
|
41
|
+
routing table (§7) is what names the skill set for each pattern.
|
|
31
42
|
|
|
32
43
|
Preconditions (tool check, model location) are the same as every other phase — see
|
|
33
44
|
`../event-modeling-shared/reference/operating-principles.md` — but this phase additionally
|
|
@@ -41,7 +41,22 @@ implementation branch.
|
|
|
41
41
|
|
|
42
42
|
## 2. Read the spec
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
**First, read the project's constitution** — the house rules for *how* implementation happens
|
|
45
|
+
here (stack and architectural shape, which implementation skill each slice pattern routes to,
|
|
46
|
+
code style, testing norms, NFR baselines, review and merge norms). It lives in one of exactly two
|
|
47
|
+
places, never both:
|
|
48
|
+
|
|
49
|
+
- **spec-kit project** (a `.specify/` directory exists at or above the model):
|
|
50
|
+
`.specify/memory/constitution.md` — spec-kit's own slot, which em defers to.
|
|
51
|
+
- **anything else**: `constitution.md` beside the model, where `em scaffold` writes it.
|
|
52
|
+
|
|
53
|
+
`em status <model>.em --json` reports which one applies and whether it's there
|
|
54
|
+
(`conformance[].constitution`) — existence only; nothing in `em` reads or judges its content.
|
|
55
|
+
**Its rules bound every technical choice you make on this slice** (see §4). If it's missing, or
|
|
56
|
+
its `ratifiedBy:` is empty (spec-kit's file: the `**Ratified**:` footer still a placeholder),
|
|
57
|
+
it isn't ratified — go to §7 before writing code.
|
|
58
|
+
|
|
59
|
+
Then read `slices/<slice-key>.md` end to end — every section is load-bearing:
|
|
45
60
|
|
|
46
61
|
| Section | What it is to the implementer |
|
|
47
62
|
|---|---|
|
|
@@ -92,7 +107,10 @@ undocumented ordering, a contradiction with adjacent code. The discipline:
|
|
|
92
107
|
a business person could have an opinion on. Silent divergence is the failure mode the whole
|
|
93
108
|
conformance loop exists to catch — don't manufacture it.
|
|
94
109
|
- Purely technical choices with no behavioral surface (private naming, idiomatic structure,
|
|
95
|
-
which assertion library) are yours
|
|
110
|
+
which assertion library) are yours — **within the constitution's rules** (§2); anything
|
|
111
|
+
observable in behavior, data, or contract is not. If no constitution exists (or its
|
|
112
|
+
`ratifiedBy` is empty), surface that to the human and do not proceed on unilateral style or
|
|
113
|
+
stack decisions for a first slice: run the constitution step (§7) first.
|
|
96
114
|
|
|
97
115
|
## 5. Definition of done
|
|
98
116
|
|
|
@@ -104,7 +122,7 @@ undocumented ordering, a contradiction with adjacent code. The discipline:
|
|
|
104
122
|
- Alternate/error flows (idempotency included) are covered by tests.
|
|
105
123
|
- The build and full test suite are green; the model still validates (`em validate` in CI —
|
|
106
124
|
you didn't touch the `.em`, so this only fails if something else broke).
|
|
107
|
-
- Nothing between the slice doc and the code was committed as a source of truth (see §
|
|
125
|
+
- Nothing between the slice doc and the code was committed as a source of truth (see §8 —
|
|
108
126
|
work containers are ephemeral; generated or symlinked specs are renderings).
|
|
109
127
|
|
|
110
128
|
## 6. At merge: the lifecycle flip
|
|
@@ -131,7 +149,55 @@ Then, if the project keeps a model README (from `../../event-modeling-shared/tem
|
|
|
131
149
|
link — never hand-edit that table. The `implementedIn` link is what the `conform` phase later
|
|
132
150
|
uses to anchor drift-checking — leaving it empty blinds the loop.
|
|
133
151
|
|
|
134
|
-
## 7.
|
|
152
|
+
## 7. Before the first slice: the constitution
|
|
153
|
+
|
|
154
|
+
The first time this project's slices reach implementation — or any time §2 finds no constitution,
|
|
155
|
+
or one whose `ratifiedBy` is still empty — **stop and run this short conversation before writing
|
|
156
|
+
code.** It happens once per project, not once per slice.
|
|
157
|
+
|
|
158
|
+
Start from the template the skill bundle ships,
|
|
159
|
+
`../../event-modeling-shared/templates/constitution.md`. Each of its five sections opens with the
|
|
160
|
+
question to ask; ask them **conversationally, one section at a time**, and write the answers into
|
|
161
|
+
the document as you go — never fill a section by guessing, by reading the codebase and inferring
|
|
162
|
+
"what they probably do", or by pasting the template's own examples. Unanswerable questions get
|
|
163
|
+
parked in the document as open items, exactly like a slice doc's Open Questions:
|
|
164
|
+
|
|
165
|
+
1. **Stack and architectural shape** — languages/runtimes, frameworks, the architectural pattern,
|
|
166
|
+
where a slice's code lives, and the routing table: which implementation skill or approach each
|
|
167
|
+
of the four slice patterns uses (for example, State Change slices → the `axon-*` skill set).
|
|
168
|
+
That table is what you obey in §2 when you read a slice's `pattern:`.
|
|
169
|
+
2. **Code style** — formatter/linter, naming, module layout, and what "idiomatic" means here.
|
|
170
|
+
3. **Testing norms** — which test levels each pattern requires, where invariant and scenario
|
|
171
|
+
tests live, and the test-naming convention that lets `em coverage` trace `INV-<MNEMONIC>-n`
|
|
172
|
+
citations.
|
|
173
|
+
4. **NFR baselines** — authz model, PII handling, performance defaults, observability: the
|
|
174
|
+
standing defaults every slice inherits where its own `## Non-Functional Requirements` section
|
|
175
|
+
is silent.
|
|
176
|
+
5. **Review and merge norms** — who reviews, what blocks a merge, and who runs
|
|
177
|
+
`em slice mark-implemented` at merge (§6).
|
|
178
|
+
|
|
179
|
+
**A human ratifies it.** The answers are the project's, not yours — you drafted the wording, they
|
|
180
|
+
sign it off. In the em-native file that's the `ratifiedBy:`/`ratifiedOn:` frontmatter (a named
|
|
181
|
+
person and an ISO date, hand-filled — no `em` command writes this file, and an empty `ratifiedBy:`
|
|
182
|
+
means *draft*). In a spec-kit project it's that file's own `**Ratified**:` footer line — never add
|
|
183
|
+
frontmatter to spec-kit's document. Until it's ratified, treat it as a proposal: you may not
|
|
184
|
+
build a first slice on it.
|
|
185
|
+
|
|
186
|
+
**In a spec-kit project, merge — never duplicate.** The constitution IS
|
|
187
|
+
`.specify/memory/constitution.md`; em writes no second file and neither do you. Append em's five
|
|
188
|
+
sections to it under their own `##` headings, **leaving every existing section byte-untouched** —
|
|
189
|
+
including spec-kit's own `## Core Principles` and `## Governance`, and any principle a team
|
|
190
|
+
already wrote. If a heading of the same name is already there, add to it rather than replacing it,
|
|
191
|
+
and show the human the diff before writing. Two cautions: spec-kit's `/speckit.constitution`
|
|
192
|
+
command rewrites that whole file from its template, so run it (if at all) **before** this
|
|
193
|
+
conversation, never after — and never use it to author em's sections. If the file is still the
|
|
194
|
+
blank stock template (`[PROJECT_NAME]`, `[PRINCIPLE_1_NAME]`, … placeholders), say so: filling
|
|
195
|
+
spec-kit's own placeholders is the team's call, and em's sections go in alongside them either way.
|
|
196
|
+
|
|
197
|
+
`em status` will then report `constitution: present` for the model. That's the whole mechanical
|
|
198
|
+
check — em stores and locates this document, and never validates a word of it.
|
|
199
|
+
|
|
200
|
+
## 8. Spec-kit projects: the SDD adapter
|
|
135
201
|
|
|
136
202
|
If the repository uses spec-kit (a `.specify/` directory exists), do not hand-author spec-kit
|
|
137
203
|
artifacts — allocate through **em-sdd-bridge**, redirect mode preferred:
|
|
@@ -163,7 +229,7 @@ plan/tasks as FEATURE_SPEC. The rules that keep redirect mode safe:
|
|
|
163
229
|
No spec-kit (or any SDD tool)? Implement straight from the slice doc — it already contains
|
|
164
230
|
everything a spec holds. Don't introduce an intermediate spec document of your own.
|
|
165
231
|
|
|
166
|
-
##
|
|
232
|
+
## 9. Never do
|
|
167
233
|
|
|
168
234
|
| Rule | Because |
|
|
169
235
|
|---|---|
|
|
@@ -172,10 +238,11 @@ everything a spec holds. Don't introduce an intermediate spec document of your o
|
|
|
172
238
|
| Never edit the `.em` model | Model edits are ratified decisions — propose, don't write |
|
|
173
239
|
| Never bump `version:` | Versions move only with ratified deltas; see `em ledger` |
|
|
174
240
|
| Never silently decide unspecified behavior | Silent divergence is the disease the conformance loop exists to catch |
|
|
241
|
+
| Never invent the house rules a first slice needs (stack, style, testing, NFR defaults) | They're the project's decision, ratified in the constitution — §7, not your judgment call |
|
|
175
242
|
| Never regenerate merged code from the model | Generated-then-owned: post-merge code belongs to its owners |
|
|
176
243
|
| Never commit an authored intermediate spec | The slice is the spec; anything between it and the code is a rendering |
|
|
177
244
|
|
|
178
|
-
##
|
|
245
|
+
## 10. Afterward: the loop closes
|
|
179
246
|
|
|
180
247
|
Implementation isn't the end of the slice's story. On a cadence — or whenever someone asks —
|
|
181
248
|
the `conform` phase checks implemented slices against the code, using the `implementedIn` link
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: event-modeling-review
|
|
3
|
-
em-version: 1.
|
|
3
|
+
em-version: 1.11.0
|
|
4
4
|
description: >-
|
|
5
5
|
Use when starting em's live browser viewer (`em watch --serve`) so a team can watch a model
|
|
6
6
|
update in real time, or facilitating a SCHEDULED stakeholder walkthrough that steps through
|
|
@@ -49,8 +49,19 @@ walk each one with the user, same as any open issue. Update the state file's Par
|
|
|
49
49
|
section with who attended, and run `em state set-review <date>` to set the `Last stakeholder
|
|
50
50
|
review:` marker (mirrors `Last conformance:`).
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
**Per-slice outcome.** A slice whose open questions are all resolved in the room →
|
|
53
|
+
`em slice review <model>.em <key> --by <name>` (flips its doc to `status: reviewed` and records
|
|
54
|
+
`reviewedBy:`/`reviewedOn:`). Anything still open stays `draft` — the walkthrough doesn't decide
|
|
55
|
+
it, the next session or the open-questions list does.
|
|
56
|
+
|
|
57
|
+
**The facilitator never ratifies, never offers to ratify, and never suggests ratification in a
|
|
58
|
+
review session. Ratification is a separate human gate after review**
|
|
59
|
+
(docs/process.md#the-slice-lifecycle-gates). It is typically multi-person, routed through
|
|
60
|
+
CODEOWNERS on `slices/**`, and it is not this session's to run — `em slice ratify` will itself
|
|
61
|
+
refuse a doc that hasn't been through `em slice review`.
|
|
62
|
+
|
|
63
|
+
End of phase: state file's `Last stakeholder review:` marker updated, every walked slice whose
|
|
64
|
+
questions all closed moved to `status: reviewed`, every issue captured live triaged (resolved on the spot, moved to Open questions / parking lot, or left open on
|
|
54
65
|
purpose). Review doesn't chain to another phase — it's a recurring, scheduled activity like
|
|
55
66
|
`conform`, not a step in the discover → model → slice sequence.
|
|
56
67
|
|
|
@@ -15,7 +15,7 @@ Keep `.em` files focused on **structure**; put deep design in markdown linked vi
|
|
|
15
15
|
em --version # print the installed em version
|
|
16
16
|
em init [file] # scaffold a starter .em model
|
|
17
17
|
em init [file] -f, --force # overwrite if the file exists
|
|
18
|
-
em scaffold <name> # scaffold a full project: <slug>/<slug>.em, README.md, .event-modeling.md (see docs/cli.md — for just a starter .em, use `em init`; for a multi-model project, pass --under to nest it under a shared parent directory)
|
|
18
|
+
em scaffold <name> # scaffold a full project: <slug>/<slug>.em, README.md, .event-modeling.md, and constitution.md (the implementation constitution — skipped, with a note, in a spec-kit project, where `.specify/memory/constitution.md` IS that document) (see docs/cli.md — for just a starter .em, use `em init`; for a multi-model project, pass --under to nest it under a shared parent directory)
|
|
19
19
|
em scaffold <name> -f, --force # overwrite the directory's contents if it already exists
|
|
20
20
|
em scaffold <name> --under <dir> # parent directory to scaffold into — writes <dir>/<slug>/ instead of ./<slug>/, the supported multi-model layout (docs/cli.md, "Multi-model projects"): one directory per model, so each model's slices/ never collides with a sibling model's
|
|
21
21
|
em render <file> # transpile a model and render it (or emit DOT)
|
|
@@ -52,10 +52,14 @@ em slice new <name> --wire <model-file> # also insert the
|
|
|
52
52
|
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
53
|
em slice index <file> --check # verify the table is current; exit non-zero on drift without writing (CI)
|
|
54
54
|
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
|
-
em slice
|
|
55
|
+
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
|
+
em slice review <file> <slice-key> --by <name> # the reviewer's (or facilitator's) name
|
|
57
|
+
em slice review <file> <slice-key> --on <date> # review date, YYYY-MM-DD (default: today)
|
|
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. Refuses a doc that never passed the review gate (`em slice review`) 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
|
|
56
59
|
em slice ratify <file> <slice-key> --by <name> # the ratifier's name
|
|
57
60
|
em slice ratify <file> <slice-key> --on <date> # ratification date, YYYY-MM-DD (default: today)
|
|
58
|
-
em slice
|
|
61
|
+
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`). Only applies to a doc at `status: implemented`; 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
|
|
59
63
|
em changelog <file> # render a model's git history as a business-readable ledger (see docs/cli.md)
|
|
60
64
|
em changelog <file> --from <rev> # start the walk at this revision (inclusive)
|
|
61
65
|
em changelog <file> --to <rev> # end the walk at this revision (inclusive; default HEAD)
|
|
@@ -96,6 +100,7 @@ em migrate <file> --write # apply the rewrit
|
|
|
96
100
|
em ledger <file> # check slice docs' version: field agrees with their content across two git revisions (opt-in CI check, MIL-89 — never part of `em validate`, see docs/ci.md)
|
|
97
101
|
em ledger <file> --from <rev> # baseline revision
|
|
98
102
|
em ledger <file> --to <rev> # compare revision (default: current working tree)
|
|
103
|
+
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
|
|
99
104
|
em ledger <file> --json # print a JSON document instead of the text report (see docs/cli.md)
|
|
100
105
|
em coverage <file> # check that every INV-* invariant ID cited in a ready-to-implement/implemented slice doc is cited by a test under --tests <dir> (MIL-130) — mechanizes reference/implement.md's definition-of-done citation check; advisory by default, --strict for CI
|
|
101
106
|
em coverage <file> --tests <dir> # directory to scan recursively for test files citing invariant IDs
|
|
@@ -148,8 +153,8 @@ em system <manifest> # verify a seam ma
|
|
|
148
153
|
em system <manifest> --json # print a JSON document instead of the text report (see docs/cli.md)
|
|
149
154
|
em contract # print the packaged implementation contract (reference/implement.md) to stdout — the agent-neutral discovery path for any agent that can run a shell, not just Claude Code (MIL-129); see docs/cli.md
|
|
150
155
|
em mcp # start an MCP (Model Context Protocol) server over stdio (MIL-21) — a structured, agent-facing alternative to shelling out to `em`; see docs/mcp.md for the full, current tool table (the list changes as commands gain MCP parity, so it's not repeated here — MIL-187). Equivalent to running the `em-mcp` bin directly
|
|
151
|
-
em skill install # copy the event-modeling skill bundle into .claude/skills/ (event-modeling, event-modeling-discover/-design/-implement/-conform/-review, event-modeling-shared)
|
|
152
|
-
em skill install -f, --force # overwrite an existing installation
|
|
156
|
+
em skill install # copy the event-modeling skill bundle into .claude/skills/ (event-modeling, event-modeling-discover/-design/-implement/-conform/-review, event-modeling-shared); across a structural bundle change (e.g. the MIL-157 split of the old single event-modeling/ directory into this six-directory bundle), `em skill sync` is the migration path — --force now performs the same reconcile (MIL-180)
|
|
157
|
+
em skill install -f, --force # overwrite an existing installation, reconciling added/updated/removed files within the bundle's own managed directories the same way `em skill sync` does — never touching an unrelated sibling skill (MIL-180)
|
|
153
158
|
em skill install --no-agents-md # skip writing/updating the AGENTS.md agent-contract section (on by default, MIL-129)
|
|
154
159
|
em skill sync [path] # update the vendored .claude/skills/ event-modeling skill bundle in [path] to match the installed em package (overwrites unconditionally; local edits are never merged, MIL-93)
|
|
155
160
|
em skill sync [path] --no-agents-md # skip writing/updating the AGENTS.md agent-contract section (on by default, MIL-129)
|
|
@@ -195,7 +200,7 @@ type Name { field: Type, ... } # named structured type, reusable from any f
|
|
|
195
200
|
| `ui` | persona | screen / interface | `@Persona` | `note`, `issue`, `divergence`, `{ fields }` |
|
|
196
201
|
| `command` | API | state-changing request | — | `note`, `issue`, `divergence`, `renamed from`, `{ fields }` |
|
|
197
202
|
| `view` | API | read model / projection | — | `from "Event"…`, `note`, `issue`, `divergence`, `public`, `{ fields }` |
|
|
198
|
-
| `event` | context | recorded fact (past tense) | `@Context` | `note`, `issue`, `divergence`, `public`, `tag`, `renamed from`, field-level `assigned`, `{ fields }` |
|
|
203
|
+
| `event` | context | recorded fact (past tense) | `@Context` | `note`, `issue`, `divergence`, `public`, `tag`, `renamed from`, `loops-to`, field-level `assigned`, `{ fields }` |
|
|
199
204
|
| `processor` / `automation` / `saga` / `translation` | automation | system reaction / adapter | — | `from "…"`, `note`, `issue`, `divergence`, `{ fields }` |
|
|
200
205
|
|
|
201
206
|
### Clauses
|
|
@@ -220,6 +225,22 @@ type Name { field: Type, ... } # named structured type, reusable from any f
|
|
|
220
225
|
instance are what show the view changing. `again` with no earlier declaration is a validation error.
|
|
221
226
|
Use `again` (not a plain repeated `view` name) whenever the view is referenced by a
|
|
222
227
|
`from`/`arrow` — plain repeats are only warning-free while unreferenced.
|
|
228
|
+
- **`loops-to "View"`** (events only): marks an event as re-feeding an earlier read model — a
|
|
229
|
+
poll/retry loop where a later fact must re-trigger an automation that already ran (a lapsed
|
|
230
|
+
reservation re-notifying the next person waiting in line, and similar re-triggers). Written
|
|
231
|
+
after the event's name/`@Context`, either on the header line or trailing an
|
|
232
|
+
inline `{ fields }` block; repeatable (`loops-to "A" loops-to "B"`, or comma-joined). The
|
|
233
|
+
target must resolve to a `view` instance STRICTLY EARLIER on the timeline — the opposite of
|
|
234
|
+
`from`'s "nearest at-or-before" rule; pointing at the same slice or later is a validation
|
|
235
|
+
error naming `from` on a later `view … again` instance as the forward-flowing alternative,
|
|
236
|
+
and naming a view that doesn't exist is a separate unresolved-target error. A resolved
|
|
237
|
+
`loops-to` counts as the event being read for both-ends-of-a-flow completeness. **No arrow is
|
|
238
|
+
ever drawn** for it — drawing one backward would violate the timeline laws — instead the
|
|
239
|
+
event gets an indigo ↩ corner marker (bottom-left) and the legend gains a "Loops" section:
|
|
240
|
+
`↩ 1 <Event> re-feeds "<View>"` (the number identifies the event, not the target). `em
|
|
241
|
+
export` carries it as `loopsTo: { name, ref }[] | null` (`from`'s shape); `model.edges` gains
|
|
242
|
+
`{ from: <event ref>, to: <view ref>, source: "loops-to" }`; `em query`'s adjacency labels the
|
|
243
|
+
connection `"loops-to"` too, so `downstream`/`upstream` follow it (cycle-safely).
|
|
223
244
|
- **`note "path.md"`** on ANY element links a markdown doc. Relative to the `.em` file. Renders as
|
|
224
245
|
a clickable marker in SVG and a legend entry in PNG/PDF. **This is how slice docs attach.**
|
|
225
246
|
- **`issue "text"`** on ANY element flags an open question inline — the diagram-visible red
|
|
@@ -280,6 +301,25 @@ type Name { field: Type, ... } # named structured type, reusable from any f
|
|
|
280
301
|
`=== true` convention as `tag`. **Reach for this before echoing a server-set field onto the
|
|
281
302
|
command just to silence a fields-completeness warning** — that misrepresents what the client
|
|
282
303
|
actually sends.
|
|
304
|
+
- **`derived`** (view fields only, MIL-200): marks a field as computed from which events have
|
|
305
|
+
landed, rather than copied from a single source event's payload (a status stepping through
|
|
306
|
+
states as events arrive, a computed ordinal, an availability flag two events can flip).
|
|
307
|
+
Trails a field's type, or the bare name of a typeless field — bare `derived` (no traced
|
|
308
|
+
source) or traced `derived from "Event A", "Event B"` (the two-word form parsed before the
|
|
309
|
+
bare check, same discipline as `renamed from` vs. plain `from`). A field whose ENTIRE text is
|
|
310
|
+
just `derived` is a field named `derived`, not a clause. `derived`/`derived from` on a
|
|
311
|
+
command/event/`ui`/`type` field is a parse error. Excludes the field from
|
|
312
|
+
`fields-completeness/view-field-no-source` entirely (and thus from `--slice-ready`). The
|
|
313
|
+
traced form still checks something: every named event must resolve among the view's ACTUAL
|
|
314
|
+
sources (its own `from` list, or the same-slice events for a `from`-less view) — an
|
|
315
|
+
unresolved name is a validation error, `derived-from-unresolved`. `em export` carries it as
|
|
316
|
+
`derived: boolean` on the field (always present, same `=== true` convention as `tag`/
|
|
317
|
+
`assigned`) and `derivedFrom: string[] | null` (the traced event name(s), `null` on a bare
|
|
318
|
+
`derived` field). **Reach for this instead of dropping a computed field out of the `.em` and
|
|
319
|
+
into doc-only prose** — the marker keeps `em export`/the model aware the field exists (the
|
|
320
|
+
`doc-model-field-mismatch` doc↔model check does not compare view field tables at all today —
|
|
321
|
+
see the slice template's field-table guidance — so this is an export-side win specifically,
|
|
322
|
+
not yet a doc-drift check).
|
|
283
323
|
- **Fields:** `command Place Order { orderId: UUID, items: LineItem[], customerId }` — inline or
|
|
284
324
|
one-per-line. Types are free text (no semantic checking) UNLESS the type string names a
|
|
285
325
|
declared `type` (see Named types below), in which case it resolves to a structured
|
|
@@ -521,6 +561,14 @@ it to the slice that displays the read model, or drop it.
|
|
|
521
561
|
a ref naming a version higher than the target's own `version:`. A `split-from`/`merged-from`
|
|
522
562
|
naming a key absent from the tree is deliberately silent — that's the normal state after a
|
|
523
563
|
real split/merge (see the four `lineage-*` codes in the table below).
|
|
564
|
+
10. **`loops-to` not earlier, or unresolved** — an event's `loops-to "View"` naming a view at the
|
|
565
|
+
same slice or later (`loops-to-forward`; that's what `from` on a later `view … again`
|
|
566
|
+
instance is for), or naming a view that doesn't exist at all, or a name that resolves to a
|
|
567
|
+
non-view (`loops-to-unresolved`).
|
|
568
|
+
11. **`derived from` names an unresolved event** — a view field's traced `derived from "Event
|
|
569
|
+
A", "Event B"` clause naming an event that isn't among the view's actual sources (its own
|
|
570
|
+
`from` list, or the same-slice events for a `from`-less view) — `derived-from-unresolved`.
|
|
571
|
+
Name one of the view's real sources, or drop the traced event.
|
|
524
572
|
|
|
525
573
|
**Warnings (should fix):**
|
|
526
574
|
1. **Reaction with no command** — a `processor`/`automation`/`saga`/`translation` that triggers
|
|
@@ -537,9 +585,11 @@ it to the slice that displays the read model, or drop it.
|
|
|
537
585
|
5. **Event nobody reads** — the mirror of (4): recording an event no read model projects is a
|
|
538
586
|
write with no reader. Follow every write slice with the read slice that consumes its event.
|
|
539
587
|
Counts as read when a `view` names it in `from` (any `again` instance will do), when a view
|
|
540
|
-
with no `from` of its own sits in its slice,
|
|
541
|
-
|
|
542
|
-
`
|
|
588
|
+
with no `from` of its own sits in its slice, via an explicit `event -> view` arrow, or via a
|
|
589
|
+
resolved `loops-to "View"` clause (a loop-back is a real consumer too — an UNRESOLVED or
|
|
590
|
+
forward `loops-to` does not count, so the event still warns as unread alongside its own
|
|
591
|
+
`loops-to-forward`/`loops-to-unresolved` error). (Events marked `public` are exempt — their
|
|
592
|
+
reader is outside the model; same for a `public` view and the no-consumer warning.)
|
|
543
593
|
6. **Read model without source** — add `from "Event"` or place the view in a slice with an event.
|
|
544
594
|
7. **Duplicate name** — the same name defined N times; references resolve to the first. Rename.
|
|
545
595
|
(A duplicate `type` name always warns, unlike a duplicate element name — there's no
|
|
@@ -549,7 +599,8 @@ it to the slice that displays the read model, or drop it.
|
|
|
549
599
|
fail while any remain open.
|
|
550
600
|
9. **View field with no source** — a `view` field whose name matches no field on any instance
|
|
551
601
|
of its source events. Only checked once BOTH the view and at least one source event declare
|
|
552
|
-
`{ fields }
|
|
602
|
+
`{ fields }` — unless the field is marked `derived` (optionally `derived from "Event A",
|
|
603
|
+
"Event B"`, whose names must be among the view's sources), which exempts it entirely.
|
|
553
604
|
10. **Event field not from a command** — an `event` field whose name matches no field on any
|
|
554
605
|
command in the same slice. Only checked once BOTH the event and at least one same-slice
|
|
555
606
|
command declare `{ fields }`. This is the payoff of the fields feature for slicing rigor:
|
|
@@ -597,6 +648,7 @@ not the prose above has caught up yet. `--slice-ready <key>`-only codes are excl
|
|
|
597
648
|
| `connection-legality/illegal-pair` | error | Illegal connection | Only ui→command→event→view→ui and view→reaction→command are legal — the message names the missing step. |
|
|
598
649
|
| `cross-model-slice-doc-collision` | warning | Colliding slice doc path across models | Give each model its own directory (see docs/cli.md, "Multi-model projects"). |
|
|
599
650
|
| `dangling-public-event` | warning | Public event/view no seam consumes | Declare the seam that reads it, or drop `public` if nothing outside the model does. |
|
|
651
|
+
| `derived-from-unresolved` | error | `derived from` names an unknown event | Name one of the view's actual sources, or drop the traced event from `derived from`. |
|
|
600
652
|
| `doc-model-element-not-in-doc` | warning | Model element the doc doesn't mention | Add the matching marker to the doc, or remove the element from the model. |
|
|
601
653
|
| `doc-model-element-not-in-model` | warning | Doc names an element the model doesn't have | Add the element to the model, or fix/remove it in the doc. |
|
|
602
654
|
| `doc-model-field-mismatch` | warning | Doc/model field mismatch | Reconcile the field table with the model's fields — names and types. |
|
|
@@ -616,6 +668,8 @@ not the prose above has caught up yet. `--slice-ready <key>`-only codes are excl
|
|
|
616
668
|
| `lineage-ref-cycle` | error | Lineage cycle | Break the cycle — a slice can't be its own ancestor. |
|
|
617
669
|
| `lineage-ref-malformed` | error | Malformed lineage ref | Fix the value to `<slice-key>@v<N>`, or remove it. |
|
|
618
670
|
| `lineage-version-impossible` | error | Impossible lineage version | Fix the referenced version, or ratify the target slice first. |
|
|
671
|
+
| `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. |
|
|
672
|
+
| `loops-to-unresolved` | error | `loops-to` target unresolved | Name a view that exists, or declare it before this event. |
|
|
619
673
|
| `note-binding-dangling` | warning | Dangling cross-slice note | Create the doc at that path, or fix/remove the note. |
|
|
620
674
|
| `note-binding-extra` | warning | Extra doc-binding note, ignored | Remove the note, or point it at the slice's actual bound doc. |
|
|
621
675
|
| `note-binding-unratified` | warning | Unratified cross-slice note | Add `covers: <this-slice-key>` to that doc's frontmatter, or correct the note's path. |
|
|
@@ -56,13 +56,15 @@ to decide `frontmatter-invalid` without re-deriving frontmatter-shape rules of i
|
|
|
56
56
|
| `schemaVersion` | integer | `1` (current dialect version) | its *value* is not read back by any `em` command today (reserved) — but its *presence* is required by `hasUsableFrontmatter()`: a doc omitting it is `frontmatter-invalid` (see below) |
|
|
57
57
|
| `pattern` | string | `state-change` \| `state-view` \| `automation` \| `translation` | authored/informational only — `em catalog` and `em export` both derive pattern from the `.em` AST instead (`em export`'s `slice.pattern`, schema `1.4`) |
|
|
58
58
|
| `swimlane` | string | free text, `<Persona> → <Context>` | display-only |
|
|
59
|
-
| `status` | string, case-insensitive | `draft` \| `reviewed` \| `ready-to-implement` \| `implemented` | `em catalog`, `em render`/`em watch` header coloring; joined into `em export`'s `slice.doc.status` (schema `1.4`); paired with `implementedIn` to compute `slice.doc.driftSignal` (schema `1.5`, MIL-85) and `em validate`'s frontmatter-coherence check (MIL-85 — see [validation.md#frontmatter-coherence](https://github.com/milehimikey/em/blob/main/docs/validation.md#frontmatter-coherence)) |
|
|
59
|
+
| `status` | string, case-insensitive | `draft` \| `reviewed` \| `ready-to-implement` \| `implemented` | written by `em slice review` (→ `reviewed`, MIL-201), `em slice ratify`/`em slice reratify` (→ `ready-to-implement`) and `em slice mark-implemented` (→ `implemented`); read by `em catalog`, `em render`/`em watch` header coloring; joined into `em export`'s `slice.doc.status` (schema `1.4`); paired with `implementedIn` to compute `slice.doc.driftSignal` (schema `1.5`, MIL-85) and `em validate`'s frontmatter-coherence check (MIL-85 — see [validation.md#frontmatter-coherence](https://github.com/milehimikey/em/blob/main/docs/validation.md#frontmatter-coherence)) |
|
|
60
60
|
| `version` | integer | positive integer, starts at `1` | joined into `em export`'s `slice.doc.version` (schema `1.4`, MIL-91) |
|
|
61
61
|
| `implementedIn` | string | free text (PR/commit link) | joined into `em export`'s `slice.doc.implementedIn` (schema `1.4`, MIL-91); paired with `status` to compute `slice.doc.driftSignal` (schema `1.5`, MIL-85) and `em validate`'s frontmatter-coherence check (MIL-85 — see [validation.md#frontmatter-coherence](https://github.com/milehimikey/em/blob/main/docs/validation.md#frontmatter-coherence)) |
|
|
62
62
|
| `split-from` | single ref | `<slice-key>@v<N>` | joined into `em export`'s `slice.doc.splitFrom` (schema `1.4`, MIL-91) and `em diff`'s `slice-added` entries (schema `1.6`, MIL-84); current-tree referential checks by `em validate` (MIL-84 — see [validation.md#lineage](https://github.com/milehimikey/em/blob/main/docs/validation.md#lineage)) |
|
|
63
63
|
| `merged-from` | list of refs | comma-separated `<slice-key>@v<N>, ...` | joined into `em export`'s `slice.doc.mergedFrom` (schema `1.4`, MIL-91) and `em diff`'s `slice-added` entries (schema `1.6`, MIL-84); current-tree referential checks by `em validate` (MIL-84 — see [validation.md#lineage](https://github.com/milehimikey/em/blob/main/docs/validation.md#lineage)) |
|
|
64
64
|
| `superseded-by` | list of refs | comma-separated `<slice-key>@v<N>, ...` | joined into `em export`'s `slice.doc.supersededBy` (schema `1.4`, MIL-91) and `em diff`'s `slice-removed` entries (schema `1.6`, MIL-84); current-tree referential checks by `em validate` (MIL-84 — see [validation.md#lineage](https://github.com/milehimikey/em/blob/main/docs/validation.md#lineage)) |
|
|
65
65
|
| `covers` | list of slice keys | comma-separated `<slice-key>, ...` (plain keys — **not** the `<slice-key>@v<N>` ref grammar above) | ratifies a cross-slice binding (MIL-121 — see [Cross-slice coverage](#cross-slice-coverage-covers) below): read by `em export`'s doc join, `em validate --slice-ready`, and (best-effort) `em render`/`em watch`'s Slice Status legend |
|
|
66
|
+
| `reviewedBy` | string | free text (typically the facilitator's or reviewer's name) | written only by `em slice review` (MIL-201 — see [cli.md](https://github.com/milehimikey/em/blob/main/docs/cli.md#em-slice-review-file-slice-key---by-name)); joined into `em export`'s `slice.doc.reviewedBy` (schema `1.11`) and `em slice index`'s Reviewed by column |
|
|
67
|
+
| `reviewedOn` | string | `YYYY-MM-DD` | written only by `em slice review` (MIL-201); joined into `em export`'s `slice.doc.reviewedOn` (schema `1.11`) |
|
|
66
68
|
| `ratifiedBy` | string | free text (typically a person's name) | written only by `em slice ratify` (MIL-165 — see [cli.md](https://github.com/milehimikey/em/blob/main/docs/cli.md#em-slice-ratify-file-slice-key---by-name)); joined into `em export`'s `slice.doc.ratifiedBy` (schema `1.8`) and `em slice index`'s Ratified by column |
|
|
67
69
|
| `ratifiedOn` | string | `YYYY-MM-DD` | written only by `em slice ratify` (MIL-165); joined into `em export`'s `slice.doc.ratifiedOn` (schema `1.8`) |
|
|
68
70
|
| `owner` | string | free text (typically a person or team name) | hand-filled — no `em` command writes it; joined into `em export`'s `slice.doc.owner` (schema `1.9`, MIL-171), `em slice index`'s Owner column, and `em status`'s per-slice `owners[]` |
|
|
@@ -84,6 +86,7 @@ convention, not parser-enforced.
|
|
|
84
86
|
| `implementedIn` | optional | optional | optional | required once the slice has *ever* reached `implemented` — may still name a **prior** version's PR during re-ratification, see below |
|
|
85
87
|
| `split-from`, `merged-from`, `superseded-by` | optional in every state — present only on docs created by a split/merge, or on a doc that has been retired |
|
|
86
88
|
| `covers` | optional in every state — present only on a doc that deliberately also serves another slice (MIL-121, see below); most docs never carry it |
|
|
89
|
+
| `reviewedBy`, `reviewedOn` | optional in every state — present once `em slice review` (MIL-201) has run at least once; a doc that never went through the review gate, or was hand-flipped to `reviewed`, simply omits both. `em slice ratify` never clears them; `em slice reratify` does (they describe the version that shipped) |
|
|
87
90
|
| `ratifiedBy`, `ratifiedOn` | optional in every state — present once `em slice ratify` (MIL-165) has run at least once; a doc predating this feature, or ratified by hand, simply omits both |
|
|
88
91
|
| `owner`, `tracking` | optional in every state — hand-filled whenever a team wants a who-holds-this / external-tracker link; most docs never carry either (MIL-171) |
|
|
89
92
|
|