@milehimikey/em 1.8.0 → 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.
Files changed (127) hide show
  1. package/.claude/skills/event-modeling/SKILL.md +58 -404
  2. package/.claude/skills/event-modeling-conform/SKILL.md +77 -0
  3. package/.claude/skills/{event-modeling → event-modeling-conform}/reference/conform.md +39 -13
  4. package/.claude/skills/event-modeling-design/SKILL.md +139 -0
  5. package/.claude/skills/event-modeling-discover/SKILL.md +89 -0
  6. package/.claude/skills/{event-modeling → event-modeling-discover}/reference/extract.md +3 -2
  7. package/.claude/skills/event-modeling-implement/SKILL.md +40 -0
  8. package/.claude/skills/{event-modeling → event-modeling-implement}/reference/implement.md +3 -2
  9. package/.claude/skills/event-modeling-review/SKILL.md +58 -0
  10. package/.claude/skills/{event-modeling → event-modeling-shared}/reference/em-dsl.md +128 -84
  11. package/.claude/skills/{event-modeling → event-modeling-shared}/reference/methodology.md +6 -5
  12. package/.claude/skills/event-modeling-shared/reference/operating-principles.md +147 -0
  13. package/.claude/skills/{event-modeling → event-modeling-shared}/templates/model-readme.md +2 -2
  14. package/.claude/skills/{event-modeling → event-modeling-shared}/templates/slice.md +51 -8
  15. package/README.md +24 -4
  16. package/dist/catalog/build.js +9 -0
  17. package/dist/catalog/build.js.map +1 -1
  18. package/dist/catalog/docJoin.d.ts +15 -0
  19. package/dist/catalog/docJoin.js +8 -0
  20. package/dist/catalog/docJoin.js.map +1 -1
  21. package/dist/catalog/modelCollisionValidate.d.ts +22 -0
  22. package/dist/catalog/modelCollisionValidate.js +67 -0
  23. package/dist/catalog/modelCollisionValidate.js.map +1 -0
  24. package/dist/catalog/orphanedSliceDocValidate.d.ts +11 -0
  25. package/dist/catalog/orphanedSliceDocValidate.js +98 -0
  26. package/dist/catalog/orphanedSliceDocValidate.js.map +1 -0
  27. package/dist/catalog/sliceDoc.d.ts +15 -0
  28. package/dist/catalog/sliceDoc.js +18 -0
  29. package/dist/catalog/sliceDoc.js.map +1 -1
  30. package/dist/cli/changelogBuild.d.ts +12 -0
  31. package/dist/cli/changelogBuild.js +89 -0
  32. package/dist/cli/changelogBuild.js.map +1 -0
  33. package/dist/cli/ciInit.d.ts +42 -0
  34. package/dist/cli/ciInit.js +298 -0
  35. package/dist/cli/ciInit.js.map +1 -0
  36. package/dist/cli/conformSupersede.d.ts +32 -0
  37. package/dist/cli/conformSupersede.js +102 -0
  38. package/dist/cli/conformSupersede.js.map +1 -0
  39. package/dist/cli/coverage.d.ts +17 -10
  40. package/dist/cli/coverage.js +61 -16
  41. package/dist/cli/coverage.js.map +1 -1
  42. package/dist/cli/frontmatterSurgery.d.ts +28 -0
  43. package/dist/cli/frontmatterSurgery.js +66 -0
  44. package/dist/cli/frontmatterSurgery.js.map +1 -0
  45. package/dist/cli/markImplemented.js +6 -45
  46. package/dist/cli/markImplemented.js.map +1 -1
  47. package/dist/cli/ratify.d.ts +41 -0
  48. package/dist/cli/ratify.js +151 -0
  49. package/dist/cli/ratify.js.map +1 -0
  50. package/dist/cli/reratify.d.ts +33 -0
  51. package/dist/cli/reratify.js +137 -0
  52. package/dist/cli/reratify.js.map +1 -0
  53. package/dist/cli/skillCheck.d.ts +6 -0
  54. package/dist/cli/skillCheck.js +46 -0
  55. package/dist/cli/skillCheck.js.map +1 -1
  56. package/dist/cli/skillDirs.d.ts +15 -0
  57. package/dist/cli/skillDirs.js +34 -0
  58. package/dist/cli/skillDirs.js.map +1 -0
  59. package/dist/cli/skillSync.d.ts +10 -0
  60. package/dist/cli/skillSync.js +15 -0
  61. package/dist/cli/skillSync.js.map +1 -1
  62. package/dist/cli/sliceIndex.d.ts +3 -0
  63. package/dist/cli/sliceIndex.js +6 -2
  64. package/dist/cli/sliceIndex.js.map +1 -1
  65. package/dist/cli/sliceLink.d.ts +52 -0
  66. package/dist/cli/sliceLink.js +152 -0
  67. package/dist/cli/sliceLink.js.map +1 -0
  68. package/dist/cli/status.d.ts +261 -0
  69. package/dist/cli/status.js +536 -0
  70. package/dist/cli/status.js.map +1 -0
  71. package/dist/cli/usageLog.d.ts +75 -0
  72. package/dist/cli/usageLog.js +193 -0
  73. package/dist/cli/usageLog.js.map +1 -0
  74. package/dist/cli.js +501 -130
  75. package/dist/cli.js.map +1 -1
  76. package/dist/emit/diffJson.d.ts +9 -1
  77. package/dist/emit/diffJson.js +44 -1
  78. package/dist/emit/diffJson.js.map +1 -1
  79. package/dist/emit/freshnessJson.d.ts +6 -0
  80. package/dist/emit/freshnessJson.js +24 -0
  81. package/dist/emit/freshnessJson.js.map +1 -0
  82. package/dist/emit/json.d.ts +67 -8
  83. package/dist/emit/json.js +19 -3
  84. package/dist/emit/json.js.map +1 -1
  85. package/dist/emit/statusJson.d.ts +7 -0
  86. package/dist/emit/statusJson.js +39 -0
  87. package/dist/emit/statusJson.js.map +1 -0
  88. package/dist/emit/typespec.d.ts +26 -0
  89. package/dist/emit/typespec.js +356 -0
  90. package/dist/emit/typespec.js.map +1 -0
  91. package/dist/emit/usageReportJson.d.ts +3 -0
  92. package/dist/emit/usageReportJson.js +23 -0
  93. package/dist/emit/usageReportJson.js.map +1 -0
  94. package/dist/mcp/server.d.ts +1 -1
  95. package/dist/mcp/server.js +301 -11
  96. package/dist/mcp/server.js.map +1 -1
  97. package/dist/model/rules.d.ts +13 -0
  98. package/dist/model/rules.js +20 -0
  99. package/dist/model/rules.js.map +1 -1
  100. package/dist/model/validate.js +9 -1
  101. package/dist/model/validate.js.map +1 -1
  102. package/dist/parser/ast.d.ts +6 -0
  103. package/dist/parser/parser.js +20 -6
  104. package/dist/parser/parser.js.map +1 -1
  105. package/dist/render/drawNotes.d.ts +11 -1
  106. package/dist/render/drawNotes.js +20 -2
  107. package/dist/render/drawNotes.js.map +1 -1
  108. package/dist/render/render.js +31 -6
  109. package/dist/render/render.js.map +1 -1
  110. package/dist/render/serve.js +4 -0
  111. package/dist/render/serve.js.map +1 -1
  112. package/dist/render/sliceOverlay.d.ts +7 -2
  113. package/dist/render/sliceOverlay.js +19 -7
  114. package/dist/render/sliceOverlay.js.map +1 -1
  115. package/dist/render/sliceStatus.d.ts +7 -3
  116. package/dist/render/sliceStatus.js +21 -14
  117. package/dist/render/sliceStatus.js.map +1 -1
  118. package/dist/render/viewerHtml.js +1 -1
  119. package/dist/render/viewerHtml.js.map +1 -1
  120. package/dist/templates.d.ts +2 -2
  121. package/dist/templates.js +5 -5
  122. package/dist/util/markers.d.ts +16 -4
  123. package/dist/util/markers.js +23 -10
  124. package/dist/util/markers.js.map +1 -1
  125. package/package.json +2 -1
  126. /package/.claude/skills/{event-modeling → event-modeling-shared}/templates/conformance-report.md +0 -0
  127. /package/.claude/skills/{event-modeling → event-modeling-shared}/templates/state.md +0 -0
@@ -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
- - **GIVEN** {{...}} **WHEN** {{...}} **THEN** {{...}}
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
- - **Happy path** — Given {{starting state / prior events}}, When {{command/trigger}},
156
- Then {{event(s) recorded}} and {{resulting read-model change}}.
157
- - **Rejected (INV-{{MNEMONIC}}-1)** — Given {{state}}, When {{command}}, Then {{rejected with reason}}; no event.
158
- - **{{Edge case}}** — Given {{...}}, When {{...}}, Then {{...}}.
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}}
package/README.md CHANGED
@@ -64,16 +64,35 @@ minutes, and [docs/workflow.md](docs/workflow.md) picks up where it leaves off:
64
64
  gets specified, gated in CI, handed to implementation, and checked against the code that
65
65
  implements it.
66
66
 
67
+ ## How it works
68
+
69
+ Model, gate, ratify, implement, check — repeat as the system evolves. Humans make the calls
70
+ that matter (build the model, ratify a slice, rule on drift); `em` and its agents handle the
71
+ mechanical parts in between. This is the loop in miniature — see
72
+ [docs/workflow.md](docs/workflow.md) for the full seven-stage lifecycle and
73
+ [docs/process.md](docs/process.md) for exactly who (or what) does each part.
74
+
75
+ ```mermaid
76
+ flowchart LR
77
+ Model["Model<br/>.em file"] --> Gate["Gate<br/>em validate in CI"]
78
+ Gate --> Ratify["Ratify a slice<br/>a human signs off"]
79
+ Ratify --> Implement["Implement<br/>agent or engineer builds it"]
80
+ Implement --> Conform["Conform<br/>em conform checks the code"]
81
+ Conform -->|drift found, ratified| Model
82
+ ```
83
+
67
84
  ## Model with AI
68
85
 
69
- `em` ships a Claude Code skill that runs a facilitated Event Modeling session: the AI asks
70
- the questions, you supply the domain, and the model renders live as it grows.
86
+ `em` ships a Claude Code skill bundle — one router skill plus five focused, SDLC-stage skills
87
+ (discover/extract, model/slice, implement, conform/validate, watch/review) — that runs a
88
+ facilitated Event Modeling session: the AI asks the questions, you supply the domain, and the
89
+ model renders live as it grows.
71
90
 
72
91
  ```bash
73
- em skill install # copy the skill into .claude/skills/event-modeling/
92
+ em skill install # copy the skill bundle into .claude/skills/
74
93
  ```
75
94
 
76
- Then run `/event-modeling` in Claude Code. The same skill also runs the reverse direction:
95
+ Then run `/event-modeling` in Claude Code. The same bundle also runs the reverse direction:
77
96
  `extract` derives a model from a system that already exists, and `conform` checks a model
78
97
  against the code implementing it and reports where they've drifted. See
79
98
  [docs/ai-workflow.md](docs/ai-workflow.md) for the phases and what a session produces, and the
@@ -98,6 +117,7 @@ built this way.
98
117
  | [docs/usage-data.md](docs/usage-data.md) | What usage data em captures, and how to roll it up for a retro |
99
118
  | [docs/architecture.md](docs/architecture.md) | How rendering works; why Graphviz, not PlantUML |
100
119
  | [docs/roadmap.md](docs/roadmap.md) | What's planned |
120
+ | [docs/decisions/](docs/decisions/) | Write-ups for open design questions (starts with [MIL-162](docs/decisions/mil-162-teachable-navigator.md), the stakeholder-portal decision) |
101
121
 
102
122
  ## Development
103
123
 
@@ -17,6 +17,7 @@ import { layoutDot, composeSvg, writeRendered } from "../render/render.js";
17
17
  import { buildSliceDiagram } from "../render/sliceDiagram.js";
18
18
  import { dedupe, kebabSlug } from "../util/slug.js";
19
19
  import { classifySlicePattern } from "./classify.js";
20
+ import { detectSliceDocCollisions } from "./modelCollisionValidate.js";
20
21
  import { parseSliceDoc } from "./sliceDoc.js";
21
22
  import { renderIndexPage, renderSlicePage } from "./pages.js";
22
23
  export async function buildCatalog(inputs, opts) {
@@ -28,6 +29,14 @@ export async function buildCatalog(inputs, opts) {
28
29
  const modelSummaries = [];
29
30
  const diagnostics = [];
30
31
  let sliceCount = 0;
32
+ // MIL-160: catalog's own doc discovery below (existsSync+parseSliceDoc, deliberately not
33
+ // routed through readSliceDoc.ts's `note`-aware convention — see this module's header
34
+ // comment) reads straight off `dirname(file)/slices/<key>.md`, same as every other doc-aware
35
+ // command — so two input models sharing a directory with overlapping slice keys would
36
+ // silently mix up whose doc is whose here too. Checked once, up front, over every input.
37
+ const collisions = detectSliceDocCollisions(inputs.map(({ file, refs }) => ({ file, sliceKeys: refs.sliceKeys })));
38
+ for (const d of collisions)
39
+ diagnostics.push({ file: d.refs?.[2] ?? "", diagnostics: [d] });
31
40
  for (const { file, model, grid, dot, refs } of inputs) {
32
41
  const modelKey = dedupe(kebabSlug(basename(file, extname(file))), usedModelKeys, "~");
33
42
  const modelDir = join(outDir, modelKey);
@@ -1 +1 @@
1
- {"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/catalog/build.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/catalog/build.ts"],"names":[],"mappings":"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"}
@@ -49,6 +49,21 @@ export interface SliceDocExport {
49
49
  * `version` above from the same doc parse — a finding built from `driftSignal` should always
50
50
  * cite `version` alongside it, never cache one without the other. */
51
51
  driftSignal: DriftSignalKind | null;
52
+ /** MIL-165: who ratified this doc's current `status`/`version` (frontmatter `ratifiedBy:`),
53
+ * written only by `em slice ratify` — null when absent (a doc predating this feature, or
54
+ * ratified by hand before it existed). */
55
+ ratifiedBy: string | null;
56
+ /** MIL-165: when this doc was ratified (frontmatter `ratifiedOn:`, `YYYY-MM-DD`), written only
57
+ * by `em slice ratify` — null when absent, same as `ratifiedBy`. */
58
+ ratifiedOn: string | null;
59
+ /** MIL-171: who (a person or team) holds this slice, from frontmatter `owner:` — hand-filled,
60
+ * no `em` command writes it. Null when absent. */
61
+ owner: string | null;
62
+ /** MIL-171: a URL into an external tracker mirroring this slice, from frontmatter `tracking:`
63
+ * — hand-filled, no `em` command writes it. Null when absent. This is the exact field
64
+ * em-tracker-bridge reads to find the mirrored ticket — its name/shape here is a cross-tool
65
+ * contract, not just an internal display field. */
66
+ tracking: string | null;
52
67
  }
53
68
  export interface SliceDocJoinResult {
54
69
  doc: SliceDocExport;
@@ -66,6 +66,10 @@ const EMPTY_CONTENT = {
66
66
  mergedFrom: [],
67
67
  supersededBy: [],
68
68
  driftSignal: null,
69
+ ratifiedBy: null,
70
+ ratifiedOn: null,
71
+ owner: null,
72
+ tracking: null,
69
73
  };
70
74
  /**
71
75
  * Resolve one slice's doc join. `baseDir` is the `.em` file's directory (doc paths, like note
@@ -150,6 +154,10 @@ function foundDoc(path, parsed) {
150
154
  mergedFrom: parsed.mergedFrom,
151
155
  supersededBy: parsed.supersededBy,
152
156
  driftSignal: classifyImplementationDrift(parsed),
157
+ ratifiedBy: parsed.ratifiedBy,
158
+ ratifiedOn: parsed.ratifiedOn,
159
+ owner: parsed.owner,
160
+ tracking: parsed.tracking,
153
161
  };
154
162
  }
155
163
  //# sourceMappingURL=docJoin.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"docJoin.js","sourceRoot":"","sources":["../../src/catalog/docJoin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"docJoin.js","sourceRoot":"","sources":["../../src/catalog/docJoin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { Diagnostic } from "../model/validate.js";
2
+ export interface ModelSliceKeys {
3
+ /** The `.em` file as given on the command line — same identity every other multi-model
4
+ * diagnostic (StatusDiagnostic, CatalogBuildResult.diagnostics) tags itself with. */
5
+ file: string;
6
+ /** This model's own compiled slice export keys, same order/index as `computeRefs()`'s
7
+ * `sliceKeys` — duplicates already deduped with a `~2` suffix by computeRefs() itself, so a
8
+ * key here is always a real, single doc path this model expects to read/write. */
9
+ sliceKeys: string[];
10
+ }
11
+ /**
12
+ * Detect colliding `slices/<key>.md` doc paths across `models`: any two files whose resolved
13
+ * base directory (`dirname(file)`, absolute so `./a.em` and `a.em` from the same cwd count as
14
+ * the same directory) is identical AND who share at least one slice export key. One diagnostic
15
+ * per colliding key, attributed to the SECOND model to use that key in file-list order — same
16
+ * "first wins, the later one gets flagged" convention `computeRefs()`'s own `duplicate-slice-name`
17
+ * diagnostic uses, so a collision reads as "this model's key collides with an earlier one," not
18
+ * the reverse. A model list of 0 or 1 files (or where every file resolves to a distinct
19
+ * directory) always returns `[]` — the ordinary single-model-per-directory case this function
20
+ * exists to leave alone.
21
+ */
22
+ export declare function detectSliceDocCollisions(models: ModelSliceKeys[]): Diagnostic[];
@@ -0,0 +1,67 @@
1
+ // SPDX-License-Identifier: MIT
2
+ // Cross-model slice-doc collision detection (MIL-160). readSliceDoc.ts resolves every slice doc
3
+ // at `<dirname(modelFile)>/slices/<sliceKey>.md` — safe as long as every model owns its own
4
+ // directory (the documented convention, docs/cli.md "Multi-model projects"), since computeRefs()
5
+ // only dedupes a slice key against the OTHER slices in the SAME model's compile
6
+ // (src/model/refs.ts). Two sibling `.em` files sharing a directory, each producing a slice
7
+ // keyed e.g. "checkout", would both resolve to the same `slices/checkout.md` — silently: neither
8
+ // model's compile ever sees the other, so nothing raises a diagnostic today. This is the one
9
+ // check that does: given every input model's file path and its own compiled slice keys, group by
10
+ // resolved base directory and flag any key more than one model in the same group produces.
11
+ //
12
+ // The only cross-model rule in the codebase — every other rule in model/rules.ts is a
13
+ // single-model concern raised from inside one compile. Deliberately NOT part of
14
+ // model/validate.ts's pipeline (which only ever sees one model at a time); instead wired
15
+ // directly into the two commands that ever compile more than one model in the same run
16
+ // (`em status` in src/cli.ts, `em catalog` in src/catalog/build.ts) — the only places that
17
+ // could possibly witness a collision. Pure — no fs — the compiled `sliceKeys` are handed in by
18
+ // the caller, already computed by the same computeRefs() call the caller made anyway.
19
+ import { dirname, resolve } from "node:path";
20
+ import { makeDiag } from "../model/rules.js";
21
+ /**
22
+ * Detect colliding `slices/<key>.md` doc paths across `models`: any two files whose resolved
23
+ * base directory (`dirname(file)`, absolute so `./a.em` and `a.em` from the same cwd count as
24
+ * the same directory) is identical AND who share at least one slice export key. One diagnostic
25
+ * per colliding key, attributed to the SECOND model to use that key in file-list order — same
26
+ * "first wins, the later one gets flagged" convention `computeRefs()`'s own `duplicate-slice-name`
27
+ * diagnostic uses, so a collision reads as "this model's key collides with an earlier one," not
28
+ * the reverse. A model list of 0 or 1 files (or where every file resolves to a distinct
29
+ * directory) always returns `[]` — the ordinary single-model-per-directory case this function
30
+ * exists to leave alone.
31
+ */
32
+ export function detectSliceDocCollisions(models) {
33
+ const diagnostics = [];
34
+ const byDir = new Map();
35
+ for (const m of models) {
36
+ const dir = resolve(dirname(m.file));
37
+ const bucket = byDir.get(dir);
38
+ if (bucket)
39
+ bucket.push(m);
40
+ else
41
+ byDir.set(dir, [m]);
42
+ }
43
+ for (const bucket of byDir.values()) {
44
+ if (bucket.length < 2)
45
+ continue; // only one model in this directory — no collision possible
46
+ const firstFileForKey = new Map();
47
+ for (const m of bucket) {
48
+ for (const key of m.sliceKeys) {
49
+ const earlier = firstFileForKey.get(key);
50
+ if (earlier === undefined) {
51
+ firstFileForKey.set(key, m.file);
52
+ continue;
53
+ }
54
+ if (earlier === m.file)
55
+ continue; // same model listed twice on the command line
56
+ diagnostics.push(makeDiag("cross-model-slice-doc-collision", {
57
+ message: `"${m.file}" and "${earlier}" share a directory and both produce slice key "${key}" — ` +
58
+ `both would read/write "slices/${key}.md"; give each model its own directory ` +
59
+ `(see docs/cli.md, "Multi-model projects")`,
60
+ refs: [key, earlier, m.file],
61
+ }));
62
+ }
63
+ }
64
+ }
65
+ return diagnostics;
66
+ }
67
+ //# sourceMappingURL=modelCollisionValidate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modelCollisionValidate.js","sourceRoot":"","sources":["../../src/catalog/modelCollisionValidate.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,gGAAgG;AAChG,4FAA4F;AAC5F,iGAAiG;AACjG,gFAAgF;AAChF,2FAA2F;AAC3F,iGAAiG;AACjG,6FAA6F;AAC7F,iGAAiG;AACjG,2FAA2F;AAC3F,EAAE;AACF,sFAAsF;AACtF,gFAAgF;AAChF,yFAAyF;AACzF,uFAAuF;AACvF,2FAA2F;AAC3F,+FAA+F;AAC/F,sFAAsF;AAEtF,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE7C,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAY7C;;;;;;;;;;GAUG;AACH,MAAM,UAAU,wBAAwB,CAAC,MAAwB;IAC/D,MAAM,WAAW,GAAiB,EAAE,CAAC;IACrC,MAAM,KAAK,GAAG,IAAI,GAAG,EAA4B,CAAC;IAClD,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QACrC,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,MAAM;YAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;;YACtB,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3B,CAAC;IAED,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;QACpC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;YAAE,SAAS,CAAC,2DAA2D;QAC5F,MAAM,eAAe,GAAG,IAAI,GAAG,EAAkB,CAAC;QAClD,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;YACvB,KAAK,MAAM,GAAG,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC;gBAC9B,MAAM,OAAO,GAAG,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACzC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;oBAC1B,eAAe,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;oBACjC,SAAS;gBACX,CAAC;gBACD,IAAI,OAAO,KAAK,CAAC,CAAC,IAAI;oBAAE,SAAS,CAAC,8CAA8C;gBAChF,WAAW,CAAC,IAAI,CACd,QAAQ,CAAC,iCAAiC,EAAE;oBAC1C,OAAO,EACL,IAAI,CAAC,CAAC,IAAI,UAAU,OAAO,mDAAmD,GAAG,MAAM;wBACvF,iCAAiC,GAAG,0CAA0C;wBAC9E,2CAA2C;oBAC7C,IAAI,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC;iBAC7B,CAAC,CACH,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { NormalizedModel } from "../model/model.js";
2
+ import { RefsResult } from "../model/refs.js";
3
+ import { Diagnostic } from "../model/validate.js";
4
+ /**
5
+ * Scan `<baseDir>/slices/` for a doc file that no current slice's own key names by filename
6
+ * convention, and whose `covers:` list (if any — MIL-121) doesn't ratify a current slice either.
7
+ * `baseDir` is the `.em` file's directory, same convention every other doc/note path in em uses.
8
+ * Returns `[]` when `slices/` doesn't exist at all — nothing to a scan with no directory to walk,
9
+ * the ordinary state for a model that hasn't authored any slice docs yet.
10
+ */
11
+ export declare function validateOrphanedSliceDocs(_model: NormalizedModel, refs: RefsResult, baseDir: string): Diagnostic[];
@@ -0,0 +1,98 @@
1
+ // SPDX-License-Identifier: MIT
2
+ // `em validate`'s fifth fs-aware rule (MIL-183, the fragility half of GH #128): a slice doc left
3
+ // behind in `slices/` after its slice is renamed or removed used to just quietly stop applying —
4
+ // nothing ever pointed at the ORPHANED FILE itself. Same fs-aware-sibling shape as
5
+ // catalog/lineageValidate.ts (MIL-84), catalog/frontmatterCoherenceValidate.ts (MIL-85),
6
+ // catalog/noteBindingValidate.ts (MIL-126), and catalog/docModelConsistencyValidate.ts (MIL-124):
7
+ // a module next to model/validate.ts, not folded into it, because it needs `baseDir`/fs access
8
+ // the rest of validate deliberately never touches. Distinct from all four of those, though, in
9
+ // which direction it walks: every one of them starts from a *slice* and asks "is its doc/note
10
+ // okay?" — this is the only rule that instead walks the filesystem and asks the opposite
11
+ // direction, "does every file out there still belong to something?"
12
+ //
13
+ // Two doc-join mechanisms coexist in this codebase (docJoin.ts's own header comment spells out
14
+ // the same split): `docJoin.ts`'s `resolveSliceDocJoin`, gated on an explicit
15
+ // `note "slices/<key>.md"` binding, drives `em export`/`em status`/the MCP tools; `em catalog`
16
+ // (catalog/build.ts) instead reads `slices/<sliceKey>.md` by BARE FILENAME CONVENTION, ignoring
17
+ // `note` entirely — a standing, deliberately-kept-separate, tested invariant (see build.ts's own
18
+ // header comment and test/catalog.e2e.test.ts). The GH #128 reporter's "matched by name, silently
19
+ // stops applying" experience is build.ts's convention path, not docJoin's note-gated one — status
20
+ // coloring on the diagram comes from whether a file happens to sit at the right name, full stop.
21
+ // So "orphaned" here is judged the same name-convention way build.ts resolves a doc: by filename
22
+ // key (and, for a MIL-121 covering doc, by its `covers:` list), never by whether some element
23
+ // happens to carry a `note`. A note-binding problem (a note pointing at the wrong place) is
24
+ // noteBindingValidate.ts's business; a stale file nothing names by convention or `covers:` any
25
+ // more is this rule's.
26
+ //
27
+ // A file only counts as a slice doc worth checking when its frontmatter is USABLE
28
+ // (hasUsableFrontmatter — sliceDoc.ts, the exact gate `em export`'s `frontmatter-invalid` and
29
+ // every sibling module already use, so this rule can't silently disagree with them on what counts
30
+ // as a readable doc). This is what keeps a README, a scratch note, or any other non-doc file in
31
+ // `slices/` from ever being flagged: nothing here can distinguish such a file from "meant to
32
+ // become a slice doc but hasn't been fleshed out yet" except the file declaring itself one via
33
+ // frontmatter — the same declare-gating posture docModelConsistencyValidate.ts's checks take.
34
+ import { readdirSync, readFileSync } from "node:fs";
35
+ import { join } from "node:path";
36
+ import { pushDiag } from "../model/rules.js";
37
+ import { hasUsableFrontmatter, parseSliceDoc } from "./sliceDoc.js";
38
+ /**
39
+ * Scan `<baseDir>/slices/` for a doc file that no current slice's own key names by filename
40
+ * convention, and whose `covers:` list (if any — MIL-121) doesn't ratify a current slice either.
41
+ * `baseDir` is the `.em` file's directory, same convention every other doc/note path in em uses.
42
+ * Returns `[]` when `slices/` doesn't exist at all — nothing to a scan with no directory to walk,
43
+ * the ordinary state for a model that hasn't authored any slice docs yet.
44
+ */
45
+ export function validateOrphanedSliceDocs(_model, refs, baseDir) {
46
+ // `_model` is unused — `refs.sliceKeys` already carries every current slice's key. Kept in the
47
+ // signature anyway to match every sibling fs-aware rule's `(model, refs, baseDir)` shape, so
48
+ // every call site can pass the same three arguments uniformly.
49
+ const slicesDir = join(baseDir, "slices");
50
+ let entries;
51
+ try {
52
+ entries = readdirSync(slicesDir, { withFileTypes: true })
53
+ .filter((e) => e.isFile())
54
+ .map((e) => e.name);
55
+ }
56
+ catch {
57
+ return []; // no slices/ directory (or unreadable) — nothing to orphan
58
+ }
59
+ const liveKeys = new Set(refs.sliceKeys.map((k) => k.toLowerCase()));
60
+ const diags = [];
61
+ for (const entry of entries.slice().sort()) {
62
+ if (!entry.toLowerCase().endsWith(".md"))
63
+ continue; // not a slice-doc-shaped file at all
64
+ const key = entry.slice(0, -".md".length);
65
+ if (liveKeys.has(key.toLowerCase()))
66
+ continue; // matches a current slice's key by name — never orphaned
67
+ let parsed;
68
+ try {
69
+ parsed = parseSliceDoc(readFileSync(join(slicesDir, entry), "utf8"));
70
+ }
71
+ catch {
72
+ continue; // unreadable file (permissions, ...) — not this rule's business
73
+ }
74
+ // Gate on usable frontmatter, same predicate every sibling fs-aware rule uses: a README, a
75
+ // freeform note, or a draft that never got as far as a full frontmatter block is not
76
+ // confidently a slice doc at all, so it's never flagged as one gone stale.
77
+ if (!hasUsableFrontmatter(parsed))
78
+ continue;
79
+ // MIL-121: a doc whose own canonical slice is gone can still legitimately serve a DIFFERENT,
80
+ // still-live slice via `covers:` — the two-slice Automation/Translation shape's shared-doc
81
+ // case. Ratifying coverage of any current slice is enough; this mirrors docJoin.ts's own
82
+ // predicate loosely (it doesn't require an actual winning cross-note here, only that the
83
+ // `covers:` declaration itself still names something live) — a stricter "and some note also
84
+ // points here" check would reintroduce exactly the kind of false positive this ticket calls
85
+ // out to avoid.
86
+ if (parsed.covers.some((c) => liveKeys.has(c)))
87
+ continue;
88
+ pushDiag(diags, "orphaned-slice-doc", {
89
+ message: `slice doc "slices/${entry}" matches no current slice's key, and its \`covers:\` list ` +
90
+ `(if any) doesn't name one either — likely left behind by a rename or removal. Rename it ` +
91
+ `to the renamed slice's key, add \`covers: <slice-key>\` (plus a \`note\` binding) to ` +
92
+ `attach it to a live slice, or delete it if it's no longer needed`,
93
+ refs: [key],
94
+ });
95
+ }
96
+ return diags;
97
+ }
98
+ //# sourceMappingURL=orphanedSliceDocValidate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orphanedSliceDocValidate.js","sourceRoot":"","sources":["../../src/catalog/orphanedSliceDocValidate.ts"],"names":[],"mappings":"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"}
@@ -59,6 +59,21 @@ export interface SliceDoc {
59
59
  * the noting slice back. Empty array when absent — the common case; a doc always covers its
60
60
  * own canonical slice key implicitly and never needs to list it here. */
61
61
  covers: string[];
62
+ /** MIL-165: `ratifiedBy:` — free text, typically a person's name — or null when absent.
63
+ * Written only by `em slice ratify`; no legacy bullet-line form. */
64
+ ratifiedBy: string | null;
65
+ /** MIL-165: `ratifiedOn:` — a `YYYY-MM-DD` date string, or null when absent. Written only by
66
+ * `em slice ratify`; validated by the CLI layer, not re-validated here (this parser stays as
67
+ * lenient about value shape as every other frontmatter field). */
68
+ ratifiedOn: string | null;
69
+ /** MIL-171: `owner:` — free text, typically a person or team name — or null when absent.
70
+ * Hand-filled; no `em` command writes it. */
71
+ owner: string | null;
72
+ /** MIL-171: `tracking:` — free text, typically an external ticket/issue URL — or null when
73
+ * absent. Hand-filled; no `em` command writes it. This is the field em-tracker-bridge reads
74
+ * to find the ticket mirroring this slice — its export name/shape (docJoin.ts) is a
75
+ * cross-tool contract, not just an internal display field. */
76
+ tracking: string | null;
62
77
  /** True when a well-formed leading `---`/`---` frontmatter fence was found and
63
78
  * closed — independent of which keys it contained. False for a legacy
64
79
  * status-bullet-only doc, a doc with no frontmatter at all, or an
@@ -33,6 +33,20 @@
33
33
  // `note "slices/<this-key>.md"` instead of authoring its own. Parsed the same
34
34
  // comma-separated-list shape as `merged-from`/`superseded-by`; see docJoin.ts for the
35
35
  // two-ended handshake that actually uses it.
36
+ //
37
+ // `ratifiedBy`/`ratifiedOn` (MIL-165) are a fifth and sixth optional frontmatter-only field:
38
+ // who ratified this doc's current `status`/`version`, and when, written by `em slice ratify`
39
+ // (cli/ratify.ts) alone — same "one write path" discipline `implementedIn` has with `em slice
40
+ // mark-implemented`. Additive, tolerate-unknown-fields: a doc that predates this feature (or was
41
+ // hand-ratified) simply has neither key, same as any other optional field's absence.
42
+ //
43
+ // `owner`/`tracking` (MIL-171) are a seventh and eighth optional frontmatter-only field: who
44
+ // (a person or team) holds this slice, and a URL into an external tracker mirroring it. Unlike
45
+ // `ratifiedBy`/`ratifiedOn`, neither has a dedicated `em` write path — both are hand-filled, free
46
+ // text, exactly like `implementedIn`. `em` only stores and displays them; `tracking` in
47
+ // particular is the field em-tracker-bridge reads to find the mirrored ticket, so its export
48
+ // name/shape is a cross-tool contract — see docJoin.ts/emit/json.ts. Additive,
49
+ // tolerate-unknown-fields: absent on every doc predating this feature.
36
50
  import { marked } from "marked";
37
51
  /** Frontmatter keys docs/slice-doc-schema.md's required-vs-optional table marks
38
52
  * required at every `status` — the mechanical basis for `frontmatter-invalid`
@@ -182,6 +196,10 @@ export function parseSliceDoc(markdown) {
182
196
  supersededBy: parseSliceRefList(fields.get("superseded-by")),
183
197
  implementedIn: fields.get("implementedin") ?? null,
184
198
  covers: parseKeyList(fields.get("covers")),
199
+ ratifiedBy: fields.get("ratifiedby") ?? null,
200
+ ratifiedOn: fields.get("ratifiedon") ?? null,
201
+ owner: fields.get("owner") ?? null,
202
+ tracking: fields.get("tracking") ?? null,
185
203
  frontmatterPresent,
186
204
  missingRequiredFields: REQUIRED_FRONTMATTER_KEYS.filter((k) => !fields.has(k)),
187
205
  html: marked.parse(body, { async: false }),
@@ -1 +1 @@
1
- {"version":3,"file":"sliceDoc.js","sourceRoot":"","sources":["../../src/catalog/sliceDoc.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sliceDoc.js","sourceRoot":"","sources":["../../src/catalog/sliceDoc.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { CommitInfo } from "./changelog-git.js";
2
+ /**
3
+ * Build the `em changelog` markdown document for an already-resolved commit list
4
+ * (oldest -> newest, see `listModelCommits`). Compiles every revision once; per-revision
5
+ * warnings are deliberately never surfaced (historical revisions can be noisy) — only a compile
6
+ * *failure* (parse error or validation error, same threshold `em diff` uses) surfaces, as that
7
+ * entry's error note, never a crash. Diffs are computed against the previous *parseable*
8
+ * revision, so a single bad revision in the middle of the walk doesn't break every entry after
9
+ * it. Content is read at each commit's own path (`readFileAtCommit`), so the walk survives
10
+ * renames.
11
+ */
12
+ export declare function buildChangelogDoc(file: string, repoRoot: string, commits: CommitInfo[]): string;