@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.
- 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 +128 -84
- 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 +17 -10
- package/dist/cli/coverage.js +61 -16
- 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/diffJson.d.ts +9 -1
- package/dist/emit/diffJson.js +44 -1
- package/dist/emit/diffJson.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 +67 -8
- package/dist/emit/json.js +19 -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/model/validate.js +9 -1
- package/dist/model/validate.js.map +1 -1
- package/dist/parser/ast.d.ts +6 -0
- package/dist/parser/parser.js +20 -6
- package/dist/parser/parser.js.map +1 -1
- package/dist/render/drawNotes.d.ts +11 -1
- package/dist/render/drawNotes.js +20 -2
- package/dist/render/drawNotes.js.map +1 -1
- package/dist/render/render.js +31 -6
- package/dist/render/render.js.map +1 -1
- package/dist/render/serve.js +4 -0
- package/dist/render/serve.js.map +1 -1
- package/dist/render/sliceOverlay.d.ts +7 -2
- package/dist/render/sliceOverlay.js +19 -7
- package/dist/render/sliceOverlay.js.map +1 -1
- package/dist/render/sliceStatus.d.ts +7 -3
- package/dist/render/sliceStatus.js +21 -14
- package/dist/render/sliceStatus.js.map +1 -1
- package/dist/render/viewerHtml.js +1 -1
- package/dist/render/viewerHtml.js.map +1 -1
- package/dist/templates.d.ts +2 -2
- package/dist/templates.js +5 -5
- 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
|
@@ -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}}
|
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
|
|
70
|
-
|
|
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/
|
|
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
|
|
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
|
|
package/dist/catalog/build.js
CHANGED
|
@@ -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;
|
package/dist/catalog/docJoin.js
CHANGED
|
@@ -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":"AAAA,+BAA+B;AAC/B,4FAA4F;AAC5F,6FAA6F;AAC7F,2FAA2F;AAC3F,4FAA4F;AAC5F,uFAAuF;AACvF,6FAA6F;AAC7F,oFAAoF;AACpF,0FAA0F;AAC1F,4FAA4F;AAC5F,EAAE;AACF,oFAAoF;AACpF,6FAA6F;AAC7F,4FAA4F;AAC5F,8FAA8F;AAC9F,wCAAwC;AACxC,EAAE;AACF,gGAAgG;AAChG,gGAAgG;AAChG,gGAAgG;AAChG,8FAA8F;AAC9F,iGAAiG;AACjG,6FAA6F;AAC7F,+FAA+F;AAC/F,iGAAiG;AACjG,6FAA6F;AAC7F,gGAAgG;AAChG,oDAAoD;AACpD,EAAE;AACF,6FAA6F;AAC7F,qEAAqE;AACrE,2FAA2F;AAC3F,4FAA4F;AAC5F,iGAAiG;AACjG,0FAA0F;AAC1F,oFAAoF;AAIpF,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,2BAA2B,EAAmB,MAAM,kBAAkB,CAAC;AAChF,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAsB,MAAM,eAAe,CAAC;AAEzE,0FAA0F;AAC1F,oGAAoG;AACpG,0DAA0D;AAC1D,MAAM,CAAC,MAAM,eAAe,GAAG,2CAA2C,CAAC;AAY3E;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAAe,EAAE,YAAoB,EAAE,QAAgB;IAC3F,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAChD,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IACvC,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IAC9D,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;IACpE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC;AACrC,CAAC;
|
|
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
|
package/dist/catalog/sliceDoc.js
CHANGED
|
@@ -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":"AAAA,+BAA+B;AAC/B,yDAAyD;AACzD,2EAA2E;AAC3E,2EAA2E;AAC3E,8EAA8E;AAC9E,4EAA4E;AAC5E,8EAA8E;AAC9E,iEAAiE;AACjE,EAAE;AACF,2EAA2E;AAC3E,2EAA2E;AAC3E,6EAA6E;AAC7E,8EAA8E;AAC9E,2EAA2E;AAC3E,yEAAyE;AACzE,EAAE;AACF,oEAAoE;AACpE,wEAAwE;AACxE,kFAAkF;AAClF,8EAA8E;AAC9E,8EAA8E;AAC9E,6EAA6E;AAC7E,EAAE;AACF,8EAA8E;AAC9E,4EAA4E;AAC5E,4EAA4E;AAC5E,8EAA8E;AAC9E,0EAA0E;AAC1E,EAAE;AACF,4EAA4E;AAC5E,4FAA4F;AAC5F,qFAAqF;AACrF,8EAA8E;AAC9E,sFAAsF;AACtF,6CAA6C;
|
|
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;
|