@milehimikey/em 1.8.1 → 1.9.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 +58 -404
- package/.claude/skills/event-modeling-conform/SKILL.md +77 -0
- package/.claude/skills/{event-modeling → event-modeling-conform}/reference/conform.md +39 -13
- package/.claude/skills/event-modeling-design/SKILL.md +139 -0
- package/.claude/skills/event-modeling-discover/SKILL.md +89 -0
- package/.claude/skills/{event-modeling → event-modeling-discover}/reference/extract.md +3 -2
- package/.claude/skills/event-modeling-implement/SKILL.md +40 -0
- package/.claude/skills/{event-modeling → event-modeling-implement}/reference/implement.md +3 -2
- package/.claude/skills/event-modeling-review/SKILL.md +58 -0
- package/.claude/skills/{event-modeling → event-modeling-shared}/reference/em-dsl.md +115 -83
- package/.claude/skills/{event-modeling → event-modeling-shared}/reference/methodology.md +6 -5
- package/.claude/skills/event-modeling-shared/reference/operating-principles.md +147 -0
- package/.claude/skills/{event-modeling → event-modeling-shared}/templates/model-readme.md +2 -2
- package/.claude/skills/{event-modeling → event-modeling-shared}/templates/slice.md +51 -8
- package/README.md +24 -4
- package/dist/catalog/build.js +9 -0
- package/dist/catalog/build.js.map +1 -1
- package/dist/catalog/docJoin.d.ts +15 -0
- package/dist/catalog/docJoin.js +8 -0
- package/dist/catalog/docJoin.js.map +1 -1
- package/dist/catalog/modelCollisionValidate.d.ts +22 -0
- package/dist/catalog/modelCollisionValidate.js +67 -0
- package/dist/catalog/modelCollisionValidate.js.map +1 -0
- package/dist/catalog/orphanedSliceDocValidate.d.ts +11 -0
- package/dist/catalog/orphanedSliceDocValidate.js +98 -0
- package/dist/catalog/orphanedSliceDocValidate.js.map +1 -0
- package/dist/catalog/sliceDoc.d.ts +15 -0
- package/dist/catalog/sliceDoc.js +18 -0
- package/dist/catalog/sliceDoc.js.map +1 -1
- package/dist/cli/changelogBuild.d.ts +12 -0
- package/dist/cli/changelogBuild.js +89 -0
- package/dist/cli/changelogBuild.js.map +1 -0
- package/dist/cli/ciInit.d.ts +42 -0
- package/dist/cli/ciInit.js +298 -0
- package/dist/cli/ciInit.js.map +1 -0
- package/dist/cli/conformSupersede.d.ts +32 -0
- package/dist/cli/conformSupersede.js +102 -0
- package/dist/cli/conformSupersede.js.map +1 -0
- package/dist/cli/coverage.d.ts +6 -1
- package/dist/cli/coverage.js +28 -3
- package/dist/cli/coverage.js.map +1 -1
- package/dist/cli/frontmatterSurgery.d.ts +28 -0
- package/dist/cli/frontmatterSurgery.js +66 -0
- package/dist/cli/frontmatterSurgery.js.map +1 -0
- package/dist/cli/markImplemented.js +6 -45
- package/dist/cli/markImplemented.js.map +1 -1
- package/dist/cli/ratify.d.ts +41 -0
- package/dist/cli/ratify.js +151 -0
- package/dist/cli/ratify.js.map +1 -0
- package/dist/cli/reratify.d.ts +33 -0
- package/dist/cli/reratify.js +137 -0
- package/dist/cli/reratify.js.map +1 -0
- package/dist/cli/skillCheck.d.ts +6 -0
- package/dist/cli/skillCheck.js +46 -0
- package/dist/cli/skillCheck.js.map +1 -1
- package/dist/cli/skillDirs.d.ts +15 -0
- package/dist/cli/skillDirs.js +34 -0
- package/dist/cli/skillDirs.js.map +1 -0
- package/dist/cli/skillSync.d.ts +10 -0
- package/dist/cli/skillSync.js +15 -0
- package/dist/cli/skillSync.js.map +1 -1
- package/dist/cli/sliceIndex.d.ts +3 -0
- package/dist/cli/sliceIndex.js +6 -2
- package/dist/cli/sliceIndex.js.map +1 -1
- package/dist/cli/sliceLink.d.ts +52 -0
- package/dist/cli/sliceLink.js +152 -0
- package/dist/cli/sliceLink.js.map +1 -0
- package/dist/cli/status.d.ts +261 -0
- package/dist/cli/status.js +536 -0
- package/dist/cli/status.js.map +1 -0
- package/dist/cli/usageLog.d.ts +75 -0
- package/dist/cli/usageLog.js +193 -0
- package/dist/cli/usageLog.js.map +1 -0
- package/dist/cli.js +501 -130
- package/dist/cli.js.map +1 -1
- package/dist/emit/freshnessJson.d.ts +6 -0
- package/dist/emit/freshnessJson.js +24 -0
- package/dist/emit/freshnessJson.js.map +1 -0
- package/dist/emit/json.d.ts +62 -8
- package/dist/emit/json.js +14 -3
- package/dist/emit/json.js.map +1 -1
- package/dist/emit/statusJson.d.ts +7 -0
- package/dist/emit/statusJson.js +39 -0
- package/dist/emit/statusJson.js.map +1 -0
- package/dist/emit/typespec.d.ts +26 -0
- package/dist/emit/typespec.js +356 -0
- package/dist/emit/typespec.js.map +1 -0
- package/dist/emit/usageReportJson.d.ts +3 -0
- package/dist/emit/usageReportJson.js +23 -0
- package/dist/emit/usageReportJson.js.map +1 -0
- package/dist/mcp/server.d.ts +1 -1
- package/dist/mcp/server.js +301 -11
- package/dist/mcp/server.js.map +1 -1
- package/dist/model/rules.d.ts +13 -0
- package/dist/model/rules.js +20 -0
- package/dist/model/rules.js.map +1 -1
- package/dist/templates.d.ts +1 -1
- package/dist/templates.js +2 -2
- package/dist/util/markers.d.ts +16 -4
- package/dist/util/markers.js +23 -10
- package/dist/util/markers.js.map +1 -1
- package/package.json +2 -1
- /package/.claude/skills/{event-modeling → event-modeling-shared}/templates/conformance-report.md +0 -0
- /package/.claude/skills/{event-modeling → event-modeling-shared}/templates/state.md +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- DSL behavior change? Update BOTH docs/dsl.md and .claude/skills/event-modeling/reference/em-dsl.md -->
|
|
1
|
+
<!-- DSL behavior change? Update BOTH docs/dsl.md and .claude/skills/event-modeling-shared/reference/em-dsl.md -->
|
|
2
2
|
|
|
3
3
|
# `em` DSL Reference & Cheatsheet
|
|
4
4
|
|
|
@@ -12,88 +12,118 @@ Keep `.em` files focused on **structure**; put deep design in markdown linked vi
|
|
|
12
12
|
|
|
13
13
|
<!-- GENERATED:cli:start -- run `npm run docs:generate` to refresh, do not hand-edit -->
|
|
14
14
|
```bash
|
|
15
|
-
em --version
|
|
16
|
-
em init [file]
|
|
17
|
-
em init [file] -f, --force
|
|
18
|
-
em scaffold <name>
|
|
19
|
-
em scaffold <name> -f, --force
|
|
20
|
-
em
|
|
21
|
-
em render <file>
|
|
22
|
-
em render <file> -
|
|
23
|
-
em render <file> --
|
|
24
|
-
em render <file> --
|
|
25
|
-
em render <file> --
|
|
26
|
-
em
|
|
27
|
-
em export <file>
|
|
28
|
-
em export <file> --
|
|
29
|
-
em
|
|
30
|
-
em
|
|
31
|
-
em
|
|
32
|
-
em diff <old> [new]
|
|
33
|
-
em diff <old> [new] --
|
|
34
|
-
em
|
|
35
|
-
em
|
|
36
|
-
em
|
|
37
|
-
em glossary <files>
|
|
38
|
-
em glossary <files> --
|
|
39
|
-
em
|
|
40
|
-
em
|
|
41
|
-
em
|
|
42
|
-
em catalog <files>
|
|
43
|
-
em catalog <files>
|
|
44
|
-
em
|
|
45
|
-
em
|
|
46
|
-
em
|
|
47
|
-
em slice new <name> -
|
|
48
|
-
em slice
|
|
49
|
-
em slice
|
|
50
|
-
em slice
|
|
51
|
-
em
|
|
52
|
-
em
|
|
53
|
-
em
|
|
54
|
-
em
|
|
55
|
-
em
|
|
56
|
-
em
|
|
57
|
-
em
|
|
58
|
-
em
|
|
59
|
-
em
|
|
60
|
-
em
|
|
61
|
-
em
|
|
62
|
-
em
|
|
63
|
-
em
|
|
64
|
-
em
|
|
65
|
-
em
|
|
66
|
-
em
|
|
67
|
-
em
|
|
68
|
-
em
|
|
69
|
-
em
|
|
70
|
-
em
|
|
71
|
-
em
|
|
72
|
-
em
|
|
73
|
-
em
|
|
74
|
-
em
|
|
75
|
-
em
|
|
76
|
-
em
|
|
77
|
-
em
|
|
78
|
-
em
|
|
79
|
-
em
|
|
80
|
-
em
|
|
81
|
-
em
|
|
82
|
-
em
|
|
83
|
-
em
|
|
84
|
-
em
|
|
85
|
-
em
|
|
86
|
-
em
|
|
87
|
-
em
|
|
88
|
-
em
|
|
89
|
-
em
|
|
90
|
-
em
|
|
91
|
-
em
|
|
92
|
-
em
|
|
93
|
-
em
|
|
94
|
-
em
|
|
95
|
-
em
|
|
96
|
-
em
|
|
15
|
+
em --version # print the installed em version
|
|
16
|
+
em init [file] # scaffold a starter .em model
|
|
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)
|
|
19
|
+
em scaffold <name> -f, --force # overwrite the directory's contents if it already exists
|
|
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
|
+
em render <file> # transpile a model and render it (or emit DOT)
|
|
22
|
+
em render <file> -o, --out <path> # output path (extension picks the format)
|
|
23
|
+
em render <file> -T, --format <fmt> # output format (svg, png, pdf, ...)
|
|
24
|
+
em render <file> --slice <name> # render only this slice, redrawn in its own canonical pattern shape (default out: slices/<kebab-slug>.svg)
|
|
25
|
+
em render <file> --emit-dot # print the generated DOT instead of rendering
|
|
26
|
+
em render <file> --keep-empty-lanes # keep the API lane even when empty
|
|
27
|
+
em export <file> # export a versioned JSON snapshot of the normalized model
|
|
28
|
+
em export <file> -o, --out <path> # write to a file instead of stdout
|
|
29
|
+
em export <file> --slice <key> # export only this slice's object (pattern/fields/doc) instead of the whole model (export key, MIL-128) — refuses only if THIS slice has an error; an unrelated slice's breakage elsewhere in the model doesn't block it (see docs/cli.md)
|
|
30
|
+
em typespec <file> # EXPERIMENTAL/POC (MIL-159): generate a TypeSpec contract for a model's commands, public events, and public views (see docs/cli.md)
|
|
31
|
+
em typespec <file> -o, --out <path> # write to a file instead of stdout
|
|
32
|
+
em diff <old> [new] # compare two models structurally (two files, or one file across git revisions)
|
|
33
|
+
em diff <old> [new] --from <rev> # diff <old> against this git revision instead of a second file
|
|
34
|
+
em diff <old> [new] --to <rev> # diff against this git revision instead of the current file (requires --from)
|
|
35
|
+
em diff <old> [new] --exit-code # exit 1 if the models differ, 0 if identical (git-diff convention)
|
|
36
|
+
em diff <old> [new] --json # print a JSON document instead of the text report (see docs/cli.md)
|
|
37
|
+
em glossary <files> # cross-model glossary of terms, with consistency checks across models (see docs/cli.md)
|
|
38
|
+
em glossary <files> --json # print the full glossary document instead of the text report
|
|
39
|
+
em glossary <files> -o, --out <path> # write the JSON document to a file instead of stdout (requires --json)
|
|
40
|
+
em glossary <files> --list-conflicts # print only the conflict lines, no summary
|
|
41
|
+
em glossary <files> --fail-on-conflicts # exit non-zero if any cross-model term conflicts were found (opt-in — conflicts are warnings and don't block by default)
|
|
42
|
+
em catalog <files> # generate a browsable static HTML catalog site over one or more .em models (see docs/cli.md)
|
|
43
|
+
em catalog <files> -o, --out <dir> # output directory
|
|
44
|
+
em catalog <files> -T, --format <fmt> # diagram format embedded in the catalog (svg or png)
|
|
45
|
+
em catalog <files> --title <text> # catalog site title
|
|
46
|
+
em catalog <files> --keep-empty-lanes # keep the API lane even when empty
|
|
47
|
+
em slice new <name> # scaffold a fresh slices/<key>.md doc — the 5 frontmatter keys required at `status: draft` plus the `# Slice:` heading and diagram-image stub; judgment sections (Intent, Scenarios, Open Questions, ...) stay hand-authored (see docs/slice-doc-schema.md, templates/slice.md)
|
|
48
|
+
em slice new <name> --pattern <pattern> # slice pattern: state-change | state-view | automation | translation
|
|
49
|
+
em slice new <name> --swimlane <swimlane> # swimlane, e.g. "Persona → Context"
|
|
50
|
+
em slice new <name> -f, --force # overwrite the file if it already exists
|
|
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 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
|
+
em slice index <file> --check # verify the table is current; exit non-zero on drift without writing (CI)
|
|
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 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#what-ratified-means) that makes who ratified, and when, a first-class recorded fact. Idempotent on the same --by/--on pair; refuses to overwrite a different one already recorded; never touches `version:` or the doc body
|
|
56
|
+
em slice ratify <file> <slice-key> --by <name> # the ratifier's name
|
|
57
|
+
em slice ratify <file> <slice-key> --on <date> # ratification date, YYYY-MM-DD (default: today)
|
|
58
|
+
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:` (they describe the PRIOR version's sign-off) so a follow-up `em slice ratify --by` applies cleanly; never touches `implementedIn:` or the doc body
|
|
59
|
+
em changelog <file> # render a model's git history as a business-readable ledger (see docs/cli.md)
|
|
60
|
+
em changelog <file> --from <rev> # start the walk at this revision (inclusive)
|
|
61
|
+
em changelog <file> --to <rev> # end the walk at this revision (inclusive; default HEAD)
|
|
62
|
+
em changelog <file> -o, --out <path> # write to a file instead of stdout
|
|
63
|
+
em state read [dir] # print the state file's mechanical fields as JSON
|
|
64
|
+
em state set-phase <phase> [dir] # rewrite Current phase: (and Last updated:); --step also rewrites Current step:
|
|
65
|
+
em state set-phase <phase> [dir] --step <n> # also set Current step: to this value
|
|
66
|
+
em state set-conformance <revision> [dir] # rewrite Last conformance: (and Last updated:) in the exact format reference/conform.md parses
|
|
67
|
+
em state set-conformance <revision> [dir] --report <path> # path to the conformance report just written
|
|
68
|
+
em state set-review <date> [dir] # rewrite Last stakeholder review: (and Last updated:)
|
|
69
|
+
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
|
|
70
|
+
em state log-usage <file> --phases <list> # comma-separated phase(s) touched this session: discover, extract, model, slice, implement, conform, review, validate, watch
|
|
71
|
+
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
|
|
72
|
+
em usage-report [root] --json # print a JSON document instead of the text report
|
|
73
|
+
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)
|
|
74
|
+
em conform-scope <file> --repo <path> # path to (or inside) the target codebase's git repository
|
|
75
|
+
em conform-scope <file> --full # ignore Last conformance:/changed paths; scope every implemented slice
|
|
76
|
+
em conform-scope <file> --seed-asis # write <model>-asis.em as a byte copy of the canonical model and ensure it's gitignored
|
|
77
|
+
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
|
|
78
|
+
em conform-supersede <file> <report-path> --as-of <rev> # the revision this ruling was made against — same value passed to `em state set-conformance`
|
|
79
|
+
em conform-supersede <file> <report-path> --findings <spec> # which finding number(s) this stamps as ruled, e.g. "1-3" or "1,2,4"
|
|
80
|
+
em conform-supersede <file> <report-path> --on <date> # ruling date, YYYY-MM-DD (default: today)
|
|
81
|
+
em watch <file> # re-render on every save
|
|
82
|
+
em watch <file> -o, --out <path> # output path (extension picks the format)
|
|
83
|
+
em watch <file> -T, --format <fmt> # output format (svg, png, pdf, ...)
|
|
84
|
+
em watch <file> --keep-empty-lanes # keep the API lane even when empty
|
|
85
|
+
em watch <file> --serve # serve a live viewer with instant push-reload (no polling)
|
|
86
|
+
em watch <file> --port <n> # port for --serve (default 5173)
|
|
87
|
+
em validate <file> # check a model against event-modeling rules
|
|
88
|
+
em validate <file> --list-issues # print only open `issue` diagnostics (slice, element, line, text)
|
|
89
|
+
em validate <file> --list-divergences # print only accepted-divergence annotations (slice, element, line, text) — never fails the build
|
|
90
|
+
em validate <file> --list-public # print only events and views marked `public` (slice, kind, name, line) — an integration-surface audit, never fails the build
|
|
91
|
+
em validate <file> --fail-on-issues # exit non-zero if the model has any open `issue`s (opt-in — issues are warnings and don't block by default)
|
|
92
|
+
em validate <file> --slice-ready <key> # readiness gate for one slice (export key): status ready-to-implement, doc resolvable via note binding, zero unchecked Open Questions — exits non-zero if not ready (MIL-87)
|
|
93
|
+
em validate <file> --json # print a JSON document instead of text — works on a model WITH errors, unlike `em export` (MIL-128, see docs/cli.md); exit codes are unchanged
|
|
94
|
+
em migrate <file> # rewrite the old two-slice Automation/Translation shape into the merged single-slice shape MIL-120 made canonical (see docs/cli.md)
|
|
95
|
+
em migrate <file> --write # apply the rewrite to the file (default: dry run — report only, write nothing)
|
|
96
|
+
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
|
+
em ledger <file> --from <rev> # baseline revision
|
|
98
|
+
em ledger <file> --to <rev> # compare revision (default: current working tree)
|
|
99
|
+
em ledger <file> --json # print a JSON document instead of the text report (see docs/cli.md)
|
|
100
|
+
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
|
+
em coverage <file> --tests <dir> # directory to scan recursively for test files citing invariant IDs
|
|
102
|
+
em coverage <file> --strict # exit non-zero if any invariant ID has zero citations (CI)
|
|
103
|
+
em coverage <file> --json # print a JSON document instead of the text report (see docs/cli.md)
|
|
104
|
+
em status <files> # deterministic state-of-the-system rollup over one or more .em models: slices by lifecycle status, driftSignal breakdown, invariant coverage totals (with --tests), open issue markers + unchecked Open Questions, and last-conformance commits-behind-HEAD (MIL-163, see docs/cli.md)
|
|
105
|
+
em status <files> --tests <dir> # directory to scan for INV-* test citations — enables invariant coverage totals
|
|
106
|
+
em status <files> --repo <path> # git repo to compute commits-behind-HEAD in (default: each model's own directory)
|
|
107
|
+
em status <files> --json # print a JSON document instead of the text report (see docs/cli.md)
|
|
108
|
+
em status <files> --md # print a markdown block suited for README embedding
|
|
109
|
+
em status <files> --badge # print a generated SVG badge
|
|
110
|
+
em status <files> -o, --out <path> # write output to a file instead of stdout
|
|
111
|
+
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)
|
|
112
|
+
em freshness <file> --repo <path> # git repo to compute behind-HEAD in (default: the model's own directory)
|
|
113
|
+
em freshness <file> --json # print a JSON document instead of the text line
|
|
114
|
+
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
|
|
115
|
+
em mcp # start an MCP (Model Context Protocol) server over stdio, exposing validate/slice_ready/list_markers/export_model/export_slice/coverage/contract as tools (MIL-21) — a structured, agent-facing alternative to shelling out to `em`; see docs/mcp.md. Equivalent to running the `em-mcp` bin directly
|
|
116
|
+
em skill install # copy the event-modeling skill bundle into .claude/skills/ (event-modeling, event-modeling-discover/-design/-implement/-conform/-review, event-modeling-shared)
|
|
117
|
+
em skill install -f, --force # overwrite an existing installation
|
|
118
|
+
em skill install --no-agents-md # skip writing/updating the AGENTS.md agent-contract section (on by default, MIL-129)
|
|
119
|
+
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)
|
|
120
|
+
em skill sync [path] --no-agents-md # skip writing/updating the AGENTS.md agent-contract section (on by default, MIL-129)
|
|
121
|
+
em skill check [path] # check the vendored .claude/skills/ event-modeling skill bundle in [path] for drift against the installed em package; exits non-zero on any mismatch (CI-ready, MIL-93)
|
|
122
|
+
em skill check [path] --json # print a JSON document instead of the text report (see docs/cli.md)
|
|
123
|
+
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)
|
|
124
|
+
em ci init <model> --tests <dir> # test directory the coverage/status steps scan for INV-* citations
|
|
125
|
+
em ci init <model> -f, --force # replace an existing workflow file that has no GENERATED markers
|
|
126
|
+
em ci init <model> --check # verify both files match the current preset; exit non-zero on drift without writing (CI)
|
|
97
127
|
```
|
|
98
128
|
<!-- GENERATED:cli:end -->
|
|
99
129
|
|
|
@@ -530,6 +560,7 @@ not the prose above has caught up yet. `--slice-ready <key>`-only codes are excl
|
|
|
530
560
|
| `both-ends-of-a-flow/ui-unbacked` | warning | `ui` with no read model or command | Add a `view` it displays, or the command it triggers. |
|
|
531
561
|
| `both-ends-of-a-flow/view-unconsumed` | warning | Read model with no consumer | Add a `ui` or reaction that consumes it, or drop this instance. |
|
|
532
562
|
| `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. |
|
|
563
|
+
| `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"). |
|
|
533
564
|
| `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. |
|
|
534
565
|
| `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. |
|
|
535
566
|
| `doc-model-field-mismatch` | warning | Doc/model field mismatch | Reconcile the field table with the model's fields — names and types. |
|
|
@@ -553,6 +584,7 @@ not the prose above has caught up yet. `--slice-ready <key>`-only codes are excl
|
|
|
553
584
|
| `note-binding-unratified` | warning | Unratified cross-slice note | Add `covers: <this-slice-key>` to that doc's frontmatter, or correct the note's path. |
|
|
554
585
|
| `note-binding-unusable` | warning | Cross-slice note to a doc with unusable frontmatter | Fix that doc's frontmatter, or fix/remove the note. |
|
|
555
586
|
| `open-issue` | warning | Open issue | Resolve the question, then remove the `issue` clause. |
|
|
587
|
+
| `orphaned-slice-doc` | warning | Orphaned slice doc | Rename it to a current slice's key, add `covers:` (plus a `note` binding) to attach it to a live slice, or delete it. |
|
|
556
588
|
| `reaction-from-future-view` | error | Backward timeline (reaction reads a future view) | Declare the view in or before the reaction's slice. |
|
|
557
589
|
| `reaction-from-unresolved` | error | Unknown read-model source | Project the event into a view first, or fix the `from` reference. |
|
|
558
590
|
| `tag-composite-unknown-field` | error | Composite tag names an unknown field | Fix the field name, or add it to the event's fields. |
|
|
@@ -213,9 +213,10 @@ state change anyone can think of. No commands, no UI yet — just facts.
|
|
|
213
213
|
User Clicked Button, User Viewed Page, User Logged In.
|
|
214
214
|
- Model the process the business **needs**, not how the current system happens to work. Existing
|
|
215
215
|
system behavior is a common source of fake events — screens and tables leaking in as facts.
|
|
216
|
-
(**Extract mode inverts this**: in the skill's `extract` phase the
|
|
217
|
-
subject and this caution is deliberately suspended — see the
|
|
218
|
-
`reference/extract.md`. The
|
|
216
|
+
(**Extract mode inverts this**: in the `event-modeling-discover` skill's `extract` phase the
|
|
217
|
+
existing system *is* the subject and this caution is deliberately suspended — see the
|
|
218
|
+
"Extract" section below and `event-modeling-discover`'s own `reference/extract.md`. The
|
|
219
|
+
derived-value and telemetry filters still apply there.)
|
|
219
220
|
- Output: a flat list of candidate `event` names.
|
|
220
221
|
|
|
221
222
|
### Step 2 — The Plot / Storyboard *(discover)*
|
|
@@ -251,7 +252,7 @@ or automation never records an event directly; it triggers a command.
|
|
|
251
252
|
### Step 6 — Elaborate Scenarios *(model first pass, slice deep pass)*
|
|
252
253
|
For each slice, write **Given / When / Then** scenarios and surface **invariants**, **critical
|
|
253
254
|
fields**, and **alternate / error flows**. In the `model` phase do a light first pass; the
|
|
254
|
-
dedicated `slice` phase writes the full rich spec (see
|
|
255
|
+
dedicated `slice` phase writes the full rich spec (see `../templates/slice.md`).
|
|
255
256
|
- Prompts: *"Given what starting state, when this command/trigger fires, then what event(s)
|
|
256
257
|
result? What must always be true? What are the failure paths? Which fields are essential and
|
|
257
258
|
what are their rules?"*
|
|
@@ -311,7 +312,7 @@ Desired-state improvements belong to the `model` and `slice` phases, after the a
|
|
|
311
312
|
agreed.
|
|
312
313
|
|
|
313
314
|
Procedure, source modes (event-driven vs. procedural synthesis), and the round-by-round loop:
|
|
314
|
-
`reference/extract.md`.
|
|
315
|
+
the `event-modeling-discover` skill's own `reference/extract.md`.
|
|
315
316
|
|
|
316
317
|
---
|
|
317
318
|
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# Operating principles, preconditions, and project layout (every phase)
|
|
2
|
+
|
|
3
|
+
Shared by every `event-modeling-*` skill. Read this before doing any work in any phase — it's
|
|
4
|
+
the discipline and mechanics that don't change no matter which phase you're facilitating.
|
|
5
|
+
`methodology.md` (the 7 steps + 4 patterns) and `em-dsl.md` (DSL syntax and validation rules) in
|
|
6
|
+
this same directory are the other two shared references; read them too before doing real work —
|
|
7
|
+
they, together with this doc, are the source of truth every phase skill builds on. Templates
|
|
8
|
+
live in `templates/`, a sibling of this `reference/` directory. References to `docs/*.md`
|
|
9
|
+
throughout these skills mean the
|
|
10
|
+
[em repository's docs](https://github.com/milehimikey/em/tree/main/docs) — they are not
|
|
11
|
+
vendored alongside these skills.
|
|
12
|
+
|
|
13
|
+
## Operating principles
|
|
14
|
+
|
|
15
|
+
- **Socratic, one question at a time.** Ask focused questions; use `AskUserQuestion` for tight
|
|
16
|
+
multiple-choice decisions. Never assume a domain fact — extract it. Prefer "who/why/what-if/
|
|
17
|
+
what-must-always-be-true/how-do-you-know" over yes-no.
|
|
18
|
+
- **Don't guess — park it.** Unresolved items go into the Open Questions list in
|
|
19
|
+
`.event-modeling.md`, not into invented model content. Note the source, blocker, and revisit
|
|
20
|
+
date when known — cheap now, useful when you come back to it.
|
|
21
|
+
- **Happy path first; branches belong to slicing.** Steps 1-7 build the **happy-path spine**.
|
|
22
|
+
Alternate, unhappy, and exception-path events (rejections, removals, cancellations,
|
|
23
|
+
expirations, declines) are **not** enumerated as a separate discover/model task — they
|
|
24
|
+
surface during the `slice` phase as each slice's alternate/error flows and rule-boundary
|
|
25
|
+
scenarios, and any new branch events get added to the `.em` then. Never list "draft the
|
|
26
|
+
branch events" as a discover/model to-do or ask the user to do it before slicing.
|
|
27
|
+
- **Reflect and re-render.** After each meaningful increment, update the `.em` file, re-render,
|
|
28
|
+
and show the user what changed. Encourage running the live view (`watch`) so a team can follow.
|
|
29
|
+
- **Keep the `.em` structural; put depth in `note` docs.** The diagram holds flow; invariants,
|
|
30
|
+
fields, and scenarios live in `slices/*.md` linked via `note "slices/<name>.md"`.
|
|
31
|
+
- **Headless/API models still use `ui`.** If the system is headless (clients call an API, not
|
|
32
|
+
screens), declare a persona per external caller/role (e.g. `IntegratorAPI`) and treat its `ui`
|
|
33
|
+
boxes as API calls, not screens: writes are `ui → command → event` and reads are
|
|
34
|
+
`read model → ui`, exactly like any other State Change/State View slice — no separate trigger
|
|
35
|
+
slice. `translation` stays reserved for genuine reactions and real external-system boundaries,
|
|
36
|
+
not a synchronous request/response call. Internal-only commands/views with no public route carry
|
|
37
|
+
no `ui` at all — they follow the ordinary Automation pattern instead. **Repeat read models**
|
|
38
|
+
across slices so the timeline flows left-to-right — put each repeat **right after the event that feeds it**, sourcing
|
|
39
|
+
only that one adjacent event, so every arrow is short (a read model far from its source events
|
|
40
|
+
draws a long arrow whose head lands columns away, making the *write* slice read as dangling —
|
|
41
|
+
keep a sub-flow that detours into another context together, not parked at the end of the model).
|
|
42
|
+
Declare every instance after the first with
|
|
43
|
+
**`view X again from "..."`** — `again` instances are exempt from the duplicate-name warning even
|
|
44
|
+
when referenced, and each reference resolves to the right instance. A reaction's command is
|
|
45
|
+
wired by same-slice presence, exactly like `ui → command` — no positional/adjacency rule to get
|
|
46
|
+
right (see `em-dsl.md`).
|
|
47
|
+
See `methodology.md` (State View) and `em-dsl.md`.
|
|
48
|
+
- **Never connect two instances of one read model.** The repeat is a timeline device, not a flow:
|
|
49
|
+
continuity is implied by the shared name, and the events arriving at each instance are what show
|
|
50
|
+
it changing. An arrow between instances says the read model feeds itself, and is an error.
|
|
51
|
+
- **Every slice is a COMPLETE pattern, never a half-slice.** A State Change is
|
|
52
|
+
`ui → command → event`; a State View is `event → read model → ui` (or `→ reaction`). So: a
|
|
53
|
+
command needs something that **triggers** it (the `ui` it's issued from, or the reaction that
|
|
54
|
+
triggers it, also in this slice), its event needs a **reader**, and that read model needs a
|
|
55
|
+
**consumer** of its own. A command nothing points at is a write nobody can start; a reaction
|
|
56
|
+
that triggers no command is a decision the system never acts on; an event nothing projects is
|
|
57
|
+
a write nobody can see; a read model nothing displays is information dropped on the floor.
|
|
58
|
+
Write the whole chain together rather than sweeping up dangling ends later. Reactions don't
|
|
59
|
+
count as readers of *events* — they read views. **Every instance** of a repeated read model
|
|
60
|
+
needs its own consumer: if you repeat a view next to an event just to keep the arrow short,
|
|
61
|
+
bring its screen along, or don't add the instance.
|
|
62
|
+
- **Only six connections are legal:** `ui → command`, `command → event`, `event → read model`,
|
|
63
|
+
`read model → ui`, `read model → reaction`, `reaction → command`. Reaching for anything else —
|
|
64
|
+
above all `command → read model` (the CQRS violation) or `read model → command` — means the model
|
|
65
|
+
is missing an **element**, not an arrow.
|
|
66
|
+
- **Validate continuously.** Run `em validate` and fix errors/warnings as you go (see DSL ref).
|
|
67
|
+
- **Save state at the end of every session** so work resumes cleanly. Also log a Usage log
|
|
68
|
+
line: `em state log-usage <model>.em --phases <phase1,phase2,...>` computes and dedupes the
|
|
69
|
+
diagnostic *categories* that fired for you and appends the canonically-formatted line — never
|
|
70
|
+
hand-run `em validate --json` and format the line yourself. This is the team's only usage
|
|
71
|
+
signal today (`docs/usage-data.md`) — keep it cheap and habitual, not a task to skip.
|
|
72
|
+
|
|
73
|
+
## Preconditions (run first)
|
|
74
|
+
|
|
75
|
+
1. Check the tool: `em --version`. If missing, tell the user to run `npm i -g @milehimikey/em`
|
|
76
|
+
and stop until installed.
|
|
77
|
+
2. Locate the model. Look for an existing `<dir>/.event-modeling.md` and `*.em` in the working
|
|
78
|
+
directory, or — for a multi-model project laid out per the convention below — one level down
|
|
79
|
+
inside a `models/` subfolder (each model gets its own `models/<slug>/` directory; check each
|
|
80
|
+
candidate for its own `.event-modeling.md`/`*.em` pair). If found, run `em state read <dir>`
|
|
81
|
+
to read the state file's mechanical fields (model path, phase, step, last updated, last
|
|
82
|
+
conformance, last review) as JSON — don't parse the bullets by hand. If not, and the phase
|
|
83
|
+
needs one, ask the user for the model name and where to create it (a lone model goes at the
|
|
84
|
+
project root; one of several goes under `models/`, per "Multi-model projects" below).
|
|
85
|
+
3. If you're not sure which phase applies, or the user gave no phase, use `em state read <dir>`'s
|
|
86
|
+
`phase`/`step` to resume the recorded phase/step — or invoke the `event-modeling` skill, which
|
|
87
|
+
does exactly this and routes to the right skill. If no model exists, propose starting
|
|
88
|
+
`discover` (greenfield, `event-modeling-discover`) or `extract` (modeling an existing system,
|
|
89
|
+
also `event-modeling-discover`).
|
|
90
|
+
4. Populate the state file's Participants section at session start. For a live workshop, ask for
|
|
91
|
+
a single human proxy to relay questions to the room, and attribute every answer/decision in
|
|
92
|
+
the Decisions log to a named participant.
|
|
93
|
+
|
|
94
|
+
## Project layout these skills create
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
<model-name>/
|
|
98
|
+
<model-name>.em # the model (slice docs linked via note "...")
|
|
99
|
+
<model-name>.svg # render target for em watch
|
|
100
|
+
README.md # overview + slice index (from templates/model-readme.md)
|
|
101
|
+
.event-modeling.md # resumable state (from templates/state.md)
|
|
102
|
+
slices/<slice-name>.md # one rich slice doc per slice (from templates/slice.md)
|
|
103
|
+
conformance/<date>-report.md
|
|
104
|
+
# conform-phase reports (from templates/conformance-report.md)
|
|
105
|
+
<model-name>-asis.em # conform-phase scratch model, regenerated per run — git-ignore this
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
When creating a new model, run `em scaffold <model-name>` — it creates `<model-name>/` and
|
|
109
|
+
writes all three starter files in one step (`<model-name>.em`, `README.md`,
|
|
110
|
+
`.event-modeling.md`), filling the Model Name/model-name placeholders and the state file's
|
|
111
|
+
mechanical fields (model path, `Current phase: discover`, `Current step: 1`, dates) for you, so
|
|
112
|
+
there's nothing left to hand-copy or fill in. Refuses if `<model-name>/` already exists; pass
|
|
113
|
+
`--force` to overwrite. You'll
|
|
114
|
+
usually replace the scaffolded `.em`'s content as the discovery conversation builds up the real
|
|
115
|
+
model — it starts out as the same starter model `em init` writes, titled from `<model-name>`.
|
|
116
|
+
`slices/*.md` and `conformance/` aren't part of `em scaffold`; they come from the `slice` and
|
|
117
|
+
`conform` phases (`event-modeling-design` and `event-modeling-conform`). The `conformance/`
|
|
118
|
+
directory and `<model-name>-asis.em` only appear once the `conform` phase runs; `em conform-scope
|
|
119
|
+
--seed-asis` creates `<model-name>-asis.em` and gitignores `*-asis.em` for you (see
|
|
120
|
+
`event-modeling-conform`'s `reference/conform.md`) — it's scratch, never committed.
|
|
121
|
+
|
|
122
|
+
### Multi-model projects
|
|
123
|
+
|
|
124
|
+
Slice docs resolve at a fixed path — `slices/<slug>.md`, sibling of the `.em` file that
|
|
125
|
+
declares the slice — with no model namespace anywhere, so **one directory per model** is the
|
|
126
|
+
whole guardrail against two models' slice names colliding. For more than one model, nest each
|
|
127
|
+
one's directory (the exact layout above) under a shared `models/` parent instead of scattering
|
|
128
|
+
them at the project root:
|
|
129
|
+
|
|
130
|
+
```
|
|
131
|
+
models/
|
|
132
|
+
checkout/
|
|
133
|
+
checkout.em
|
|
134
|
+
slices/...
|
|
135
|
+
fulfillment/
|
|
136
|
+
fulfillment.em
|
|
137
|
+
slices/...
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Run `em scaffold <model-name> --under models` for each model — it creates `models/<slug>/`
|
|
141
|
+
directly rather than a two-step `cd models && em scaffold <model-name>`. See
|
|
142
|
+
[docs/cli.md, "Multi-model projects"](https://github.com/milehimikey/em/blob/main/docs/cli.md#multi-model-projects)
|
|
143
|
+
for the full rationale, and why slice keys stay unqualified (no `<model>/<slice>` prefix) —
|
|
144
|
+
directory isolation alone is sufficient. Two `.em` files sharing a directory with colliding
|
|
145
|
+
slice keys don't go undetected: `em status`/`em catalog`, the two commands that ever compile
|
|
146
|
+
more than one model in a run, raise a `cross-model-slice-doc-collision` warning naming both
|
|
147
|
+
files — treat that warning as a sign the models need separating, not a false positive.
|
|
@@ -37,8 +37,8 @@ never connected to one another.
|
|
|
37
37
|
`em slice index {{model-name}}.em` to (re)write the table below from the model and its
|
|
38
38
|
slice docs; never hand-edit between the markers. -->
|
|
39
39
|
<!-- GENERATED:slices:start -->
|
|
40
|
-
| # | Slice | Pattern | Status | Implemented in | Design doc |
|
|
41
|
-
|
|
40
|
+
| # | Slice | Pattern | Status | Ratified by | Owner | Tracking | Implemented in | Design doc |
|
|
41
|
+
|---|-------|---------|--------|-------------|-------|----------|----------------|------------|
|
|
42
42
|
<!-- GENERATED:slices:end -->
|
|
43
43
|
|
|
44
44
|
## Status
|
|
@@ -35,6 +35,17 @@ to write up. Delete it otherwise; most docs never carry it. Requires a matching
|
|
|
35
35
|
`note "slices/{{this-slice-name}}.md"` on an element in the OTHER slice — this key alone doesn't
|
|
36
36
|
bind anything. Plain slice keys, comma-separated — not the `<slice-key>@v<N>` ref grammar above.
|
|
37
37
|
|
|
38
|
+
`ratifiedBy`/`ratifiedOn` record who ratified this doc's current `status`/`version`, and when —
|
|
39
|
+
don't hand-fill these; run `em slice ratify <model>.em {{this-slice-name}} --by "<name>"` at the
|
|
40
|
+
handoff gate instead (docs/process.md#what-ratified-means), which flips `status` to
|
|
41
|
+
`ready-to-implement` and writes both in one edit.
|
|
42
|
+
|
|
43
|
+
`owner`/`tracking` are optional and, unlike `ratifiedBy`/`ratifiedOn`, hand-filled — no `em`
|
|
44
|
+
command writes either. `owner` is free text naming who (a person or team) holds this slice;
|
|
45
|
+
`tracking` is a URL into an external tracker (Jira, Linear, ...) mirroring it — the exact field
|
|
46
|
+
`em-tracker-bridge` reads to find the mirrored ticket. `em` only stores and displays both; it
|
|
47
|
+
never talks to a tracker itself. Delete both otherwise; most docs never carry them.
|
|
48
|
+
|
|
38
49
|
Full machine schema — required-vs-optional keys per `status`, value types/enums, the
|
|
39
50
|
unknown-key policy — is documented in docs/slice-doc-schema.md.
|
|
40
51
|
|
|
@@ -59,6 +70,9 @@ implementedIn: {{PR/commit link — fill in once status is `implemented`}}
|
|
|
59
70
|
# (e.g. the view-only half of a two-slice Automation/Translation, MIL-121); delete otherwise.
|
|
60
71
|
# Plain slice keys, comma-separated. See docs/slice-doc-schema.md#cross-slice-coverage-covers.
|
|
61
72
|
# covers: <slice-key>, <slice-key>
|
|
73
|
+
# Ownership / tracking — optional, hand-filled (no `em` command writes either); delete otherwise.
|
|
74
|
+
# owner: <person or team>
|
|
75
|
+
# tracking: <ticket URL>
|
|
62
76
|
---
|
|
63
77
|
# Slice: {{Slice Name}}
|
|
64
78
|
|
|
@@ -81,7 +95,9 @@ implementedIn: {{PR/commit link — fill in once status is `implemented`}}
|
|
|
81
95
|
#### Requirement: {{title}} ({{stable ID, e.g. an INV-{{MNEMONIC}}-n from Invariants below}})
|
|
82
96
|
{{requirement text — same voice as an Invariants entry}}
|
|
83
97
|
##### Scenario: {{name}}
|
|
84
|
-
- **
|
|
98
|
+
- **Given:** {{...}}
|
|
99
|
+
- **When:** {{...}}
|
|
100
|
+
- **Then:** {{...}}
|
|
85
101
|
|
|
86
102
|
### Modified
|
|
87
103
|
<!-- Same shape as Added — the stable ID names the requirement that changed. -->
|
|
@@ -146,16 +162,33 @@ an event directly.}}
|
|
|
146
162
|
`INV-<MNEMONIC>-<n>`, where `<MNEMONIC>` is a short (2-4 letter/digit), slice-unique
|
|
147
163
|
abbreviation of this slice's key (e.g. slice `checkout` -> `INV-CHK-1`) — see
|
|
148
164
|
docs/slice-doc-schema.md. Add a letter suffix for a closely-related sub-invariant
|
|
149
|
-
(`INV-CHK-3a`).
|
|
165
|
+
(`INV-CHK-3a`). Keep the rule statement itself to one line. If it needs more — why the rule
|
|
166
|
+
exists, what "violation" looks like in practice, an edge case worth calling out — add that as
|
|
167
|
+
a nested bullet under the rule instead of one long run-on sentence: this section renders as
|
|
168
|
+
HTML (`em catalog`/`em render`/`em watch`), and a nested bullet stays visually distinct where
|
|
169
|
+
a wrapped sentence collapses into a wall of text. The ID must stay on the rule's own
|
|
170
|
+
top-level bullet line — `em coverage` extracts INV IDs from that line only, never from a
|
|
171
|
+
nested elaboration bullet underneath it. -->
|
|
150
172
|
- **INV-{{MNEMONIC}}-1:** {{rule that the command enforces; violation ⇒ rejection}}
|
|
173
|
+
- {{optional: rationale, edge-case detail, or what "violation" means here — its own bullet}}
|
|
151
174
|
- **INV-{{MNEMONIC}}-2:** {{...}}
|
|
152
175
|
|
|
153
176
|
## Scenarios (Given / When / Then)
|
|
154
|
-
<!-- The executable specification. Cover the happy path AND the key rule boundaries.
|
|
155
|
-
-
|
|
156
|
-
|
|
157
|
-
- **
|
|
158
|
-
- **
|
|
177
|
+
<!-- The executable specification. Cover the happy path AND the key rule boundaries. Each
|
|
178
|
+
scenario is a case-label bullet with Given/When/Then as nested sub-bullets — not one run-on
|
|
179
|
+
sentence — so the case reads as distinct beats once rendered instead of a dense paragraph. -->
|
|
180
|
+
- **Happy path**
|
|
181
|
+
- **Given:** {{starting state / prior events}}
|
|
182
|
+
- **When:** {{command/trigger}}
|
|
183
|
+
- **Then:** {{event(s) recorded}} and {{resulting read-model change}}.
|
|
184
|
+
- **Rejected (INV-{{MNEMONIC}}-1)**
|
|
185
|
+
- **Given:** {{state}}
|
|
186
|
+
- **When:** {{command}}
|
|
187
|
+
- **Then:** rejected with reason; no event.
|
|
188
|
+
- **{{Edge case}}**
|
|
189
|
+
- **Given:** {{...}}
|
|
190
|
+
- **When:** {{...}}
|
|
191
|
+
- **Then:** {{...}}
|
|
159
192
|
|
|
160
193
|
## Alternate & Error Flows
|
|
161
194
|
<!-- Failure paths, retries, compensations, timeouts, idempotency. -->
|
|
@@ -174,5 +207,15 @@ an event directly.}}
|
|
|
174
207
|
- **Downstream read models / slices affected:** {{...}}
|
|
175
208
|
|
|
176
209
|
## Open Questions
|
|
177
|
-
<!-- Park unresolved items here instead of guessing. Mirror them into .event-modeling.md.
|
|
210
|
+
<!-- Park unresolved items here instead of guessing. Mirror them into .event-modeling.md.
|
|
211
|
+
|
|
212
|
+
Lifecycle across versions: while THIS version is still being worked, a resolved item
|
|
213
|
+
(`- [x]`) can stay checked here as a visible record of what's already been decided this
|
|
214
|
+
round. On the same commit that ratifies the NEXT version (bumps `version`, rewrites
|
|
215
|
+
`## Delta` above) — prune every already-checked item from this list; keep only what's still
|
|
216
|
+
open, plus anything new the delta itself surfaced. Same "replace, never accumulate" stance
|
|
217
|
+
as `## Delta`, for the same reason: an ever-growing scroll of resolved questions goes stale
|
|
218
|
+
exactly like an accumulating Delta log would, and full history already lives in git
|
|
219
|
+
(`git log -p slices/<name>.md`) — this section is a live worklist, not an audit trail. See
|
|
220
|
+
docs/slice-doc-schema.md#open-questions-section-lifecycle. -->
|
|
178
221
|
- [ ] {{question}}
|