@milehimikey/em 1.9.1 → 1.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/skills/event-modeling/SKILL.md +1 -1
- package/.claude/skills/event-modeling-conform/SKILL.md +5 -1
- package/.claude/skills/event-modeling-design/SKILL.md +31 -12
- package/.claude/skills/event-modeling-discover/SKILL.md +1 -1
- package/.claude/skills/event-modeling-implement/SKILL.md +14 -3
- package/.claude/skills/event-modeling-implement/reference/implement.md +73 -6
- package/.claude/skills/event-modeling-review/SKILL.md +14 -3
- package/.claude/skills/event-modeling-shared/reference/em-dsl.md +110 -11
- package/.claude/skills/event-modeling-shared/reference/slice-doc-schema.md +4 -1
- package/.claude/skills/event-modeling-shared/templates/constitution.md +111 -0
- package/.claude/skills/event-modeling-shared/templates/model-readme.md +2 -2
- package/.claude/skills/event-modeling-shared/templates/slice.md +4 -0
- package/README.md +8 -1
- package/dist/catalog/docJoin.d.ts +8 -0
- package/dist/catalog/docJoin.js +4 -0
- package/dist/catalog/docJoin.js.map +1 -1
- package/dist/catalog/sliceDoc.d.ts +8 -0
- package/dist/catalog/sliceDoc.js +2 -0
- package/dist/catalog/sliceDoc.js.map +1 -1
- package/dist/cli/ciInit.d.ts +10 -3
- package/dist/cli/ciInit.js +22 -14
- package/dist/cli/ciInit.js.map +1 -1
- package/dist/cli/ledgerCheck.d.ts +72 -0
- package/dist/cli/ledgerCheck.js +122 -1
- package/dist/cli/ledgerCheck.js.map +1 -1
- package/dist/cli/ratify.d.ts +37 -5
- package/dist/cli/ratify.js +106 -9
- package/dist/cli/ratify.js.map +1 -1
- package/dist/cli/reratify.js +14 -5
- package/dist/cli/reratify.js.map +1 -1
- package/dist/cli/review.d.ts +38 -0
- package/dist/cli/review.js +160 -0
- package/dist/cli/review.js.map +1 -0
- package/dist/cli/sliceIndex.d.ts +3 -0
- package/dist/cli/sliceIndex.js +5 -4
- package/dist/cli/sliceIndex.js.map +1 -1
- package/dist/cli/stateFile.d.ts +10 -0
- package/dist/cli/stateFile.js +14 -0
- package/dist/cli/stateFile.js.map +1 -1
- package/dist/cli/status.d.ts +44 -3
- package/dist/cli/status.js +75 -18
- package/dist/cli/status.js.map +1 -1
- package/dist/cli/systemInputs.d.ts +34 -0
- package/dist/cli/systemInputs.js +129 -0
- package/dist/cli/systemInputs.js.map +1 -0
- package/dist/cli.js +362 -23
- package/dist/cli.js.map +1 -1
- package/dist/emit/freshnessJson.d.ts +1 -1
- package/dist/emit/freshnessJson.js +5 -1
- package/dist/emit/freshnessJson.js.map +1 -1
- package/dist/emit/json.d.ts +37 -1
- package/dist/emit/json.js +67 -1
- package/dist/emit/json.js.map +1 -1
- package/dist/emit/ledgerJson.d.ts +1 -1
- package/dist/emit/ledgerJson.js +6 -1
- package/dist/emit/ledgerJson.js.map +1 -1
- package/dist/emit/queryJson.d.ts +6 -0
- package/dist/emit/queryJson.js +33 -0
- package/dist/emit/queryJson.js.map +1 -0
- package/dist/emit/statusJson.d.ts +1 -1
- package/dist/emit/statusJson.js +5 -1
- package/dist/emit/statusJson.js.map +1 -1
- package/dist/emit/systemJson.d.ts +8 -0
- package/dist/emit/systemJson.js +38 -0
- package/dist/emit/systemJson.js.map +1 -0
- package/dist/mcp/server.d.ts +1 -1
- package/dist/mcp/server.js +195 -9
- package/dist/mcp/server.js.map +1 -1
- package/dist/model/edges.d.ts +28 -1
- package/dist/model/edges.js +77 -15
- package/dist/model/edges.js.map +1 -1
- package/dist/model/model.d.ts +6 -0
- package/dist/model/model.js +2 -0
- package/dist/model/model.js.map +1 -1
- package/dist/model/qualifiedRef.d.ts +47 -0
- package/dist/model/qualifiedRef.js +100 -0
- package/dist/model/qualifiedRef.js.map +1 -0
- package/dist/model/queryIndex.d.ts +53 -0
- package/dist/model/queryIndex.js +114 -0
- package/dist/model/queryIndex.js.map +1 -0
- package/dist/model/rules.d.ts +88 -0
- package/dist/model/rules.js +101 -0
- package/dist/model/rules.js.map +1 -1
- package/dist/model/sliceDocIndex.d.ts +30 -0
- package/dist/model/sliceDocIndex.js +110 -0
- package/dist/model/sliceDocIndex.js.map +1 -0
- package/dist/model/validate.js +85 -11
- package/dist/model/validate.js.map +1 -1
- package/dist/parser/ast.d.ts +25 -0
- package/dist/parser/parser.d.ts +2 -0
- package/dist/parser/parser.js +104 -34
- package/dist/parser/parser.js.map +1 -1
- package/dist/query/format.d.ts +8 -0
- package/dist/query/format.js +80 -0
- package/dist/query/format.js.map +1 -0
- package/dist/query/pipeline.d.ts +17 -0
- package/dist/query/pipeline.js +38 -0
- package/dist/query/pipeline.js.map +1 -0
- package/dist/query/system.d.ts +60 -0
- package/dist/query/system.js +87 -0
- package/dist/query/system.js.map +1 -0
- package/dist/query/verbs.d.ts +100 -0
- package/dist/query/verbs.js +306 -0
- package/dist/query/verbs.js.map +1 -0
- package/dist/render/drawEdges.js +15 -4
- package/dist/render/drawEdges.js.map +1 -1
- package/dist/render/drawNotes.d.ts +13 -3
- package/dist/render/drawNotes.js +96 -20
- package/dist/render/drawNotes.js.map +1 -1
- package/dist/render/render.js +6 -5
- package/dist/render/render.js.map +1 -1
- package/dist/render/sliceDiagram.js +1 -0
- package/dist/render/sliceDiagram.js.map +1 -1
- package/dist/system/manifest.d.ts +45 -0
- package/dist/system/manifest.js +178 -0
- package/dist/system/manifest.js.map +1 -0
- package/dist/system/verify.d.ts +88 -0
- package/dist/system/verify.js +263 -0
- package/dist/system/verify.js.map +1 -0
- package/dist/templates.d.ts +14 -1
- package/dist/templates.js +134 -5
- package/dist/templates.js.map +1 -1
- package/dist/util/slug.js +16 -10
- package/dist/util/slug.js.map +1 -1
- package/package.json +10 -1
package/dist/model/rules.d.ts
CHANGED
|
@@ -68,6 +68,13 @@ export declare const RULES: {
|
|
|
68
68
|
readonly usageCategory: "event field not provided by command";
|
|
69
69
|
readonly docAnchor: "fields-completeness";
|
|
70
70
|
};
|
|
71
|
+
readonly "derived-from-unresolved": {
|
|
72
|
+
readonly severity: "error";
|
|
73
|
+
readonly title: "`derived from` names an unknown event";
|
|
74
|
+
readonly fix: "Name one of the view's actual sources, or drop the traced event from `derived from`.";
|
|
75
|
+
readonly usageCategory: "derived from names unresolved event";
|
|
76
|
+
readonly docAnchor: "fields-completeness";
|
|
77
|
+
};
|
|
71
78
|
readonly "reaction-from-unresolved": {
|
|
72
79
|
readonly severity: "error";
|
|
73
80
|
readonly title: "Unknown read-model source";
|
|
@@ -134,6 +141,18 @@ export declare const RULES: {
|
|
|
134
141
|
readonly fix: "Restructure so the target comes later.";
|
|
135
142
|
readonly usageCategory: "arrow points backward";
|
|
136
143
|
};
|
|
144
|
+
readonly "loops-to-forward": {
|
|
145
|
+
readonly severity: "error";
|
|
146
|
+
readonly title: "`loops-to` target not earlier on the timeline";
|
|
147
|
+
readonly fix: "Point `loops-to` at an earlier view, or use `from` on a later `view … again` instance instead.";
|
|
148
|
+
readonly usageCategory: "loops-to points forward";
|
|
149
|
+
};
|
|
150
|
+
readonly "loops-to-unresolved": {
|
|
151
|
+
readonly severity: "error";
|
|
152
|
+
readonly title: "`loops-to` target unresolved";
|
|
153
|
+
readonly fix: "Name a view that exists, or declare it before this event.";
|
|
154
|
+
readonly usageCategory: "loops-to target unresolved";
|
|
155
|
+
};
|
|
137
156
|
readonly "connection-legality/illegal-pair": {
|
|
138
157
|
readonly severity: "error";
|
|
139
158
|
readonly title: "Illegal connection";
|
|
@@ -323,12 +342,81 @@ export declare const RULES: {
|
|
|
323
342
|
readonly fix: "Rename the type so its export ref is unique.";
|
|
324
343
|
readonly usageCategory: "duplicate type ref";
|
|
325
344
|
};
|
|
345
|
+
readonly "duplicate-model-key": {
|
|
346
|
+
readonly severity: "warning";
|
|
347
|
+
readonly title: "Duplicate model key";
|
|
348
|
+
readonly fix: "Give each model a unique `model \"Name\"` so its key (and every cross-model ref) is stable.";
|
|
349
|
+
readonly usageCategory: "duplicate model key";
|
|
350
|
+
};
|
|
326
351
|
readonly "cross-model-slice-doc-collision": {
|
|
327
352
|
readonly severity: "warning";
|
|
328
353
|
readonly title: "Colliding slice doc path across models";
|
|
329
354
|
readonly fix: "Give each model its own directory (see docs/cli.md, \"Multi-model projects\").";
|
|
330
355
|
readonly usageCategory: "colliding slice doc path across models";
|
|
331
356
|
};
|
|
357
|
+
readonly "system-manifest-invalid": {
|
|
358
|
+
readonly severity: "error";
|
|
359
|
+
readonly title: "Seam manifest invalid";
|
|
360
|
+
readonly fix: "Fix the manifest: required keys, `systemSchemaVersion: \"1.0\"`, a readable `source` per model, and only declared model keys in seam refs.";
|
|
361
|
+
readonly usageCategory: "seam manifest invalid";
|
|
362
|
+
readonly docAnchor: "seam-manifest";
|
|
363
|
+
};
|
|
364
|
+
readonly "system-model-key-mismatch": {
|
|
365
|
+
readonly severity: "error";
|
|
366
|
+
readonly title: "Manifest model key differs from the export's `model.key`";
|
|
367
|
+
readonly fix: "Rename the manifest's `models:` key to the computed key the message prints.";
|
|
368
|
+
readonly usageCategory: "seam manifest model key mismatch";
|
|
369
|
+
readonly docAnchor: "seam-manifest";
|
|
370
|
+
};
|
|
371
|
+
readonly "seam-endpoint-unresolved": {
|
|
372
|
+
readonly severity: "error";
|
|
373
|
+
readonly title: "Seam endpoint does not resolve";
|
|
374
|
+
readonly fix: "Fix the ref to an element the named model actually exports (`em export` lists every ref), or re-declare the seam after a rename.";
|
|
375
|
+
readonly usageCategory: "seam endpoint unresolved";
|
|
376
|
+
readonly docAnchor: "seam-manifest";
|
|
377
|
+
};
|
|
378
|
+
readonly "seam-source-not-public": {
|
|
379
|
+
readonly severity: "error";
|
|
380
|
+
readonly title: "Seam source is not `public`";
|
|
381
|
+
readonly fix: "Mark the event/view `public` in its model, or point the seam at the element that is.";
|
|
382
|
+
readonly usageCategory: "seam source not public";
|
|
383
|
+
readonly docAnchor: "seam-manifest";
|
|
384
|
+
};
|
|
385
|
+
readonly "seam-consumer-not-reaction": {
|
|
386
|
+
readonly severity: "error";
|
|
387
|
+
readonly title: "Seam consumer is not a reaction";
|
|
388
|
+
readonly fix: "Point `to` at a translation/automation element (or a slice containing exactly one).";
|
|
389
|
+
readonly usageCategory: "seam consumer not a reaction";
|
|
390
|
+
readonly docAnchor: "seam-manifest";
|
|
391
|
+
};
|
|
392
|
+
readonly "seam-duplicate": {
|
|
393
|
+
readonly severity: "warning";
|
|
394
|
+
readonly title: "Duplicate seam";
|
|
395
|
+
readonly fix: "Remove the repeated `from`/`to` pair.";
|
|
396
|
+
readonly usageCategory: "duplicate seam";
|
|
397
|
+
readonly docAnchor: "seam-manifest";
|
|
398
|
+
};
|
|
399
|
+
readonly "dangling-public-event": {
|
|
400
|
+
readonly severity: "warning";
|
|
401
|
+
readonly title: "Public event/view no seam consumes";
|
|
402
|
+
readonly fix: "Declare the seam that reads it, or drop `public` if nothing outside the model does.";
|
|
403
|
+
readonly usageCategory: "public event not consumed by any seam";
|
|
404
|
+
readonly docAnchor: "seam-manifest";
|
|
405
|
+
};
|
|
406
|
+
readonly "unbound-translation": {
|
|
407
|
+
readonly severity: "warning";
|
|
408
|
+
readonly title: "Externally-fed reaction no seam feeds";
|
|
409
|
+
readonly fix: "Declare the seam whose `to` is this reaction, or give it an in-model `from`.";
|
|
410
|
+
readonly usageCategory: "externally-fed reaction not bound by any seam";
|
|
411
|
+
readonly docAnchor: "seam-manifest";
|
|
412
|
+
};
|
|
413
|
+
readonly "undeclared-seam-candidate": {
|
|
414
|
+
readonly severity: "warning";
|
|
415
|
+
readonly title: "Looks connected across models, no seam declared";
|
|
416
|
+
readonly fix: "Declare the seam, or rename one side so the name match stops looking like a link.";
|
|
417
|
+
readonly usageCategory: "undeclared seam candidate";
|
|
418
|
+
readonly docAnchor: "seam-manifest";
|
|
419
|
+
};
|
|
332
420
|
readonly "slice-ready-unknown-slice": {
|
|
333
421
|
readonly severity: "error";
|
|
334
422
|
readonly title: "Unknown --slice-ready key";
|
package/dist/model/rules.js
CHANGED
|
@@ -68,6 +68,13 @@ export const RULES = {
|
|
|
68
68
|
usageCategory: "event field not provided by command",
|
|
69
69
|
docAnchor: "fields-completeness",
|
|
70
70
|
},
|
|
71
|
+
"derived-from-unresolved": {
|
|
72
|
+
severity: "error",
|
|
73
|
+
title: "`derived from` names an unknown event",
|
|
74
|
+
fix: "Name one of the view's actual sources, or drop the traced event from `derived from`.",
|
|
75
|
+
usageCategory: "derived from names unresolved event",
|
|
76
|
+
docAnchor: "fields-completeness",
|
|
77
|
+
},
|
|
71
78
|
"reaction-from-unresolved": {
|
|
72
79
|
severity: "error",
|
|
73
80
|
title: "Unknown read-model source",
|
|
@@ -134,6 +141,18 @@ export const RULES = {
|
|
|
134
141
|
fix: "Restructure so the target comes later.",
|
|
135
142
|
usageCategory: "arrow points backward",
|
|
136
143
|
},
|
|
144
|
+
"loops-to-forward": {
|
|
145
|
+
severity: "error",
|
|
146
|
+
title: "`loops-to` target not earlier on the timeline",
|
|
147
|
+
fix: "Point `loops-to` at an earlier view, or use `from` on a later `view … again` instance instead.",
|
|
148
|
+
usageCategory: "loops-to points forward",
|
|
149
|
+
},
|
|
150
|
+
"loops-to-unresolved": {
|
|
151
|
+
severity: "error",
|
|
152
|
+
title: "`loops-to` target unresolved",
|
|
153
|
+
fix: "Name a view that exists, or declare it before this event.",
|
|
154
|
+
usageCategory: "loops-to target unresolved",
|
|
155
|
+
},
|
|
137
156
|
"connection-legality/illegal-pair": {
|
|
138
157
|
severity: "error",
|
|
139
158
|
title: "Illegal connection",
|
|
@@ -323,6 +342,17 @@ export const RULES = {
|
|
|
323
342
|
fix: "Rename the type so its export ref is unique.",
|
|
324
343
|
usageCategory: "duplicate type ref",
|
|
325
344
|
},
|
|
345
|
+
// MIL-193: two models in one multi-model invocation whose model keys (kebab-slugged declared
|
|
346
|
+
// names, model/qualifiedRef.ts) collide — the later one takes a `~n` suffix, exactly as
|
|
347
|
+
// `duplicate-slice-name` handles a slice-key collision. Raised by computeModelKeys(), which
|
|
348
|
+
// only ever runs where more than one model is in play (`em query`, MIL-194's `em system`);
|
|
349
|
+
// a single-model compile can never see it.
|
|
350
|
+
"duplicate-model-key": {
|
|
351
|
+
severity: "warning",
|
|
352
|
+
title: "Duplicate model key",
|
|
353
|
+
fix: "Give each model a unique `model \"Name\"` so its key (and every cross-model ref) is stable.",
|
|
354
|
+
usageCategory: "duplicate model key",
|
|
355
|
+
},
|
|
326
356
|
// MIL-160: two input models sharing a directory (so both resolve slice docs at
|
|
327
357
|
// `<that-directory>/slices/<key>.md`) whose compiled slice keys overlap — nothing before this
|
|
328
358
|
// caught it, since computeRefs() dedupes slice keys only within one model's own compile. Raised
|
|
@@ -336,6 +366,77 @@ export const RULES = {
|
|
|
336
366
|
fix: "Give each model its own directory (see docs/cli.md, \"Multi-model projects\").",
|
|
337
367
|
usageCategory: "colliding slice doc path across models",
|
|
338
368
|
},
|
|
369
|
+
// MIL-194: the nine codes `em system <manifest>` raises while verifying a seam manifest
|
|
370
|
+
// (docs/cli.md "em system") against each model's export document — the cross-model half of
|
|
371
|
+
// "both ends of a flow": every `public` event/view needs a declared reader somewhere in the
|
|
372
|
+
// system, every externally-fed reaction needs a declared producer. Raised by
|
|
373
|
+
// src/system/verify.ts (pure, over export JSON only — never a compiled model) and
|
|
374
|
+
// src/system/manifest.ts (the manifest's own shape). Registered here, like
|
|
375
|
+
// `cross-model-slice-doc-collision`, so severity/title/fix generate into the same reference
|
|
376
|
+
// tables every other code does; none of them is ever raised by `em validate` itself.
|
|
377
|
+
"system-manifest-invalid": {
|
|
378
|
+
severity: "error",
|
|
379
|
+
title: "Seam manifest invalid",
|
|
380
|
+
fix: "Fix the manifest: required keys, `systemSchemaVersion: \"1.0\"`, a readable `source` per model, and only declared model keys in seam refs.",
|
|
381
|
+
usageCategory: "seam manifest invalid",
|
|
382
|
+
docAnchor: "seam-manifest",
|
|
383
|
+
},
|
|
384
|
+
"system-model-key-mismatch": {
|
|
385
|
+
severity: "error",
|
|
386
|
+
title: "Manifest model key differs from the export's `model.key`",
|
|
387
|
+
fix: "Rename the manifest's `models:` key to the computed key the message prints.",
|
|
388
|
+
usageCategory: "seam manifest model key mismatch",
|
|
389
|
+
docAnchor: "seam-manifest",
|
|
390
|
+
},
|
|
391
|
+
"seam-endpoint-unresolved": {
|
|
392
|
+
severity: "error",
|
|
393
|
+
title: "Seam endpoint does not resolve",
|
|
394
|
+
fix: "Fix the ref to an element the named model actually exports (`em export` lists every ref), or re-declare the seam after a rename.",
|
|
395
|
+
usageCategory: "seam endpoint unresolved",
|
|
396
|
+
docAnchor: "seam-manifest",
|
|
397
|
+
},
|
|
398
|
+
"seam-source-not-public": {
|
|
399
|
+
severity: "error",
|
|
400
|
+
title: "Seam source is not `public`",
|
|
401
|
+
fix: "Mark the event/view `public` in its model, or point the seam at the element that is.",
|
|
402
|
+
usageCategory: "seam source not public",
|
|
403
|
+
docAnchor: "seam-manifest",
|
|
404
|
+
},
|
|
405
|
+
"seam-consumer-not-reaction": {
|
|
406
|
+
severity: "error",
|
|
407
|
+
title: "Seam consumer is not a reaction",
|
|
408
|
+
fix: "Point `to` at a translation/automation element (or a slice containing exactly one).",
|
|
409
|
+
usageCategory: "seam consumer not a reaction",
|
|
410
|
+
docAnchor: "seam-manifest",
|
|
411
|
+
},
|
|
412
|
+
"seam-duplicate": {
|
|
413
|
+
severity: "warning",
|
|
414
|
+
title: "Duplicate seam",
|
|
415
|
+
fix: "Remove the repeated `from`/`to` pair.",
|
|
416
|
+
usageCategory: "duplicate seam",
|
|
417
|
+
docAnchor: "seam-manifest",
|
|
418
|
+
},
|
|
419
|
+
"dangling-public-event": {
|
|
420
|
+
severity: "warning",
|
|
421
|
+
title: "Public event/view no seam consumes",
|
|
422
|
+
fix: "Declare the seam that reads it, or drop `public` if nothing outside the model does.",
|
|
423
|
+
usageCategory: "public event not consumed by any seam",
|
|
424
|
+
docAnchor: "seam-manifest",
|
|
425
|
+
},
|
|
426
|
+
"unbound-translation": {
|
|
427
|
+
severity: "warning",
|
|
428
|
+
title: "Externally-fed reaction no seam feeds",
|
|
429
|
+
fix: "Declare the seam whose `to` is this reaction, or give it an in-model `from`.",
|
|
430
|
+
usageCategory: "externally-fed reaction not bound by any seam",
|
|
431
|
+
docAnchor: "seam-manifest",
|
|
432
|
+
},
|
|
433
|
+
"undeclared-seam-candidate": {
|
|
434
|
+
severity: "warning",
|
|
435
|
+
title: "Looks connected across models, no seam declared",
|
|
436
|
+
fix: "Declare the seam, or rename one side so the name match stops looking like a link.",
|
|
437
|
+
usageCategory: "undeclared seam candidate",
|
|
438
|
+
docAnchor: "seam-manifest",
|
|
439
|
+
},
|
|
339
440
|
"slice-ready-unknown-slice": {
|
|
340
441
|
severity: "error",
|
|
341
442
|
title: "Unknown --slice-ready key",
|
package/dist/model/rules.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rules.js","sourceRoot":"","sources":["../../src/model/rules.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"rules.js","sourceRoot":"","sources":["../../src/model/rules.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { SliceDoc } from "../catalog/sliceDoc.js";
|
|
2
|
+
import { DriftSignalKind } from "../catalog/driftSignal.js";
|
|
3
|
+
import { Slice } from "./model.js";
|
|
4
|
+
/** Read + parse every `slices/*.md` file under `baseDir` exactly once, keyed by its filename
|
|
5
|
+
* stem (lowercased) — the same key `computeRefs()` assigns as a slice's export key. A missing
|
|
6
|
+
* `slices/` directory (routine — not every model has reached specify yet) returns an empty map,
|
|
7
|
+
* the same "nothing bound" state `readSliceDoc()` reports per-file via `null`. An individual
|
|
8
|
+
* file that fails to read (permissions, a broken symlink) is skipped rather than thrown —
|
|
9
|
+
* same silent-miss convention `readSliceDoc()` uses for a missing file. */
|
|
10
|
+
export declare function loadSliceDocsOnce(baseDir: string): Map<string, SliceDoc>;
|
|
11
|
+
/** A slice's query-facing doc join — deliberately narrower than `SliceDocExport`
|
|
12
|
+
* (`catalog/docJoin.ts`): only the facts `em query`'s verbs actually surface (declaring
|
|
13
|
+
* slice, doc path/status, drift, and the doc body for invariant-ID extraction), no lineage/
|
|
14
|
+
* ratification/owner fields. */
|
|
15
|
+
export interface SliceQueryDoc {
|
|
16
|
+
found: boolean;
|
|
17
|
+
path: string;
|
|
18
|
+
reason: "no-doc-bound" | "binding-missing-file" | "frontmatter-invalid" | null;
|
|
19
|
+
status: string | null;
|
|
20
|
+
implementedIn: string | null;
|
|
21
|
+
driftSignal: DriftSignalKind | null;
|
|
22
|
+
/** The doc's body text (post-frontmatter), for `extractInvariantIds()` — null whenever
|
|
23
|
+
* `found` is false or the frontmatter wasn't usable (nothing safe to scan). */
|
|
24
|
+
body: string | null;
|
|
25
|
+
}
|
|
26
|
+
/** Same resolution semantics as `docJoin.ts`'s resolveSliceDocJoin() — canonical `note` binding
|
|
27
|
+
* first, then a ratified MIL-121 cross-binding naming this slice in its `covers:` list — but
|
|
28
|
+
* reading from the in-memory map `loadSliceDocsOnce()` built once for the whole model, instead
|
|
29
|
+
* of one `readSliceDoc()` fs call per slice/candidate. */
|
|
30
|
+
export declare function joinSliceDocFast(slice: Slice, sliceKey: string, docsByKey: Map<string, SliceDoc>): SliceQueryDoc;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// A once-per-model slice-doc join for `em query` (MIL-168): the same canonical-then-
|
|
3
|
+
// MIL-121-cross-binding resolution `catalog/docJoin.ts`'s resolveSliceDocJoin() performs, but
|
|
4
|
+
// sourced from one `readdirSync(<baseDir>/slices/)` up front instead of one
|
|
5
|
+
// `existsSync`+`readFileSync` pair (`readSliceDoc.ts`) per slice/candidate. `em export`/`em
|
|
6
|
+
// status`/`em coverage` each call resolveSliceDocJoin() once per slice already and stay on that
|
|
7
|
+
// path unchanged (their per-slice cost is amortized across a single command run the same way);
|
|
8
|
+
// this module exists because `em query` builds one ModelIndex per compiled model and then
|
|
9
|
+
// answers many lookups against it, so paying the fs cost once, up front, per model — rather
|
|
10
|
+
// than once per slice scattered through the join — is the win at thousands-of-slices scale (see
|
|
11
|
+
// this ticket's report for the benchmark).
|
|
12
|
+
//
|
|
13
|
+
// Deliberately a read path, not a lint: unlike resolveSliceDocJoin(), this never raises a
|
|
14
|
+
// diagnostic for a missing-but-bound doc or invalid frontmatter — `em query` reports facts
|
|
15
|
+
// (`found`/`reason`), and leaves surfacing that as a warning to `em export`/`em status`, which
|
|
16
|
+
// already do.
|
|
17
|
+
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
18
|
+
import { join } from "node:path";
|
|
19
|
+
import { parseSliceDoc, hasUsableFrontmatter } from "../catalog/sliceDoc.js";
|
|
20
|
+
import { classifyImplementationDrift } from "../catalog/driftSignal.js";
|
|
21
|
+
import { NOTE_SLICE_PATH } from "../catalog/docJoin.js";
|
|
22
|
+
/** Matches a slice-doc filename (`slices/<key>.md`) — same kebab-slug grammar
|
|
23
|
+
* `catalog/sliceDoc.ts`'s SLICE_REF and `docJoin.ts`'s NOTE_SLICE_PATH use for the key itself. */
|
|
24
|
+
const SLICE_DOC_FILENAME_RE = /^([a-z0-9]+(?:-[a-z0-9]+)*)\.md$/i;
|
|
25
|
+
/** Read + parse every `slices/*.md` file under `baseDir` exactly once, keyed by its filename
|
|
26
|
+
* stem (lowercased) — the same key `computeRefs()` assigns as a slice's export key. A missing
|
|
27
|
+
* `slices/` directory (routine — not every model has reached specify yet) returns an empty map,
|
|
28
|
+
* the same "nothing bound" state `readSliceDoc()` reports per-file via `null`. An individual
|
|
29
|
+
* file that fails to read (permissions, a broken symlink) is skipped rather than thrown —
|
|
30
|
+
* same silent-miss convention `readSliceDoc()` uses for a missing file. */
|
|
31
|
+
export function loadSliceDocsOnce(baseDir) {
|
|
32
|
+
const docs = new Map();
|
|
33
|
+
let entries;
|
|
34
|
+
try {
|
|
35
|
+
entries = readdirSync(join(baseDir, "slices"));
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return docs;
|
|
39
|
+
}
|
|
40
|
+
const names = new Set(entries);
|
|
41
|
+
for (const name of entries) {
|
|
42
|
+
const m = SLICE_DOC_FILENAME_RE.exec(name);
|
|
43
|
+
if (!m)
|
|
44
|
+
continue;
|
|
45
|
+
const key = m[1].toLowerCase();
|
|
46
|
+
// `readSliceDoc()` opens `slices/<key>.md` with the lowercased key verbatim, so a mixed-case
|
|
47
|
+
// filename is only a doc where the filesystem itself folds case. If the exact lowercase
|
|
48
|
+
// file is its own directory entry (a case-sensitive fs holding both), that entry is the
|
|
49
|
+
// one readSliceDoc() reads — skip this one, whatever order readdir listed them in.
|
|
50
|
+
// Otherwise probe once — only for the rare mixed-case entry — so query and export agree
|
|
51
|
+
// on every platform.
|
|
52
|
+
if (m[1] !== key) {
|
|
53
|
+
if (names.has(`${key}.md`))
|
|
54
|
+
continue;
|
|
55
|
+
if (!existsSync(join(baseDir, "slices", `${key}.md`)))
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
try {
|
|
59
|
+
docs.set(key, parseSliceDoc(readFileSync(join(baseDir, "slices", name), "utf8")));
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
// unreadable — treated as "no doc" for this key, same as a fs error inside readSliceDoc().
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return docs;
|
|
66
|
+
}
|
|
67
|
+
/** Same resolution semantics as `docJoin.ts`'s resolveSliceDocJoin() — canonical `note` binding
|
|
68
|
+
* first, then a ratified MIL-121 cross-binding naming this slice in its `covers:` list — but
|
|
69
|
+
* reading from the in-memory map `loadSliceDocsOnce()` built once for the whole model, instead
|
|
70
|
+
* of one `readSliceDoc()` fs call per slice/candidate. */
|
|
71
|
+
export function joinSliceDocFast(slice, sliceKey, docsByKey) {
|
|
72
|
+
const path = `slices/${sliceKey}.md`;
|
|
73
|
+
const boundEls = slice.elements.filter((el) => el.note === path);
|
|
74
|
+
if (boundEls.length === 0) {
|
|
75
|
+
for (const el of slice.elements) {
|
|
76
|
+
if (!el.note)
|
|
77
|
+
continue;
|
|
78
|
+
const m = el.note.match(NOTE_SLICE_PATH);
|
|
79
|
+
if (!m)
|
|
80
|
+
continue;
|
|
81
|
+
const otherKey = m[1].toLowerCase();
|
|
82
|
+
if (otherKey === sliceKey)
|
|
83
|
+
continue;
|
|
84
|
+
const doc = docsByKey.get(otherKey);
|
|
85
|
+
if (!doc || !hasUsableFrontmatter(doc) || !doc.covers.includes(sliceKey))
|
|
86
|
+
continue;
|
|
87
|
+
return foundDoc(`slices/${otherKey}.md`, doc);
|
|
88
|
+
}
|
|
89
|
+
return { found: false, path, reason: "no-doc-bound", status: null, implementedIn: null, driftSignal: null, body: null };
|
|
90
|
+
}
|
|
91
|
+
const doc = docsByKey.get(sliceKey);
|
|
92
|
+
if (!doc)
|
|
93
|
+
return { found: false, path, reason: "binding-missing-file", status: null, implementedIn: null, driftSignal: null, body: null };
|
|
94
|
+
if (!hasUsableFrontmatter(doc)) {
|
|
95
|
+
return { found: true, path, reason: "frontmatter-invalid", status: null, implementedIn: null, driftSignal: null, body: null };
|
|
96
|
+
}
|
|
97
|
+
return foundDoc(path, doc);
|
|
98
|
+
}
|
|
99
|
+
function foundDoc(path, doc) {
|
|
100
|
+
return {
|
|
101
|
+
found: true,
|
|
102
|
+
path,
|
|
103
|
+
reason: null,
|
|
104
|
+
status: doc.status,
|
|
105
|
+
implementedIn: doc.implementedIn,
|
|
106
|
+
driftSignal: classifyImplementationDrift(doc),
|
|
107
|
+
body: doc.body,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=sliceDocIndex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sliceDocIndex.js","sourceRoot":"","sources":["../../src/model/sliceDocIndex.ts"],"names":[],"mappings":"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"}
|
package/dist/model/validate.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { AUTOMATION_KINDS } from "../parser/ast.js";
|
|
4
4
|
import { collectTags, normalizeName, resolveTypeRef } from "./model.js";
|
|
5
5
|
import { pushDiag } from "./rules.js";
|
|
6
|
+
import { connectionKind, resolveLoopsToTarget } from "./edges.js";
|
|
6
7
|
export function validate(model, grid, refs) {
|
|
7
8
|
const diags = [];
|
|
8
9
|
const refOf = (id) => refs.refById.get(id);
|
|
@@ -93,6 +94,9 @@ export function validate(model, grid, refs) {
|
|
|
93
94
|
// `{ fields }`: the view, and *every* source event. A partially-declared
|
|
94
95
|
// source set can't prove a gap (the fieldless event may well provide the
|
|
95
96
|
// field), so it stays silent rather than warning on legitimate fields.
|
|
97
|
+
// A field marked `derived` (MIL-200) opts out of this check entirely — it's the
|
|
98
|
+
// model's own record that the field is computed from which events have landed, not
|
|
99
|
+
// copied from a single source event's payload.
|
|
96
100
|
if (view.fields && view.fields.length > 0) {
|
|
97
101
|
const fromNames = view.from ?? [];
|
|
98
102
|
const sourceEvents = [];
|
|
@@ -111,6 +115,11 @@ export function validate(model, grid, refs) {
|
|
|
111
115
|
}
|
|
112
116
|
const eventList = fromNames.map((n) => `"${n}"`).join(", ");
|
|
113
117
|
for (const f of view.fields) {
|
|
118
|
+
// `derived` (bare or traced, MIL-200) marks a field as computed from which events
|
|
119
|
+
// have landed rather than copied from a single source event's payload — exempt
|
|
120
|
+
// from this check entirely, same posture as `assigned` below for event fields.
|
|
121
|
+
if (f.derived)
|
|
122
|
+
continue;
|
|
114
123
|
if (!fieldUnion.has(normalizeName(f.name))) {
|
|
115
124
|
pushDiag(diags, "fields-completeness/view-field-no-source", {
|
|
116
125
|
message: `view "${view.name}" field "${f.name}" has no source in ${eventList}`,
|
|
@@ -120,6 +129,28 @@ export function validate(model, grid, refs) {
|
|
|
120
129
|
}
|
|
121
130
|
}
|
|
122
131
|
}
|
|
132
|
+
// `derived from "Event A", "Event B"` (view fields only, MIL-200): the traced form
|
|
133
|
+
// still checks something — every named event must resolve among the view's ACTUAL
|
|
134
|
+
// sources, its `from` names, or (for a `from`-less view) the events in its own slice.
|
|
135
|
+
// Independent of `sourcesDeclareFields` above: this checks event *names*, not field
|
|
136
|
+
// completeness, so it applies whether or not the sources declare `{ fields }`.
|
|
137
|
+
const actualSourceEvents = fromNames.length > 0 ? sourceEvents : events;
|
|
138
|
+
const actualSourceNames = new Set(actualSourceEvents.map((e) => normalizeName(e.name)));
|
|
139
|
+
for (const f of view.fields) {
|
|
140
|
+
for (const name of f.derivedFrom ?? []) {
|
|
141
|
+
if (!actualSourceNames.has(normalizeName(name))) {
|
|
142
|
+
const actualList = actualSourceEvents.length > 0
|
|
143
|
+
? actualSourceEvents.map((e) => `"${e.name}"`).join(", ")
|
|
144
|
+
: "(none)";
|
|
145
|
+
pushDiag(diags, "derived-from-unresolved", {
|
|
146
|
+
message: `view "${view.name}" field "${f.name}" is derived from unknown event "${name}" — ` +
|
|
147
|
+
`its actual sources are ${actualList}`,
|
|
148
|
+
line: view.line,
|
|
149
|
+
refs: [refOf(view.id), ...actualSourceEvents.map((e) => refOf(e.id))],
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
123
154
|
}
|
|
124
155
|
}
|
|
125
156
|
// Fields completeness: every event field in a slice should trace to a field on
|
|
@@ -193,6 +224,45 @@ export function validate(model, grid, refs) {
|
|
|
193
224
|
}
|
|
194
225
|
}
|
|
195
226
|
}
|
|
227
|
+
// `loops-to "View"` (event only, MIL-199): a later fact re-feeding an earlier read model —
|
|
228
|
+
// the one loop-back device forward-only `from`/`arrow` can't express. The target must
|
|
229
|
+
// resolve to a `view` instance strictly EARLIER on the timeline; same-slice-or-later is
|
|
230
|
+
// what `from` on a later `view … again` instance is for.
|
|
231
|
+
for (const el of model.elements) {
|
|
232
|
+
if (el.kind !== "event")
|
|
233
|
+
continue;
|
|
234
|
+
for (const name of el.loopsTo ?? []) {
|
|
235
|
+
const bucket = model.byName.get(normalizeName(name));
|
|
236
|
+
const views = bucket?.filter((e) => e.kind === "view") ?? [];
|
|
237
|
+
if (views.length === 0) {
|
|
238
|
+
// Same courtesy as the reaction/view `from` checks above: a name that exists but as
|
|
239
|
+
// the wrong kind reads like a typo without saying so.
|
|
240
|
+
const other = bucket?.[0];
|
|
241
|
+
pushDiag(diags, "loops-to-unresolved", {
|
|
242
|
+
message: other
|
|
243
|
+
? `event "${el.name}" loops-to "${name}", which is a ${other.kind}, not a read model — ` +
|
|
244
|
+
`\`loops-to\` names the view this event re-feeds`
|
|
245
|
+
: `event "${el.name}" loops-to unknown read model "${name}"`,
|
|
246
|
+
line: el.line,
|
|
247
|
+
refs: other ? [refOf(el.id), refOf(other.id)] : [refOf(el.id)],
|
|
248
|
+
});
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
const target = resolveLoopsToTarget(model, el, name);
|
|
252
|
+
if (!target) {
|
|
253
|
+
const nearest = views
|
|
254
|
+
.filter((v) => v.sliceIndex >= el.sliceIndex)
|
|
255
|
+
.sort((a, b) => a.sliceIndex - b.sliceIndex)[0];
|
|
256
|
+
pushDiag(diags, "loops-to-forward", {
|
|
257
|
+
message: `time flows left to right: event "${el.name}" (slice ${el.sliceIndex + 1}) loops-to ` +
|
|
258
|
+
`"${name}" (slice ${nearest.sliceIndex + 1}), which is not earlier on the timeline — ` +
|
|
259
|
+
`that's what \`from\` on a later \`view ${name} again\` instance is for`,
|
|
260
|
+
line: el.line,
|
|
261
|
+
refs: [refOf(el.id), refOf(nearest.id)],
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
196
266
|
// A \`view X again\` instance needs an earlier declaration to continue.
|
|
197
267
|
for (const el of model.elements) {
|
|
198
268
|
if (el.kind === "view" && el.again && el.logicalId === el.id) {
|
|
@@ -396,6 +466,18 @@ export function validate(model, grid, refs) {
|
|
|
396
466
|
if (from?.kind === "event" && to?.kind === "view")
|
|
397
467
|
readEvents.add(normalizeName(from.name));
|
|
398
468
|
}
|
|
469
|
+
// A resolved `loops-to "View"` (MIL-199) counts as consumption too — the event re-feeds an
|
|
470
|
+
// earlier read model instead of a new one, but it's still read by something. An unresolved
|
|
471
|
+
// or forward target (already flagged above by its own rule) does not credit the event here;
|
|
472
|
+
// it stays reported as unread on top of its loops-to diagnostic rather than silently passing.
|
|
473
|
+
for (const el of model.elements) {
|
|
474
|
+
if (el.kind !== "event")
|
|
475
|
+
continue;
|
|
476
|
+
for (const name of el.loopsTo ?? []) {
|
|
477
|
+
if (resolveLoopsToTarget(model, el, name))
|
|
478
|
+
readEvents.add(normalizeName(el.name));
|
|
479
|
+
}
|
|
480
|
+
}
|
|
399
481
|
for (const el of model.elements) {
|
|
400
482
|
if (el.kind !== "event")
|
|
401
483
|
continue;
|
|
@@ -662,17 +744,9 @@ const isAuto = (k) => AUTOMATION_KINDS.has(k);
|
|
|
662
744
|
/** The only kind pairs a connection may take, per the four patterns: information enters the
|
|
663
745
|
* system through a command and leaves through a read model, and nothing skips a step. */
|
|
664
746
|
function isLegalFlow(from, to) {
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
return to === "event"; // State Change
|
|
669
|
-
if (from === "event")
|
|
670
|
-
return to === "view"; // State View
|
|
671
|
-
if (from === "view")
|
|
672
|
-
return to === "ui" || isAuto(to); // State View / Automation / Translation
|
|
673
|
-
if (isAuto(from))
|
|
674
|
-
return to === "command"; // reactions always go through a command
|
|
675
|
-
return false;
|
|
747
|
+
// The six legal connections are a pure function of the endpoint kinds — edges.ts owns the
|
|
748
|
+
// table (the renderer, `em query`, and this rule all read the same one).
|
|
749
|
+
return connectionKind(from, to) !== undefined;
|
|
676
750
|
}
|
|
677
751
|
/** Why a given illegal pair is illegal, and what to put in the gap. */
|
|
678
752
|
function flowGuidance(from, to) {
|