@primmel/primmel 1.8.2 → 1.9.1

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 (86) hide show
  1. package/dist/index.d.ts +1 -0
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +20 -2
  4. package/dist/index.js.map +1 -1
  5. package/dist/src/check-rules.d.ts.map +1 -1
  6. package/dist/src/check-rules.js +55 -0
  7. package/dist/src/check-rules.js.map +1 -1
  8. package/dist/src/check.d.ts +74 -2
  9. package/dist/src/check.d.ts.map +1 -1
  10. package/dist/src/check.js +514 -15
  11. package/dist/src/check.js.map +1 -1
  12. package/dist/src/export/impact.d.ts +45 -0
  13. package/dist/src/export/impact.d.ts.map +1 -0
  14. package/dist/src/export/impact.js +234 -0
  15. package/dist/src/export/impact.js.map +1 -0
  16. package/dist/src/export/rdf.d.ts.map +1 -1
  17. package/dist/src/export/rdf.js +4 -1
  18. package/dist/src/export/rdf.js.map +1 -1
  19. package/dist/src/export/retrieval.d.ts +408 -0
  20. package/dist/src/export/retrieval.d.ts.map +1 -0
  21. package/dist/src/export/retrieval.js +1156 -0
  22. package/dist/src/export/retrieval.js.map +1 -0
  23. package/dist/src/model-diff.d.ts +23 -0
  24. package/dist/src/model-diff.d.ts.map +1 -1
  25. package/dist/src/model-diff.js +132 -30
  26. package/dist/src/model-diff.js.map +1 -1
  27. package/dist/src/ser-des/config/calculation.d.ts.map +1 -1
  28. package/dist/src/ser-des/config/calculation.js +119 -4
  29. package/dist/src/ser-des/config/calculation.js.map +1 -1
  30. package/dist/src/ser-des/config/dimension.d.ts +12 -0
  31. package/dist/src/ser-des/config/dimension.d.ts.map +1 -0
  32. package/dist/src/ser-des/config/dimension.js +57 -0
  33. package/dist/src/ser-des/config/dimension.js.map +1 -0
  34. package/dist/src/ser-des/config/index.d.ts.map +1 -1
  35. package/dist/src/ser-des/config/index.js +5 -0
  36. package/dist/src/ser-des/config/index.js.map +1 -1
  37. package/dist/src/ser-des/config/packageManifest.d.ts.map +1 -1
  38. package/dist/src/ser-des/config/packageManifest.js +7 -1
  39. package/dist/src/ser-des/config/packageManifest.js.map +1 -1
  40. package/dist/src/ser-des/config/quantityRegister.d.ts.map +1 -1
  41. package/dist/src/ser-des/config/quantityRegister.js +38 -0
  42. package/dist/src/ser-des/config/quantityRegister.js.map +1 -1
  43. package/dist/src/ser-des/config/reference.d.ts.map +1 -1
  44. package/dist/src/ser-des/config/reference.js +18 -0
  45. package/dist/src/ser-des/config/reference.js.map +1 -1
  46. package/dist/src/ser-des/config/requirement.d.ts.map +1 -1
  47. package/dist/src/ser-des/config/requirement.js +47 -0
  48. package/dist/src/ser-des/config/requirement.js.map +1 -1
  49. package/dist/src/ser-des/config/subject.d.ts +10 -1
  50. package/dist/src/ser-des/config/subject.d.ts.map +1 -1
  51. package/dist/src/ser-des/config/subject.js +96 -63
  52. package/dist/src/ser-des/config/subject.js.map +1 -1
  53. package/dist/src/ser-des/config/term.d.ts.map +1 -1
  54. package/dist/src/ser-des/config/term.js +82 -20
  55. package/dist/src/ser-des/config/term.js.map +1 -1
  56. package/dist/src/ser-des/config/viewProfile.d.ts.map +1 -1
  57. package/dist/src/ser-des/config/viewProfile.js +22 -5
  58. package/dist/src/ser-des/config/viewProfile.js.map +1 -1
  59. package/dist/src/ser-des/parse-block.d.ts +1 -0
  60. package/dist/src/ser-des/parse-block.d.ts.map +1 -1
  61. package/dist/src/ser-des/parse-block.js +34 -0
  62. package/dist/src/ser-des/parse-block.js.map +1 -1
  63. package/dist/src/ser-des/parse.d.ts.map +1 -1
  64. package/dist/src/ser-des/parse.js +2 -0
  65. package/dist/src/ser-des/parse.js.map +1 -1
  66. package/dist/src/ser-des/types.d.ts +2 -1
  67. package/dist/src/ser-des/types.d.ts.map +1 -1
  68. package/dist/src/types/Calculation.d.ts +15 -0
  69. package/dist/src/types/Calculation.d.ts.map +1 -1
  70. package/dist/src/types/Package.d.ts +8 -0
  71. package/dist/src/types/Package.d.ts.map +1 -1
  72. package/dist/src/types/Quantity.d.ts +7 -0
  73. package/dist/src/types/Quantity.d.ts.map +1 -1
  74. package/dist/src/types/Reference.d.ts +11 -0
  75. package/dist/src/types/Reference.d.ts.map +1 -1
  76. package/dist/src/types/Requirement.d.ts +17 -0
  77. package/dist/src/types/Requirement.d.ts.map +1 -1
  78. package/dist/src/types/Standard.d.ts +2 -1
  79. package/dist/src/types/Standard.d.ts.map +1 -1
  80. package/dist/src/types/Subject.d.ts +10 -0
  81. package/dist/src/types/Subject.d.ts.map +1 -1
  82. package/dist/src/types/Term.d.ts +33 -1
  83. package/dist/src/types/Term.d.ts.map +1 -1
  84. package/dist-browser/index.mjs +1654 -1460
  85. package/dist-cli/primmel.mjs +2143 -188
  86. package/package.json +1 -1
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // scripts/check.mts
4
- import { existsSync as existsSync7, readdirSync as readdirSync5, statSync as statSync3, writeFileSync } from "node:fs";
5
- import { join as join6 } from "node:path";
4
+ import { existsSync as existsSync7, readdirSync as readdirSync6, statSync as statSync4, writeFileSync } from "node:fs";
5
+ import { join as join7 } from "node:path";
6
6
 
7
7
  // src/check.ts
8
8
  import { existsSync as existsSync5, readdirSync as readdirSync3, readFileSync as readFileSync5, statSync as statSync2 } from "fs";
@@ -266,6 +266,8 @@ function parse(mmelString, parsers, options = {}) {
266
266
  // Primmel v3.1 dataspace + trust (TODO.primmel/10)
267
267
  dataspaces: {},
268
268
  policies: {},
269
+ // Primmel v3.2 consumption constructs (TODO.primmel/11)
270
+ dimensions: {},
269
271
  // Issue collection (duplicate IDs, etc.)
270
272
  issues: []
271
273
  };
@@ -401,6 +403,16 @@ function resolve(ctx, resolvers) {
401
403
  }
402
404
 
403
405
  // src/ser-des/parse-block.ts
406
+ var ALIAS_FAMILY_KEYWORDS = /* @__PURE__ */ new Set([
407
+ "aliases",
408
+ "alt",
409
+ "colloquial",
410
+ "abbreviations",
411
+ "deprecated"
412
+ ]);
413
+ function isAliasFamilyKeyword(keyword) {
414
+ return ALIAS_FAMILY_KEYWORDS.has(keyword);
415
+ }
404
416
  function forEachEntry(data, visitor, errCtx) {
405
417
  if (data === "") {
406
418
  return;
@@ -432,6 +444,11 @@ function forEachEntry(data, visitor, errCtx) {
432
444
  i++;
433
445
  i++;
434
446
  }
447
+ } else if (isAliasFamilyKeyword(keyword)) {
448
+ i++;
449
+ if (!t[i - 1].startsWith("{") && t[i]?.startsWith("{")) {
450
+ i++;
451
+ }
435
452
  } else {
436
453
  i++;
437
454
  }
@@ -461,6 +478,15 @@ function skipUnknownValue(t, i, keyword) {
461
478
  }
462
479
  return i;
463
480
  }
481
+ if (isAliasFamilyKeyword(keyword)) {
482
+ if (i < t.length) {
483
+ i++;
484
+ }
485
+ if (!t[i - 1]?.startsWith("{") && t[i]?.startsWith("{")) {
486
+ i++;
487
+ }
488
+ return i;
489
+ }
464
490
  if (i < t.length) {
465
491
  i++;
466
492
  }
@@ -3224,6 +3250,12 @@ var parseReference = (id, data) => {
3224
3250
  ref.clause = unwrapBlock(t[i++]);
3225
3251
  } else if (keyword === "title") {
3226
3252
  ref.title = unwrapBlock(t[i++]);
3253
+ } else if (keyword === "org") {
3254
+ ref.org = unwrapBlock(t[i++]);
3255
+ } else if (keyword === "edition") {
3256
+ ref.edition = unwrapBlock(t[i++]);
3257
+ } else if (keyword === "urn") {
3258
+ ref.urn = unwrapBlock(t[i++]);
3227
3259
  } else {
3228
3260
  i++;
3229
3261
  }
@@ -3246,6 +3278,15 @@ var dumpReference = function(ref) {
3246
3278
  if (ref.title) {
3247
3279
  out += ' title "' + escapeString(ref.title) + '"\n';
3248
3280
  }
3281
+ if (ref.org) {
3282
+ out += ' org "' + escapeString(ref.org) + '"\n';
3283
+ }
3284
+ if (ref.edition) {
3285
+ out += ' edition "' + escapeString(ref.edition) + '"\n';
3286
+ }
3287
+ if (ref.urn) {
3288
+ out += ' urn "' + escapeString(ref.urn) + '"\n';
3289
+ }
3249
3290
  out += "}\n";
3250
3291
  return out;
3251
3292
  };
@@ -4370,6 +4411,9 @@ var dumpMapProfile = function(mp) {
4370
4411
  };
4371
4412
 
4372
4413
  // src/ser-des/config/viewProfile.ts
4414
+ function parseListFacet(v) {
4415
+ return v.startsWith("{") || v.startsWith("[") ? tokenizePackage(v).map(stripWrapping) : [stripWrapping(v)];
4416
+ }
4373
4417
  var parseViewProfile = function(id, data) {
4374
4418
  const result = {
4375
4419
  id,
@@ -4384,9 +4428,9 @@ var parseViewProfile = function(id, data) {
4384
4428
  if (command === "description") {
4385
4429
  result.description = unwrapped(value);
4386
4430
  } else if (command === "roles") {
4387
- result.roles = tokenizePackage(value());
4431
+ result.roles = parseListFacet(value());
4388
4432
  } else if (command === "visible") {
4389
- result.visibleElements = tokenizePackage(value());
4433
+ result.visibleElements = parseListFacet(value());
4390
4434
  } else if (command === "against") {
4391
4435
  result.against = value().trim();
4392
4436
  } else {
@@ -4404,13 +4448,13 @@ var parseViewProfile = function(id, data) {
4404
4448
  var dumpViewProfile = function(vp) {
4405
4449
  let out = "view_profile " + vp.id + " {\n";
4406
4450
  if (vp.description) {
4407
- out += ' description "' + vp.description + '"\n';
4451
+ out += ' description "' + escapeString(vp.description) + '"\n';
4408
4452
  }
4409
4453
  if (vp.roles.length > 0) {
4410
- out += " roles " + vp.roles.join(" ") + "\n";
4454
+ out += " roles { " + vp.roles.map(dumpBareSafe).join(" ") + " }\n";
4411
4455
  }
4412
4456
  if (vp.visibleElements.length > 0) {
4413
- out += " visible " + vp.visibleElements.join(" ") + "\n";
4457
+ out += " visible { " + vp.visibleElements.map(dumpBareSafe).join(" ") + " }\n";
4414
4458
  }
4415
4459
  if (vp.against) {
4416
4460
  out += " against " + vp.against + "\n";
@@ -5352,6 +5396,10 @@ function parseInputs(block) {
5352
5396
  let defaultValue = "";
5353
5397
  let hasDefault = false;
5354
5398
  let enumValues;
5399
+ let quantityKind;
5400
+ let rangeMin;
5401
+ let rangeMax;
5402
+ let hasRange = false;
5355
5403
  if (i < t.length && t[i].startsWith("{")) {
5356
5404
  const propBlock = unwrapBlock(t[i++]);
5357
5405
  const pt = tokenizePackage(propBlock);
@@ -5360,7 +5408,27 @@ function parseInputs(block) {
5360
5408
  const cmd = pt[j++];
5361
5409
  if (j < pt.length) {
5362
5410
  if (cmd === "unit") {
5363
- unit = unwrapBlock(pt[j++]);
5411
+ unit = stripWrapping(pt[j++]);
5412
+ } else if (cmd === "quantity_kind") {
5413
+ quantityKind = stripWrapping(pt[j++]);
5414
+ } else if (cmd === "range") {
5415
+ const rt = tokenizePackage(unwrapBlock(pt[j++]));
5416
+ let k = 0;
5417
+ while (k < rt.length) {
5418
+ const rc = rt[k++];
5419
+ if (k >= rt.length) {
5420
+ break;
5421
+ }
5422
+ if (rc === "min") {
5423
+ rangeMin = stripWrapping(rt[k++]);
5424
+ hasRange = true;
5425
+ } else if (rc === "max") {
5426
+ rangeMax = stripWrapping(rt[k++]);
5427
+ hasRange = true;
5428
+ } else {
5429
+ unwrapBlock(rt[k++]);
5430
+ }
5431
+ }
5364
5432
  } else if (cmd === "description") {
5365
5433
  description = unwrapBlock(pt[j++]);
5366
5434
  } else if (cmd === "default") {
@@ -5374,7 +5442,7 @@ function parseInputs(block) {
5374
5442
  }
5375
5443
  }
5376
5444
  }
5377
- inputs.push({
5445
+ const inp = {
5378
5446
  name,
5379
5447
  type,
5380
5448
  unit,
@@ -5382,7 +5450,20 @@ function parseInputs(block) {
5382
5450
  defaultValue,
5383
5451
  hasDefault,
5384
5452
  enumValues
5385
- });
5453
+ };
5454
+ if (quantityKind !== void 0) {
5455
+ inp.quantityKind = quantityKind;
5456
+ }
5457
+ if (hasRange) {
5458
+ inp.hasRange = true;
5459
+ if (rangeMin !== void 0) {
5460
+ inp.rangeMin = rangeMin;
5461
+ }
5462
+ if (rangeMax !== void 0) {
5463
+ inp.rangeMax = rangeMax;
5464
+ }
5465
+ }
5466
+ inputs.push(inp);
5386
5467
  }
5387
5468
  return inputs;
5388
5469
  }
@@ -5393,6 +5474,10 @@ function parseOutput(block) {
5393
5474
  let unit = "1";
5394
5475
  let name = "";
5395
5476
  let description = "";
5477
+ let quantityKind;
5478
+ let rangeMin;
5479
+ let rangeMax;
5480
+ let hasRange = false;
5396
5481
  if (t[i] === ":") {
5397
5482
  i++;
5398
5483
  }
@@ -5407,7 +5492,27 @@ function parseOutput(block) {
5407
5492
  const cmd = pt[j++];
5408
5493
  if (j < pt.length) {
5409
5494
  if (cmd === "unit") {
5410
- unit = unwrapBlock(pt[j++]);
5495
+ unit = stripWrapping(pt[j++]);
5496
+ } else if (cmd === "quantity_kind") {
5497
+ quantityKind = stripWrapping(pt[j++]);
5498
+ } else if (cmd === "range") {
5499
+ const rt = tokenizePackage(unwrapBlock(pt[j++]));
5500
+ let k = 0;
5501
+ while (k < rt.length) {
5502
+ const rc = rt[k++];
5503
+ if (k >= rt.length) {
5504
+ break;
5505
+ }
5506
+ if (rc === "min") {
5507
+ rangeMin = stripWrapping(rt[k++]);
5508
+ hasRange = true;
5509
+ } else if (rc === "max") {
5510
+ rangeMax = stripWrapping(rt[k++]);
5511
+ hasRange = true;
5512
+ } else {
5513
+ unwrapBlock(rt[k++]);
5514
+ }
5515
+ }
5411
5516
  } else if (cmd === "name") {
5412
5517
  name = stripWrapping(pt[j++]);
5413
5518
  } else if (cmd === "description") {
@@ -5425,6 +5530,18 @@ function parseOutput(block) {
5425
5530
  if (description) {
5426
5531
  out.description = description;
5427
5532
  }
5533
+ if (quantityKind !== void 0) {
5534
+ out.quantityKind = quantityKind;
5535
+ }
5536
+ if (hasRange) {
5537
+ out.hasRange = true;
5538
+ if (rangeMin !== void 0) {
5539
+ out.rangeMin = rangeMin;
5540
+ }
5541
+ if (rangeMax !== void 0) {
5542
+ out.rangeMax = rangeMax;
5543
+ }
5544
+ }
5428
5545
  return out;
5429
5546
  }
5430
5547
  function parseLookup(block) {
@@ -5494,6 +5611,9 @@ var dumpCalculation = function(c) {
5494
5611
  for (const inp of c.inputs) {
5495
5612
  let line = " " + inp.name + " : " + inp.type + " { ";
5496
5613
  line += 'unit "' + escapeString(inp.unit) + '"';
5614
+ if (inp.quantityKind) {
5615
+ line += " quantity_kind " + inp.quantityKind;
5616
+ }
5497
5617
  if (inp.description) {
5498
5618
  line += ' description "' + escapeString(inp.description) + '"';
5499
5619
  }
@@ -5503,18 +5623,41 @@ var dumpCalculation = function(c) {
5503
5623
  if (inp.enumValues && inp.enumValues.length > 0) {
5504
5624
  line += " enum_values { " + inp.enumValues.join(" ") + " }";
5505
5625
  }
5626
+ if (inp.hasRange) {
5627
+ line += " range {";
5628
+ if (inp.rangeMin) {
5629
+ line += " min " + dumpBareSafe(inp.rangeMin);
5630
+ }
5631
+ if (inp.rangeMax) {
5632
+ line += " max " + dumpBareSafe(inp.rangeMax);
5633
+ }
5634
+ line += " }";
5635
+ }
5506
5636
  line += " }\n";
5507
5637
  out += line;
5508
5638
  }
5509
5639
  out += " }\n";
5510
5640
  }
5511
5641
  let outputLine = " output : " + c.output.type + ' { unit "' + escapeString(c.output.unit) + '"';
5642
+ if (c.output.quantityKind) {
5643
+ outputLine += " quantity_kind " + c.output.quantityKind;
5644
+ }
5512
5645
  if (c.output.name) {
5513
5646
  outputLine += ' name "' + escapeString(c.output.name) + '"';
5514
5647
  }
5515
5648
  if (c.output.description) {
5516
5649
  outputLine += ' description "' + escapeString(c.output.description) + '"';
5517
5650
  }
5651
+ if (c.output.hasRange) {
5652
+ outputLine += " range {";
5653
+ if (c.output.rangeMin) {
5654
+ outputLine += " min " + dumpBareSafe(c.output.rangeMin);
5655
+ }
5656
+ if (c.output.rangeMax) {
5657
+ outputLine += " max " + dumpBareSafe(c.output.rangeMax);
5658
+ }
5659
+ outputLine += " }";
5660
+ }
5518
5661
  out += outputLine + " }\n";
5519
5662
  if (c.expression) {
5520
5663
  out += ' expression "' + escapeString(c.expression) + '"\n';
@@ -7694,6 +7837,25 @@ var dumpConformanceTest = function(ct) {
7694
7837
  };
7695
7838
 
7696
7839
  // src/ser-des/config/term.ts
7840
+ var ALIAS_KEYWORDS = {
7841
+ aliases: "aliases",
7842
+ alt: "aliases",
7843
+ colloquial: "colloquial",
7844
+ abbreviations: "abbreviations",
7845
+ deprecated: "deprecated"
7846
+ };
7847
+ function isAliasKeyword(command) {
7848
+ return command in ALIAS_KEYWORDS;
7849
+ }
7850
+ function appendAliasEntries(term, facet, entries) {
7851
+ if (facet === "aliases") {
7852
+ const merged = [...term.aliases ?? [], ...entries];
7853
+ term.aliases = merged;
7854
+ term.alt = merged;
7855
+ } else {
7856
+ (term[facet] ??= []).push(...entries);
7857
+ }
7858
+ }
7697
7859
  var parseTerm = function(id, data) {
7698
7860
  const result = {
7699
7861
  id,
@@ -7764,12 +7926,28 @@ var parseTerm = function(id, data) {
7764
7926
  result.formType = unwrapped(value);
7765
7927
  } else if (command === "part_of_speech") {
7766
7928
  result.partOfSpeech = unwrapped(value);
7767
- } else if (command === "alt") {
7768
- result.alt = tokenizePackage(value()).map(stripWrapping);
7769
- } else if (command === "deprecated") {
7770
- result.deprecated = tokenizePackage(value()).map(stripWrapping);
7771
- } else if (command === "abbreviations") {
7772
- result.abbreviations = tokenizePackage(value()).map(stripWrapping);
7929
+ } else if (isAliasKeyword(command)) {
7930
+ const first = value();
7931
+ let spelling;
7932
+ let listToken = first;
7933
+ if (!first.startsWith("{")) {
7934
+ spelling = first;
7935
+ const next = peek();
7936
+ if (next === void 0 || !next.startsWith("{")) {
7937
+ throw new Error(
7938
+ `Parsing error: term. ID ${id}: alias-family facet "${command}" with spelling code "${spelling}" expects a list block`
7939
+ );
7940
+ }
7941
+ listToken = value();
7942
+ }
7943
+ const entries = tokenizePackage(listToken).map(stripWrapping);
7944
+ const facet = ALIAS_KEYWORDS[command];
7945
+ if (spelling === void 0) {
7946
+ appendAliasEntries(result, facet, entries);
7947
+ } else {
7948
+ const variant = (result.aliasSpellings ??= {})[spelling] ??= {};
7949
+ (variant[facet] ??= []).push(...entries);
7950
+ }
7773
7951
  } else if (command === "see_also") {
7774
7952
  result.seeAlso = tokenizePackage(value()).map(stripWrapping);
7775
7953
  } else {
@@ -7826,14 +8004,33 @@ var dumpTerm = function(term) {
7826
8004
  out += ' part_of_speech "' + escapeString(term.partOfSpeech) + '"\n';
7827
8005
  }
7828
8006
  const listEntry = (s) => /\s/.test(s) ? '"' + escapeString(s) + '"' : s;
7829
- if (term.alt && term.alt.length > 0) {
7830
- out += " alt { " + term.alt.map(listEntry).join(" ") + " }\n";
8007
+ const aliasLine = (facet, list, tag) => " " + facet + (tag ? " " + tag : "") + " { " + list.map(listEntry).join(" ") + " }\n";
8008
+ const aliases = term.aliases ?? term.alt;
8009
+ if (aliases && aliases.length > 0) {
8010
+ out += aliasLine("aliases", aliases);
7831
8011
  }
7832
- if (term.deprecated && term.deprecated.length > 0) {
7833
- out += " deprecated { " + term.deprecated.map(listEntry).join(" ") + " }\n";
8012
+ if (term.colloquial && term.colloquial.length > 0) {
8013
+ out += aliasLine("colloquial", term.colloquial);
7834
8014
  }
7835
8015
  if (term.abbreviations && term.abbreviations.length > 0) {
7836
- out += " abbreviations { " + term.abbreviations.map(listEntry).join(" ") + " }\n";
8016
+ out += aliasLine("abbreviations", term.abbreviations);
8017
+ }
8018
+ if (term.deprecated && term.deprecated.length > 0) {
8019
+ out += aliasLine("deprecated", term.deprecated);
8020
+ }
8021
+ for (const code of Object.keys(term.aliasSpellings ?? {}).sort()) {
8022
+ const variant = term.aliasSpellings[code];
8023
+ for (const facet of [
8024
+ "aliases",
8025
+ "colloquial",
8026
+ "abbreviations",
8027
+ "deprecated"
8028
+ ]) {
8029
+ const list = variant[facet];
8030
+ if (list && list.length > 0) {
8031
+ out += aliasLine(facet, list, code);
8032
+ }
8033
+ }
7837
8034
  }
7838
8035
  if (term.seeAlso && term.seeAlso.length > 0) {
7839
8036
  out += " see_also { " + term.seeAlso.map(listEntry).join(" ") + " }\n";
@@ -8720,6 +8917,7 @@ function readLimit(block) {
8720
8917
  relativeTo: "",
8721
8918
  notes: "",
8722
8919
  accepts: null,
8920
+ quantity: null,
8723
8921
  acceptance: null,
8724
8922
  sourceDiscrepancy: null
8725
8923
  };
@@ -8740,6 +8938,24 @@ function readLimit(block) {
8740
8938
  limit.relativeTo = stripWrapping(t[i++]);
8741
8939
  } else if (cmd === "notes") {
8742
8940
  limit.notes = stripWrapping(t[i++]);
8941
+ } else if (cmd === "quantity") {
8942
+ const quantity = { kind: "", unit: "" };
8943
+ const qt = tokenize(unwrapBlock(t[i++]));
8944
+ let k = 0;
8945
+ while (k < qt.length) {
8946
+ const qc = qt[k++];
8947
+ if (k >= qt.length) {
8948
+ break;
8949
+ }
8950
+ if (qc === "kind") {
8951
+ quantity.kind = stripWrapping(qt[k++]);
8952
+ } else if (qc === "unit") {
8953
+ quantity.unit = stripWrapping(qt[k++]);
8954
+ } else {
8955
+ unwrapBlock(qt[k++]);
8956
+ }
8957
+ }
8958
+ limit.quantity = quantity;
8743
8959
  } else if (cmd === "accepts") {
8744
8960
  limit.accepts = readAccepts(unwrapBlock(t[i++]));
8745
8961
  } else if (cmd === "acceptance") {
@@ -8812,7 +9028,8 @@ function readParameters(block) {
8812
9028
  rangeMin: "",
8813
9029
  rangeMax: "",
8814
9030
  hasRange: false,
8815
- enumValues: []
9031
+ enumValues: [],
9032
+ bind: ""
8816
9033
  };
8817
9034
  if (i < t.length && !t[i].startsWith("{")) {
8818
9035
  param.type = stripWrapping(t[i++]);
@@ -8829,6 +9046,8 @@ function readParameters(block) {
8829
9046
  param.description = stripWrapping(pt[j++]);
8830
9047
  } else if (pc === "unit") {
8831
9048
  param.unit = stripWrapping(pt[j++]);
9049
+ } else if (pc === "bind") {
9050
+ param.bind = stripWrapping(pt[j++]);
8832
9051
  } else if (pc === "default") {
8833
9052
  param.defaultValue = stripWrapping(pt[j++]);
8834
9053
  param.hasDefault = true;
@@ -8975,6 +9194,16 @@ function dumpLimit(limit) {
8975
9194
  if (limit.notes) {
8976
9195
  out += ' notes "' + escapeString(limit.notes) + '"\n';
8977
9196
  }
9197
+ if (limit.quantity) {
9198
+ let line = " quantity {";
9199
+ if (limit.quantity.kind) {
9200
+ line += " kind " + limit.quantity.kind;
9201
+ }
9202
+ if (limit.quantity.unit) {
9203
+ line += ' unit "' + escapeString(limit.quantity.unit) + '"';
9204
+ }
9205
+ out += line + " }\n";
9206
+ }
8978
9207
  if (limit.accepts) {
8979
9208
  const a = limit.accepts;
8980
9209
  let line = " accepts { verdict " + a.verdict;
@@ -9036,6 +9265,9 @@ var dumpRequirement = function(r) {
9036
9265
  if (p.unit) {
9037
9266
  line += 'unit "' + escapeString(p.unit) + '" ';
9038
9267
  }
9268
+ if (p.bind) {
9269
+ line += 'bind "' + escapeString(p.bind) + '" ';
9270
+ }
9039
9271
  if (p.hasDefault) {
9040
9272
  line += "default " + dumpBareSafe(p.defaultValue) + " ";
9041
9273
  }
@@ -9298,6 +9530,8 @@ var parsePackage = function(data) {
9298
9530
  manifest.supersedes = readUrnList(t[i++]);
9299
9531
  } else if (cmd === "replaces") {
9300
9532
  manifest.replaces = readUrnList(t[i++]);
9533
+ } else if (cmd === "superseded_by") {
9534
+ manifest.supersededBy = readUrnList(t[i++]);
9301
9535
  } else if (cmd === "validity") {
9302
9536
  const vblock = unwrapBlock(t[i++]);
9303
9537
  const vt = tokenize(vblock);
@@ -10155,6 +10389,14 @@ function parseDimension(id, block) {
10155
10389
  dim.source = readSource(unwrapBlock(t[i++]));
10156
10390
  } else if (cmd === "values") {
10157
10391
  dim.values = parseDimensionValues(unwrapBlock(t[i++]));
10392
+ } else if (cmd === "values_of") {
10393
+ dim.valuesOf = stripWrapping(t[i++]);
10394
+ } else if (cmd === "ref") {
10395
+ const r = parseRef(t, i, stripWrapping, unwrapBlock);
10396
+ if (!foldRefIntoLegacy(dim, r.ref)) {
10397
+ (dim.refs ??= []).push(r.ref);
10398
+ }
10399
+ i = r.next;
10158
10400
  } else {
10159
10401
  i = skipUnknownValue(t, i, cmd);
10160
10402
  }
@@ -10236,6 +10478,73 @@ function parseDimensionValues(block) {
10236
10478
  }
10237
10479
  return out;
10238
10480
  }
10481
+ function dumpDimension(d, indent) {
10482
+ const inner = indent + " ";
10483
+ const valueIndent = indent + " ";
10484
+ let out = indent + "dimension " + d.id + " {\n";
10485
+ if (d.label) {
10486
+ out += inner + 'label "' + escapeString(d.label) + '"\n';
10487
+ }
10488
+ if (d.scope) {
10489
+ out += inner + "scope " + d.scope + "\n";
10490
+ }
10491
+ if (d.cardinality) {
10492
+ out += inner + "cardinality " + d.cardinality + "\n";
10493
+ }
10494
+ if (d.labelSeparator) {
10495
+ out += inner + 'label_separator "' + escapeString(d.labelSeparator) + '"\n';
10496
+ }
10497
+ if (d.description) {
10498
+ out += inner + 'description "' + escapeString(d.description) + '"\n';
10499
+ }
10500
+ out += dumpSource("reference", d.source, inner);
10501
+ if (d.valuesOf) {
10502
+ out += inner + "values_of " + d.valuesOf + "\n";
10503
+ }
10504
+ if (d.values.length > 0) {
10505
+ out += inner + "values {\n";
10506
+ for (const v of d.values) {
10507
+ let line = valueIndent + v.id;
10508
+ const hasProps = v.label || v.description || v.termRef || Object.keys(v.payload).length > 0 || v.implies.length > 0;
10509
+ if (hasProps) {
10510
+ line += " { ";
10511
+ if (v.label) {
10512
+ line += 'label "' + escapeString(v.label) + '" ';
10513
+ }
10514
+ if (v.description) {
10515
+ line += 'description "' + escapeString(v.description) + '" ';
10516
+ }
10517
+ if (v.termRef) {
10518
+ line += "term_ref " + v.termRef + " ";
10519
+ }
10520
+ if (v.implies.length > 0) {
10521
+ line += "implies { " + v.implies.join(" ") + " } ";
10522
+ }
10523
+ if (Object.keys(v.payload).length > 0) {
10524
+ line += "payload { ";
10525
+ for (const [k, val] of Object.entries(v.payload)) {
10526
+ if (typeof val === "object" && val !== null) {
10527
+ line += k + " { ";
10528
+ for (const [nk, nv] of Object.entries(val)) {
10529
+ line += nk + ': "' + escapeString(String(nv)) + '" ';
10530
+ }
10531
+ line += "} ";
10532
+ } else {
10533
+ line += k + ': "' + escapeString(String(val)) + '" ';
10534
+ }
10535
+ }
10536
+ line += "} ";
10537
+ }
10538
+ line += "}";
10539
+ }
10540
+ out += line + "\n";
10541
+ }
10542
+ out += inner + "}\n";
10543
+ }
10544
+ out += dumpRefs(d.refs, inner, escapeString);
10545
+ out += indent + "}\n";
10546
+ return out;
10547
+ }
10239
10548
  function parseModelGroup(block) {
10240
10549
  const mg = {
10241
10550
  definition: "",
@@ -10374,64 +10683,7 @@ var dumpInstrument = function(inst) {
10374
10683
  out += line + "}\n";
10375
10684
  }
10376
10685
  for (const d of inst.dimensions) {
10377
- out += " dimension " + d.id + " {\n";
10378
- if (d.label) {
10379
- out += ' label "' + escapeString(d.label) + '"\n';
10380
- }
10381
- if (d.scope) {
10382
- out += " scope " + d.scope + "\n";
10383
- }
10384
- if (d.cardinality) {
10385
- out += " cardinality " + d.cardinality + "\n";
10386
- }
10387
- if (d.labelSeparator) {
10388
- out += ' label_separator "' + escapeString(d.labelSeparator) + '"\n';
10389
- }
10390
- if (d.description) {
10391
- out += ' description "' + escapeString(d.description) + '"\n';
10392
- }
10393
- out += dumpSource("reference", d.source, " ");
10394
- if (d.values.length > 0) {
10395
- out += " values {\n";
10396
- for (const v of d.values) {
10397
- let line = " " + v.id;
10398
- const hasProps = v.label || v.description || v.termRef || Object.keys(v.payload).length > 0 || v.implies.length > 0;
10399
- if (hasProps) {
10400
- line += " { ";
10401
- if (v.label) {
10402
- line += 'label "' + escapeString(v.label) + '" ';
10403
- }
10404
- if (v.description) {
10405
- line += 'description "' + escapeString(v.description) + '" ';
10406
- }
10407
- if (v.termRef) {
10408
- line += "term_ref " + v.termRef + " ";
10409
- }
10410
- if (v.implies.length > 0) {
10411
- line += "implies { " + v.implies.join(" ") + " } ";
10412
- }
10413
- if (Object.keys(v.payload).length > 0) {
10414
- line += "payload { ";
10415
- for (const [k, val] of Object.entries(v.payload)) {
10416
- if (typeof val === "object" && val !== null) {
10417
- line += k + " { ";
10418
- for (const [nk, nv] of Object.entries(val)) {
10419
- line += nk + ': "' + escapeString(String(nv)) + '" ';
10420
- }
10421
- line += "} ";
10422
- } else {
10423
- line += k + ': "' + escapeString(String(val)) + '" ';
10424
- }
10425
- }
10426
- line += "} ";
10427
- }
10428
- line += "}";
10429
- }
10430
- out += line + "\n";
10431
- }
10432
- out += " }\n";
10433
- }
10434
- out += " }\n";
10686
+ out += dumpDimension(d, " ");
10435
10687
  }
10436
10688
  if (inst.familyMetamodelClass || inst.familyDefinition || inst.familyNote || inst.familySource && (inst.familySource.doc || inst.familySource.clause)) {
10437
10689
  out += " family {\n";
@@ -12875,6 +13127,10 @@ function parseKind(id, block) {
12875
13127
  out.siUnit = stripWrapping(t[i++]);
12876
13128
  } else if (cmd === "description") {
12877
13129
  out.description = stripWrapping(t[i++]);
13130
+ } else if (cmd === "corresponds") {
13131
+ const { corr, next } = parseCorresponds(t, i, stripWrapping);
13132
+ (out.correspondences ??= []).push(corr);
13133
+ i = next;
12878
13134
  } else {
12879
13135
  unwrapBlock(t[i++]);
12880
13136
  }
@@ -12910,6 +13166,10 @@ function parseUnit(id, block) {
12910
13166
  out.offsetToSI = readNumber(t[i++], 0);
12911
13167
  } else if (cmd === "definition") {
12912
13168
  out.definition = stripWrapping(t[i++]);
13169
+ } else if (cmd === "corresponds") {
13170
+ const { corr, next } = parseCorresponds(t, i, stripWrapping);
13171
+ (out.correspondences ??= []).push(corr);
13172
+ i = next;
12913
13173
  } else {
12914
13174
  unwrapBlock(t[i++]);
12915
13175
  }
@@ -12945,6 +13205,24 @@ var parseQuantityRegister = function(id, data) {
12945
13205
  return ctx;
12946
13206
  };
12947
13207
  };
13208
+ function dumpCorrespondencesInline(corrs) {
13209
+ let out = "";
13210
+ for (const c of corrs ?? []) {
13211
+ out += " corresponds " + dumpBareSafe(c.scheme) + ' "' + escapeString(c.concept) + '"';
13212
+ if (c.projections.length > 0) {
13213
+ out += " {";
13214
+ for (const p of c.projections) {
13215
+ out += " projection " + dumpBareSafe(p.codec) + " {";
13216
+ for (const e of p.entries) {
13217
+ out += " " + dumpBareSafe(e.key) + " " + dumpBareSafe(e.value);
13218
+ }
13219
+ out += " }";
13220
+ }
13221
+ out += " }";
13222
+ }
13223
+ }
13224
+ return out;
13225
+ }
12948
13226
  function dumpDimensions(dimensions) {
12949
13227
  const keys = Object.keys(dimensions);
12950
13228
  if (keys.length === 0) {
@@ -12962,6 +13240,7 @@ var dumpQuantityRegister = function(reg) {
12962
13240
  if (k.description) {
12963
13241
  line += ' description "' + escapeString(k.description) + '"';
12964
13242
  }
13243
+ line += dumpCorrespondencesInline(k.correspondences);
12965
13244
  out += line + " }\n";
12966
13245
  }
12967
13246
  for (const u of reg.units) {
@@ -12984,6 +13263,7 @@ var dumpQuantityRegister = function(reg) {
12984
13263
  if (u.definition) {
12985
13264
  line += ' definition "' + escapeString(u.definition) + '"';
12986
13265
  }
13266
+ line += dumpCorrespondencesInline(u.correspondences);
12987
13267
  out += line + " }\n";
12988
13268
  }
12989
13269
  if (reg.referenceIds.length > 0) {
@@ -13442,6 +13722,25 @@ var policyConstruct = {
13442
13722
  dump: dumpPolicy
13443
13723
  };
13444
13724
 
13725
+ // src/ser-des/config/dimension.ts
13726
+ var parseTopLevelDimension = function(id, data) {
13727
+ const dim = parseDimension(id, unwrapBlock(data));
13728
+ return (ctx) => {
13729
+ ctx.dimensions[id] = dim;
13730
+ return ctx;
13731
+ };
13732
+ };
13733
+ var dumpTopLevelDimension = function(d) {
13734
+ return dumpDimension(d, "");
13735
+ };
13736
+ var dimensionConstruct = {
13737
+ keyword: "dimension",
13738
+ field: "dimensions",
13739
+ takesID: true,
13740
+ parse: parseTopLevelDimension,
13741
+ dump: dumpTopLevelDimension
13742
+ };
13743
+
13445
13744
  // src/ser-des/config/activityArchetype.ts
13446
13745
  var parseActivityArchetype = (id, data) => {
13447
13746
  const archetype = {
@@ -13859,7 +14158,11 @@ var CONSTRUCTS = [
13859
14158
  // sub-structures (config/trustRef.ts, config/correspondence.ts), not
13860
14159
  // top-level constructs.
13861
14160
  dataspaceConstruct,
13862
- policyConstruct
14161
+ policyConstruct,
14162
+ // Primmel v3.2 consumption constructs (TODO.primmel/11; MN 114 clause
14163
+ // 10.6): the top-level applicability dimension (one grammar with the
14164
+ // instrument's inline dimension blocks, two placements).
14165
+ dimensionConstruct
13863
14166
  ];
13864
14167
  function buildParserConfig(constructs) {
13865
14168
  const out = {};
@@ -14005,6 +14308,9 @@ function packageFiles(dir) {
14005
14308
  }
14006
14309
  return files;
14007
14310
  }
14311
+ function loadPackage(dir, options = {}) {
14312
+ return loadPackageInternal(dir, options).standard;
14313
+ }
14008
14314
  function countNewlines(text) {
14009
14315
  let n = 0;
14010
14316
  for (let i = 0; i < text.length; i++) {
@@ -15160,30 +15466,38 @@ var GENERIC_ANCHOR = [
15160
15466
  "conformanceProcessIds"
15161
15467
  ];
15162
15468
  function provenanceOf(el) {
15163
- const out = [];
15164
- const push = (r) => {
15469
+ const channels = {};
15470
+ const push = (channel, r) => {
15165
15471
  if (r && typeof r === "object" && (r.doc || r.clause)) {
15166
- out.push(normalizeSourceRef(r.doc ?? "", r.clause ?? "", r.fragment));
15472
+ (channels[channel] ??= []).push(
15473
+ normalizeSourceRef(r.doc ?? "", r.clause ?? "", r.fragment)
15474
+ );
15167
15475
  }
15168
15476
  };
15169
- push(el.source);
15170
- push(el.sourceRef);
15477
+ push("source", el.source);
15478
+ push("sourceRef", el.sourceRef);
15171
15479
  for (const r of el.sourceRefs ?? []) {
15172
- push(r);
15480
+ push("sourceRefs", r);
15173
15481
  }
15174
15482
  const refString = el.reference;
15175
15483
  if (typeof refString === "string" && refString.startsWith("urn:")) {
15176
- push({ doc: refString, clause: "" });
15484
+ push("reference", { doc: refString, clause: "" });
15177
15485
  }
15178
- const seen = /* @__PURE__ */ new Set();
15179
- return out.filter((r) => {
15180
- const k = provenanceEdgeKey(r);
15181
- if (seen.has(k)) {
15182
- return false;
15183
- }
15184
- seen.add(k);
15185
- return true;
15186
- });
15486
+ const dedup = (rs) => {
15487
+ const seen = /* @__PURE__ */ new Set();
15488
+ return rs.filter((r) => {
15489
+ const k = provenanceEdgeKey(r);
15490
+ if (seen.has(k)) {
15491
+ return false;
15492
+ }
15493
+ seen.add(k);
15494
+ return true;
15495
+ });
15496
+ };
15497
+ for (const [channel, rs] of Object.entries(channels)) {
15498
+ channels[channel] = dedup(rs);
15499
+ }
15500
+ return { edges: dedup(Object.values(channels).flat()), channels };
15187
15501
  }
15188
15502
  function provenanceEdgeKey(r) {
15189
15503
  return canonical({ basis: r.basis, clause: r.clause, fragment: r.fragment });
@@ -15191,26 +15505,28 @@ function provenanceEdgeKey(r) {
15191
15505
  function elementOf(field, el) {
15192
15506
  const id = String(el.id ?? el.entityName ?? "");
15193
15507
  const tier = TIER_BY_FIELD[field] ?? "cross-cutting";
15194
- const provenance = provenanceOf(el);
15508
+ const { edges: provenance, channels: provenanceChannels } = provenanceOf(el);
15195
15509
  const consumed = new Set(PROVENANCE_FIELDS);
15196
15510
  if (typeof el.reference === "string" && el.reference.startsWith("urn:")) {
15197
15511
  consumed.add("reference");
15198
15512
  }
15513
+ const fields = {};
15199
15514
  const aspects = {};
15200
15515
  const spec = ASPECT_SPECS[field];
15201
- const pick = (fields) => {
15516
+ const pick = (names) => {
15202
15517
  const out = {};
15203
- for (const f of fields) {
15518
+ for (const f of names) {
15204
15519
  if (el[f] !== void 0) {
15205
15520
  out[f] = el[f];
15206
15521
  consumed.add(f);
15522
+ fields[f] = el[f];
15207
15523
  }
15208
15524
  }
15209
15525
  return out;
15210
15526
  };
15211
15527
  if (spec) {
15212
- for (const [aspect, fields] of Object.entries(spec)) {
15213
- const picked = pick(fields ?? []);
15528
+ for (const [aspect, names] of Object.entries(spec)) {
15529
+ const picked = pick(names ?? []);
15214
15530
  if (Object.keys(picked).length > 0) {
15215
15531
  aspects[aspect] = canonical(picked);
15216
15532
  }
@@ -15220,10 +15536,9 @@ function elementOf(field, el) {
15220
15536
  const entries = el.entries ?? [];
15221
15537
  for (const e of entries) {
15222
15538
  if (e && typeof e.spelling === "string") {
15223
- aspects[`spelling:${e.spelling}`] = canonical({
15224
- value: e.value,
15225
- via: e.via
15226
- });
15539
+ const entry = { value: e.value, via: e.via };
15540
+ aspects[`spelling:${e.spelling}`] = canonical(entry);
15541
+ fields[`spelling:${e.spelling}`] = entry;
15227
15542
  }
15228
15543
  }
15229
15544
  } else {
@@ -15244,15 +15559,31 @@ function elementOf(field, el) {
15244
15559
  fragment: r.fragment
15245
15560
  }))
15246
15561
  );
15562
+ for (const [channel, edges] of Object.entries(provenanceChannels)) {
15563
+ fields[channel] = edges.map((r) => ({
15564
+ basis: r.basis,
15565
+ clause: r.clause,
15566
+ fragment: r.fragment
15567
+ }));
15568
+ }
15247
15569
  }
15248
15570
  const rest = {};
15249
15571
  for (const [k, v] of Object.entries(el)) {
15250
15572
  if (!consumed.has(k) && k !== "id") {
15251
15573
  rest[k] = v;
15574
+ fields[k] = v;
15252
15575
  }
15253
15576
  }
15254
15577
  aspects.structure = canonical(rest);
15255
- return { key: `${field}:${id}`, id, kind: field, tier, aspects, provenance };
15578
+ return {
15579
+ key: `${field}:${id}`,
15580
+ id,
15581
+ kind: field,
15582
+ tier,
15583
+ aspects,
15584
+ fields,
15585
+ provenance
15586
+ };
15256
15587
  }
15257
15588
  function elementIndex(standard, duplicates) {
15258
15589
  const out = /* @__PURE__ */ new Map();
@@ -15490,6 +15821,46 @@ function labelAspect(elA, elB, name) {
15490
15821
  }
15491
15822
  return `${name} (changed)`;
15492
15823
  }
15824
+ var isPlainObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
15825
+ function fieldDiffPaths(prefix, a, b, out) {
15826
+ if (isPlainObject(a) && isPlainObject(b)) {
15827
+ const keys = [.../* @__PURE__ */ new Set([...Object.keys(a), ...Object.keys(b)])].sort();
15828
+ for (const k of keys) {
15829
+ fieldDiffPaths(`${prefix}.${k}`, a[k], b[k], out);
15830
+ }
15831
+ return;
15832
+ }
15833
+ if (canonical(a) !== canonical(b)) {
15834
+ out.push(prefix);
15835
+ }
15836
+ }
15837
+ function changedFields(elA, elB) {
15838
+ const names = [
15839
+ .../* @__PURE__ */ new Set([...Object.keys(elA.fields), ...Object.keys(elB.fields)])
15840
+ ].sort();
15841
+ const out = [];
15842
+ for (const name of names) {
15843
+ fieldDiffPaths(name, elA.fields[name], elB.fields[name], out);
15844
+ }
15845
+ const PROVENANCE_CHANNELS = [
15846
+ "source",
15847
+ "sourceRef",
15848
+ "sourceRefs",
15849
+ "reference"
15850
+ ];
15851
+ const seenMoves = /* @__PURE__ */ new Set();
15852
+ return out.filter((path) => {
15853
+ if (!PROVENANCE_CHANNELS.includes(path)) {
15854
+ return true;
15855
+ }
15856
+ const move = canonical(elA.fields[path]) + " \u2192 " + canonical(elB.fields[path]);
15857
+ if (seenMoves.has(move)) {
15858
+ return false;
15859
+ }
15860
+ seenMoves.add(move);
15861
+ return true;
15862
+ });
15863
+ }
15493
15864
  function diffStandards(a, b, options = {}) {
15494
15865
  const duplicatesA = [];
15495
15866
  const duplicatesB = [];
@@ -15547,7 +15918,8 @@ function diffStandards(a, b, options = {}) {
15547
15918
  id: elA.id,
15548
15919
  kind: elA.kind,
15549
15920
  tier: elA.tier,
15550
- aspects: differing.map((name) => labelAspect(elA, elB, name)).sort()
15921
+ aspects: differing.map((name) => labelAspect(elA, elB, name)).sort(),
15922
+ fields: changedFields(elA, elB)
15551
15923
  });
15552
15924
  tally[elA.tier].changed++;
15553
15925
  }
@@ -15630,7 +16002,9 @@ function formatDiffReport(diff) {
15630
16002
  if (diff.changed.length > 0) {
15631
16003
  lines.push("", "changed:");
15632
16004
  for (const e of diff.changed) {
15633
- lines.push(` ~ ${fmtEntry(e)} \u2014 ${e.aspects.join(", ")}`);
16005
+ lines.push(
16006
+ ` ~ ${fmtEntry(e)} \u2014 ${e.aspects.join(", ")} (fields: ${e.fields.join(", ")})`
16007
+ );
15634
16008
  }
15635
16009
  }
15636
16010
  if (diff.moved.length > 0) {
@@ -16371,6 +16745,22 @@ var CHECK_RULES = [
16371
16745
  "normal",
16372
16746
  "TODO.roadmap/28, INV-8, doctrine \xA713.5"
16373
16747
  ),
16748
+ // ── the v3.2 lineage edge (TODO.primmel/11; MN 114 v3.2 clause 9.3.1,
16749
+ // primmel/spec#18) ──
16750
+ // C113: the lineage graph is the union of the backward edges
16751
+ // (supersedes/replaces) and the forward edge (superseded_by); when two
16752
+ // composed packages declare opposite edges between the same pair the
16753
+ // declarations must agree — A supersedes { B } while B declares
16754
+ // superseded_by { C } without A is an error. A missing forward edge is
16755
+ // NOT an error: the backward edges remain the authored minimum.
16756
+ R(
16757
+ "C113",
16758
+ "edition-lineage-coherent",
16759
+ "edition",
16760
+ "error",
16761
+ "normal",
16762
+ "TODO.primmel/11, MN 114 clause 9.3.1 (primmel/spec#18 ask 3)"
16763
+ ),
16374
16764
  // ── the model supply chain (TODO.roadmap/36, doctrine ch. 15) ───────
16375
16765
  // Three publishers — standard (reference), manufacturer (product
16376
16766
  // reference), user (implementation) — with mapping as the only
@@ -16710,6 +17100,108 @@ var CHECK_RULES = [
16710
17100
  "normal",
16711
17101
  "docs/primmel/18 \xA718.6 (the unified reference/relation construct)"
16712
17102
  ),
17103
+ // ── the v3.2 consumption constructs (TODO.primmel/11; MN 114 v3.2,
17104
+ // primmel/spec#18) ──
17105
+ // C110: the term alias family's shape (clause 13.10.1) — duplicate
17106
+ // entries within one list are errors; the same string in two family
17107
+ // fields of one term and the label echo are warning legs during the
17108
+ // v3.2 rollout (the v2 `alt` semantics allowed the overlap; the
17109
+ // cross-field leg tightens to the spec's error when the consumer wave
17110
+ // re-authors the estate's terms — TODO.primmel/11d).
17111
+ R(
17112
+ "C110",
17113
+ "term-alias-shape",
17114
+ "base",
17115
+ "error",
17116
+ "normal",
17117
+ "TODO.primmel/11, MN 114 clause 13.10.1 (primmel/spec#18 ask 1)"
17118
+ ),
17119
+ // C111: the dimension declaration's shape (clause 10.6) — value ids
17120
+ // unique within a dimension, implies targets resolving inside their
17121
+ // own dimension and acyclic, values vs values_of never combined, an
17122
+ // undocumented values_of register warned, and one dimension identifier
17123
+ // once per applicability namespace (the is_dimension-attribute/inline
17124
+ // mirror pattern tolerated — R 144's power_supply precedent).
17125
+ R(
17126
+ "C111",
17127
+ "dimension-shape",
17128
+ "base",
17129
+ "error",
17130
+ "normal",
17131
+ "TODO.primmel/11, MN 114 clause 10.6 (primmel/spec#18 ask 2)"
17132
+ ),
17133
+ // C112: the structured reference identity (clause 14.7) — a malformed
17134
+ // urn is an error (the same well-formedness class as C85); a reference
17135
+ // carrying neither urn nor the org+document pair is a warning (a
17136
+ // display-string citation is visible debt, never silently citable).
17137
+ R(
17138
+ "C112",
17139
+ "reference-identity",
17140
+ "base",
17141
+ "error",
17142
+ "normal",
17143
+ "TODO.primmel/11, MN 114 clause 14.7 (primmel/spec#18 ask 3)"
17144
+ ),
17145
+ // C114: the limit's quantity typing agrees with the verdict it binds
17146
+ // (clause 11.1.2) — a limit and its acceptance chain can never drift
17147
+ // apart in units. C115: the calculation signature (clause 13.7.1) —
17148
+ // units and quantity kinds resolve against the merged quantity register
17149
+ // and agree in kind, a range's min never exceeds its max, and an
17150
+ // enum-typed input declares its values. The unit-resolution leg ships
17151
+ // as a WARNING during the v3.2 rollout (the C33 doctrine §6.8
17152
+ // precedent: unmapped units are warnings — the estate's R 60 declares
17153
+ // counts/v on inputs no register carries; the leg tightens to the
17154
+ // spec's error when the register catches up — TODO.primmel/11d).
17155
+ R(
17156
+ "C114",
17157
+ "limit-quantity-coherence",
17158
+ "quantities",
17159
+ "error",
17160
+ "normal",
17161
+ "TODO.primmel/11, MN 114 clause 11.1.2 (primmel/spec#18 ask 4)"
17162
+ ),
17163
+ R(
17164
+ "C115",
17165
+ "calculation-signature-shape",
17166
+ "quantities",
17167
+ "error",
17168
+ "normal",
17169
+ "TODO.primmel/11, MN 114 clause 13.7.1 (primmel/spec#18 ask 4)"
17170
+ ),
17171
+ // C116/C117: the verdict chain (clause 11.3) — a verdict's inputs may
17172
+ // name another verdict, making the acceptance chain an explicit graph.
17173
+ // Every input resolves to a declared symbol, a test variable or
17174
+ // observable, or another verdict; the verdict→verdict graph never
17175
+ // cycles. C118: the instance-parameter schema (clause 11.1.3) — a
17176
+ // parameter's bind path resolves against the subject's aspect catalog
17177
+ // (the binds_to path discipline), its unit resolves against the merged
17178
+ // quantity register (the rollout WARNING leg, the C33 §6.8 precedent —
17179
+ // tightens with C115's leg, TODO.primmel/11d), and a range's min never
17180
+ // exceeds its max.
17181
+ R(
17182
+ "C116",
17183
+ "verdict-inputs-resolve",
17184
+ "characteristics",
17185
+ "error",
17186
+ "normal",
17187
+ "TODO.primmel/11, MN 114 clause 11.3 (primmel/spec#18 ask 5)"
17188
+ ),
17189
+ R(
17190
+ "C117",
17191
+ "verdict-chain-acyclic",
17192
+ "characteristics",
17193
+ "error",
17194
+ "normal",
17195
+ "TODO.primmel/11, MN 114 clause 11.3 (primmel/spec#18 ask 5)"
17196
+ ),
17197
+ R(
17198
+ "C118",
17199
+ "requirement-parameter-shape",
17200
+ "base",
17201
+ "error",
17202
+ "normal",
17203
+ "TODO.primmel/11, MN 114 clause 11.1.3 (primmel/spec#18 ask 5)"
17204
+ ),
16713
17205
  // ── the dataspace family (TODO.primmel/10; MN 114 v3.1 clause 19) ──
16714
17206
  // The v3.1 extension set: the dataspace definition, the policy
16715
17207
  // construct (Primmel's own policy grammar; ODRL is a codec output),
@@ -17500,12 +17992,12 @@ function uncoveredSentenceMessage(urn, s) {
17500
17992
  const text = s.text.length > 100 ? `${s.text.slice(0, 97)}\u2026` : s.text;
17501
17993
  return `sentence ${urn}#${s.address} (normative, ${s.kind}): bound by no model element and excluded by no allowance \u2014 "${text}" (text-coverage-sentence-uncovered)`;
17502
17994
  }
17503
- function packageTextCoverageReport(dir, loadPackage) {
17995
+ function packageTextCoverageReport(dir, loadPackage2) {
17504
17996
  const { manifests, config, issues } = loadTextCoverageData(dir);
17505
17997
  if (manifests.length === 0) {
17506
17998
  return null;
17507
17999
  }
17508
- const { standard } = loadPackage(dir);
18000
+ const { standard } = loadPackage2(dir);
17509
18001
  const report = computeTextCoverage(standard, manifests, config);
17510
18002
  report.configIssues.unshift(...issues);
17511
18003
  return report;
@@ -17720,6 +18212,10 @@ function checkPackage(dir, options = {}) {
17720
18212
  issues.push(...checkEditionLifecycle(dir, standard));
17721
18213
  issues.push(...checkSpellingCodes(standard));
17722
18214
  issues.push(...checkDeclaredPredicates(standard));
18215
+ issues.push(...checkTermAliases(standard));
18216
+ issues.push(...checkDimensions(standard));
18217
+ issues.push(...checkReferences(standard));
18218
+ issues.push(...checkVerdictChains(standard));
17723
18219
  const reqIds = new Set(
17724
18220
  (standard.requirements ?? []).map((r) => r.id)
17725
18221
  );
@@ -17738,6 +18234,7 @@ function checkPackage(dir, options = {}) {
17738
18234
  const symbolIds = new Set((standard.symbols ?? []).map((s) => s.id));
17739
18235
  const dimIds = /* @__PURE__ */ new Map();
17740
18236
  const dimCardinality = /* @__PURE__ */ new Map();
18237
+ const dimCardinalityOpen = /* @__PURE__ */ new Set();
17741
18238
  for (const inst of standard.instruments ?? []) {
17742
18239
  for (const d of inst.dimensions ?? []) {
17743
18240
  dimIds.set(d.id, new Set(d.values.map((v) => v.id)));
@@ -17746,6 +18243,31 @@ function checkPackage(dir, options = {}) {
17746
18243
  }
17747
18244
  }
17748
18245
  }
18246
+ for (const a of standard.attributeDefinitions ?? []) {
18247
+ if (a.isDimension !== true || dimIds.has(a.id)) {
18248
+ continue;
18249
+ }
18250
+ const enumDef = (standard.enums ?? []).find((e) => e.id === a.enumRef);
18251
+ const domain = enumDef ? new Set(enumDef.values.map((v) => v.id)) : a.enumValues && a.enumValues.length > 0 ? new Set(a.enumValues) : null;
18252
+ dimIds.set(a.id, domain);
18253
+ dimCardinalityOpen.add(a.id);
18254
+ }
18255
+ for (const d of standard.dimensions ?? []) {
18256
+ if (dimIds.has(d.id)) {
18257
+ continue;
18258
+ }
18259
+ if (d.valuesOf) {
18260
+ dimIds.set(
18261
+ d.id,
18262
+ d.valuesOf === "capabilities" ? new Set((standard.capabilities ?? []).map((c) => c.id)) : null
18263
+ );
18264
+ } else {
18265
+ dimIds.set(d.id, new Set(d.values.map((v) => v.id)));
18266
+ }
18267
+ if (d.cardinality) {
18268
+ dimCardinality.set(d.id, d.cardinality);
18269
+ }
18270
+ }
17749
18271
  for (const form of standard.forms ?? []) {
17750
18272
  const checkField = (f) => {
17751
18273
  if (f.bind) {
@@ -17876,7 +18398,7 @@ function checkPackage(dir, options = {}) {
17876
18398
  "C3",
17877
18399
  `conformance test ${t.id}: test_subject dimension "${dim}" not declared`
17878
18400
  );
17879
- } else if (!dimIds.get(dim).has(String(value))) {
18401
+ } else if (dimIds.get(dim) !== null && !dimIds.get(dim).has(String(value))) {
17880
18402
  err(
17881
18403
  "C3",
17882
18404
  `conformance test ${t.id}: test_subject ${dim}="${value}" not in the dimension's values`
@@ -17895,15 +18417,24 @@ function checkPackage(dir, options = {}) {
17895
18417
  `requirement ${r.id}: applicability dimension "${a.dimension}" not declared`
17896
18418
  );
17897
18419
  } else {
18420
+ const domain = dimIds.get(a.dimension) ?? null;
17898
18421
  for (const v of a.values ?? []) {
17899
- if (!dimIds.get(a.dimension).has(v)) {
18422
+ if (domain !== null && !domain.has(v)) {
17900
18423
  err(
17901
18424
  "C3",
17902
18425
  `requirement ${r.id}: applicability ${a.dimension}="${v}" not in the dimension's values`
17903
18426
  );
17904
18427
  }
17905
18428
  }
17906
- if ((a.match === "all" || a.match === "exact") && dimCardinality.get(a.dimension) !== "set") {
18429
+ for (const k of Object.keys(a.mapping ?? {})) {
18430
+ if (domain !== null && !domain.has(k)) {
18431
+ err(
18432
+ "C3",
18433
+ `requirement ${r.id}: applicability ${a.dimension} mapping key "${k}" not in the dimension's values`
18434
+ );
18435
+ }
18436
+ }
18437
+ if ((a.match === "all" || a.match === "exact") && dimCardinality.get(a.dimension) !== "set" && !dimCardinalityOpen.has(a.dimension)) {
17907
18438
  warn(
17908
18439
  "C3",
17909
18440
  `requirement ${r.id}: applicability ${a.dimension} match ${a.match} on a single-cardinality dimension \u2014 only meaningful on set dimensions ('all' reduces to 'any'; a multi-value 'exact' is unsatisfiable on one value)`
@@ -20080,14 +20611,151 @@ function checkPackage(dir, options = {}) {
20080
20611
  );
20081
20612
  }
20082
20613
  }
20083
- for (const d of standard.duals ?? []) {
20084
- if (d.attribute && !attrIds.has(d.attribute)) {
20085
- err(
20086
- "C34",
20087
- `dual ${d.id}: attribute "${d.attribute}" is not a declared attribute_definition (duality-coherence)`
20088
- );
20614
+ for (const r of standard.requirements ?? []) {
20615
+ const q = r.limit?.quantity;
20616
+ const accepts = r.limit?.accepts;
20617
+ if (!q || !accepts) {
20618
+ continue;
20089
20619
  }
20090
- if (!d.designed && !d.exhibited) {
20620
+ const verdict = (standard.verdicts ?? []).find(
20621
+ (v) => v.id === accepts.verdict
20622
+ );
20623
+ if (!verdict) {
20624
+ continue;
20625
+ }
20626
+ if (q.kind && verdict.quantityKind && q.kind !== verdict.quantityKind) {
20627
+ err(
20628
+ "C114",
20629
+ `requirement ${r.id}: limit declares quantity kind "${q.kind}" but accepts verdict ${verdict.id} derives kind "${verdict.quantityKind}" \u2014 a limit and its acceptance chain never drift apart in units (limit-quantity-coherence)`
20630
+ );
20631
+ }
20632
+ if (q.unit && verdict.unit && q.unit !== verdict.unit) {
20633
+ err(
20634
+ "C114",
20635
+ `requirement ${r.id}: limit declares quantity unit "${q.unit}" but accepts verdict ${verdict.id} derives unit "${verdict.unit}" (limit-quantity-coherence)`
20636
+ );
20637
+ }
20638
+ }
20639
+ for (const c of standard.calculations ?? []) {
20640
+ const entries = [
20641
+ ...(c.inputs ?? []).map((inp) => ({
20642
+ owner: `calculation ${c.id}: input ${inp.name}`,
20643
+ type: inp.type,
20644
+ unit: inp.unit,
20645
+ isInput: true,
20646
+ quantityKind: inp.quantityKind,
20647
+ rangeMin: inp.rangeMin,
20648
+ rangeMax: inp.rangeMax,
20649
+ hasRange: inp.hasRange,
20650
+ enumValues: inp.enumValues
20651
+ })),
20652
+ {
20653
+ owner: `calculation ${c.id}: output`,
20654
+ type: c.output.type,
20655
+ unit: c.output.unit,
20656
+ isInput: false,
20657
+ quantityKind: c.output.quantityKind,
20658
+ rangeMin: c.output.rangeMin,
20659
+ rangeMax: c.output.rangeMax,
20660
+ hasRange: c.output.hasRange
20661
+ }
20662
+ ];
20663
+ for (const e of entries) {
20664
+ const declaredUnit = e.unit && e.unit !== "1" ? e.unit : "";
20665
+ const unitKind = declaredUnit ? kindOfUnit(declaredUnit) : void 0;
20666
+ if (declaredUnit && registersExist && unitKind === void 0) {
20667
+ warn(
20668
+ "C115",
20669
+ `${e.owner}: unit "${declaredUnit}" resolves to no registered unit of the merged quantity register (calculation-signature-shape)`
20670
+ );
20671
+ }
20672
+ if (e.quantityKind) {
20673
+ if (!kindDecl.has(e.quantityKind)) {
20674
+ err(
20675
+ "C115",
20676
+ `${e.owner}: quantity_kind "${e.quantityKind}" resolves to no registered kind of the merged quantity register (calculation-signature-shape)`
20677
+ );
20678
+ } else if (unitKind !== void 0 && unitKind !== e.quantityKind) {
20679
+ err(
20680
+ "C115",
20681
+ `${e.owner}: declared quantity_kind "${e.quantityKind}" but unit "${declaredUnit}" measures kind ${unitKind} \u2014 the typed-unit pair must agree in kind (calculation-signature-shape)`
20682
+ );
20683
+ }
20684
+ }
20685
+ if (e.hasRange && e.rangeMin && e.rangeMax) {
20686
+ const lo = Number(e.rangeMin);
20687
+ const hi = Number(e.rangeMax);
20688
+ if (!Number.isNaN(lo) && !Number.isNaN(hi) && lo > hi) {
20689
+ err(
20690
+ "C115",
20691
+ `${e.owner}: range min ${e.rangeMin} exceeds max ${e.rangeMax} (calculation-signature-shape)`
20692
+ );
20693
+ }
20694
+ }
20695
+ if (e.isInput && e.type === "enum" && (e.enumValues === void 0 || e.enumValues.length === 0)) {
20696
+ err(
20697
+ "C115",
20698
+ `${e.owner}: an enum-typed input declares its values \u2014 enum_values is absent or empty (calculation-signature-shape)`
20699
+ );
20700
+ }
20701
+ }
20702
+ }
20703
+ for (const r of standard.requirements ?? []) {
20704
+ for (const p of r.parameters ?? []) {
20705
+ const where = `requirement ${r.id}: param ${p.name}`;
20706
+ if (p.bind) {
20707
+ const parts = String(p.bind).split(".");
20708
+ const id = parts[2];
20709
+ if (id) {
20710
+ if (parts[1] === "classification") {
20711
+ const dim = DIM_ALIASES[id] ?? id;
20712
+ if (!dimIds.has(dim) && !attrIds.has(id) && !attrIds.has(dim)) {
20713
+ err(
20714
+ "C118",
20715
+ `${where}: bind "${p.bind}" \u2014 dimension "${id}" not declared (requirement-parameter-shape)`
20716
+ );
20717
+ }
20718
+ } else if (parts[1] === "behaviors") {
20719
+ if (!behaviorIds.has(id)) {
20720
+ err(
20721
+ "C118",
20722
+ `${where}: bind "${p.bind}" \u2014 behavior "${id}" not declared (requirement-parameter-shape)`
20723
+ );
20724
+ }
20725
+ } else if (!isIdentityPath(String(p.bind)) && !attrIds.has(id) && !symbolIds.has(id)) {
20726
+ err(
20727
+ "C118",
20728
+ `${where}: bind "${p.bind}" \u2014 attribute "${id}" not defined (requirement-parameter-shape)`
20729
+ );
20730
+ }
20731
+ }
20732
+ }
20733
+ if (p.unit && registersExist && kindOfUnit(p.unit) === void 0) {
20734
+ warn(
20735
+ "C118",
20736
+ `${where}: unit "${p.unit}" resolves to no registered unit of the merged quantity register (requirement-parameter-shape)`
20737
+ );
20738
+ }
20739
+ if (p.hasRange && p.rangeMin && p.rangeMax) {
20740
+ const lo = Number(p.rangeMin);
20741
+ const hi = Number(p.rangeMax);
20742
+ if (!Number.isNaN(lo) && !Number.isNaN(hi) && lo > hi) {
20743
+ err(
20744
+ "C118",
20745
+ `${where}: range min ${p.rangeMin} exceeds max ${p.rangeMax} (requirement-parameter-shape)`
20746
+ );
20747
+ }
20748
+ }
20749
+ }
20750
+ }
20751
+ for (const d of standard.duals ?? []) {
20752
+ if (d.attribute && !attrIds.has(d.attribute)) {
20753
+ err(
20754
+ "C34",
20755
+ `dual ${d.id}: attribute "${d.attribute}" is not a declared attribute_definition (duality-coherence)`
20756
+ );
20757
+ }
20758
+ if (!d.designed && !d.exhibited) {
20091
20759
  err(
20092
20760
  "C34",
20093
20761
  `dual ${d.id}: neither designed nor exhibited stated \u2014 a dual pair carries at least one role (duality-coherence)`
@@ -21486,6 +22154,216 @@ function checkDeclaredPredicates(standard) {
21486
22154
  }
21487
22155
  return issues;
21488
22156
  }
22157
+ function checkTermAliases(standard) {
22158
+ const issues = [];
22159
+ const err = (message) => issues.push({ check: "C110", severity: "error", message });
22160
+ const warn = (message) => issues.push({ check: "C110", severity: "warning", message });
22161
+ const FACETS = ["aliases", "colloquial", "abbreviations", "deprecated"];
22162
+ for (const t of standard.terms ?? []) {
22163
+ const scopes = [
22164
+ [
22165
+ "",
22166
+ {
22167
+ aliases: t.aliases ?? t.alt,
22168
+ colloquial: t.colloquial,
22169
+ abbreviations: t.abbreviations,
22170
+ deprecated: t.deprecated
22171
+ }
22172
+ ],
22173
+ ...Object.entries(t.aliasSpellings ?? {}).map(
22174
+ ([code, v]) => [
22175
+ ` ${code}`,
22176
+ { ...v }
22177
+ ]
22178
+ )
22179
+ ];
22180
+ for (const [tag, scope] of scopes) {
22181
+ const where = (facet) => `term ${t.id}: ${facet}${tag ? ` ${tag}` : ""}`;
22182
+ for (const facet of FACETS) {
22183
+ const seen = /* @__PURE__ */ new Set();
22184
+ for (const entry of scope[facet] ?? []) {
22185
+ if (seen.has(entry)) {
22186
+ err(
22187
+ `${where(facet)}: duplicate entry "${entry}" \u2014 one entry has one home (term-alias-shape)`
22188
+ );
22189
+ }
22190
+ seen.add(entry);
22191
+ }
22192
+ }
22193
+ const home = /* @__PURE__ */ new Map();
22194
+ for (const facet of FACETS) {
22195
+ for (const entry of scope[facet] ?? []) {
22196
+ const prior = home.get(entry);
22197
+ if (prior !== void 0 && prior !== facet) {
22198
+ warn(
22199
+ `${where(facet)}: "${entry}" already appears in ${prior} \u2014 one entry has one home (term-alias-shape)`
22200
+ );
22201
+ } else {
22202
+ home.set(entry, facet);
22203
+ }
22204
+ }
22205
+ }
22206
+ }
22207
+ if (t.label) {
22208
+ for (const [tag, scope] of scopes) {
22209
+ for (const facet of FACETS) {
22210
+ if ((scope[facet] ?? []).includes(t.label)) {
22211
+ warn(
22212
+ `term ${t.id}: ${facet}${tag ? ` ${tag}` : ""} entry "${t.label}" merely echoes the term's label \u2014 an alias adds a bridge or it does not belong (term-alias-shape)`
22213
+ );
22214
+ }
22215
+ }
22216
+ }
22217
+ }
22218
+ }
22219
+ return issues;
22220
+ }
22221
+ function checkDimensions(standard) {
22222
+ const issues = [];
22223
+ const err = (message) => issues.push({ check: "C111", severity: "error", message });
22224
+ const warn = (message) => issues.push({ check: "C111", severity: "warning", message });
22225
+ const checkShape = (owner, d) => {
22226
+ const seen = /* @__PURE__ */ new Set();
22227
+ for (const v of d.values) {
22228
+ if (seen.has(v.id)) {
22229
+ err(
22230
+ `${owner} dimension ${d.id}: duplicate value id "${v.id}" (dimension-shape)`
22231
+ );
22232
+ }
22233
+ seen.add(v.id);
22234
+ }
22235
+ const valueIds = new Set(d.values.map((v) => v.id));
22236
+ const adj = /* @__PURE__ */ new Map();
22237
+ for (const v of d.values) {
22238
+ for (const target of v.implies ?? []) {
22239
+ if (!valueIds.has(target)) {
22240
+ err(
22241
+ `${owner} dimension ${d.id}: value ${v.id} implies "${target}", which is not a value of this dimension \u2014 implies targets resolve inside their own dimension (dimension-shape)`
22242
+ );
22243
+ }
22244
+ }
22245
+ adj.set(
22246
+ v.id,
22247
+ (v.implies ?? []).filter((t) => valueIds.has(t))
22248
+ );
22249
+ }
22250
+ const cycle = findCycle(adj);
22251
+ if (cycle) {
22252
+ err(
22253
+ `${owner} dimension ${d.id}: implies cycle ${cycle.join(" \u2192 ")} \u2014 the applicability engine walks the implication closure, so the graph must be acyclic (dimension-shape)`
22254
+ );
22255
+ }
22256
+ if (d.valuesOf && d.values.length > 0) {
22257
+ err(
22258
+ `${owner} dimension ${d.id}: declares both values and values_of \u2014 a dimension carries one value domain (dimension-shape)`
22259
+ );
22260
+ }
22261
+ if (d.valuesOf && d.valuesOf !== "capabilities") {
22262
+ warn(
22263
+ `${owner} dimension ${d.id}: values_of "${d.valuesOf}" names a register the kernel does not document (the documented register is capabilities) \u2014 the value domain stays open (dimension-shape)`
22264
+ );
22265
+ }
22266
+ };
22267
+ for (const inst of standard.instruments ?? []) {
22268
+ for (const d of inst.dimensions ?? []) {
22269
+ checkShape(`instrument ${inst.id}:`, d);
22270
+ }
22271
+ }
22272
+ for (const d of standard.dimensions ?? []) {
22273
+ checkShape("top-level", d);
22274
+ }
22275
+ const inlineHome = /* @__PURE__ */ new Map();
22276
+ for (const inst of standard.instruments ?? []) {
22277
+ for (const d of inst.dimensions ?? []) {
22278
+ const prior = inlineHome.get(d.id);
22279
+ if (prior !== void 0 && prior !== inst.id) {
22280
+ err(
22281
+ `dimension ${d.id}: declared inline on both instrument ${prior} and instrument ${inst.id} \u2014 one dimension identifier once per applicability namespace (dimension-shape)`
22282
+ );
22283
+ } else {
22284
+ inlineHome.set(d.id, inst.id);
22285
+ }
22286
+ }
22287
+ }
22288
+ const attrDims = new Set(
22289
+ (standard.attributeDefinitions ?? []).filter((a) => a.isDimension === true).map((a) => a.id)
22290
+ );
22291
+ for (const d of standard.dimensions ?? []) {
22292
+ if (inlineHome.has(d.id)) {
22293
+ err(
22294
+ `dimension ${d.id}: declared both top-level and inline on instrument ${inlineHome.get(d.id)} \u2014 one dimension identifier once per applicability namespace (dimension-shape)`
22295
+ );
22296
+ }
22297
+ if (attrDims.has(d.id)) {
22298
+ err(
22299
+ `dimension ${d.id}: declared both top-level and as the is_dimension attribute definition of the same id \u2014 one dimension identifier once per applicability namespace (dimension-shape)`
22300
+ );
22301
+ }
22302
+ }
22303
+ return issues;
22304
+ }
22305
+ function checkReferences(standard) {
22306
+ const issues = [];
22307
+ for (const r of standard.references ?? []) {
22308
+ if (r.urn !== void 0) {
22309
+ if (!/^[A-Za-z][A-Za-z0-9+.-]*:[^\s<>"{}|^`\\]*$/.test(r.urn)) {
22310
+ issues.push({
22311
+ check: "C112",
22312
+ severity: "error",
22313
+ message: `reference ${r.id}: urn "${r.urn}" is not a well-formed IRI (a scheme followed by no whitespace or IRI delimiters) (reference-identity)`
22314
+ });
22315
+ }
22316
+ } else if (!(r.org && r.document)) {
22317
+ issues.push({
22318
+ check: "C112",
22319
+ severity: "warning",
22320
+ message: `reference ${r.id}: carries neither urn nor the org-and-document pair \u2014 a display-string citation is not machine-traversable (reference-identity)`
22321
+ });
22322
+ }
22323
+ }
22324
+ return issues;
22325
+ }
22326
+ function checkVerdictChains(standard) {
22327
+ const issues = [];
22328
+ const symbolIds = new Set((standard.symbols ?? []).map((s) => s.id));
22329
+ const testNames = /* @__PURE__ */ new Set();
22330
+ for (const t of standard.conformanceTests ?? []) {
22331
+ for (const v of t.variables ?? []) {
22332
+ testNames.add(v.name);
22333
+ }
22334
+ for (const o of t.observables ?? []) {
22335
+ testNames.add(o.name);
22336
+ }
22337
+ }
22338
+ const verdictIds = new Set((standard.verdicts ?? []).map((v) => v.id));
22339
+ for (const v of standard.verdicts ?? []) {
22340
+ for (const inp of v.inputs ?? []) {
22341
+ if (!symbolIds.has(inp) && !testNames.has(inp) && !verdictIds.has(inp)) {
22342
+ issues.push({
22343
+ check: "C116",
22344
+ severity: "error",
22345
+ message: `verdict ${v.id}: input "${inp}" resolves to no declared symbol, test variable or observable, or verdict (verdict-inputs-resolve)`
22346
+ });
22347
+ }
22348
+ }
22349
+ }
22350
+ const adj = /* @__PURE__ */ new Map();
22351
+ for (const v of standard.verdicts ?? []) {
22352
+ adj.set(
22353
+ v.id,
22354
+ (v.inputs ?? []).filter((i) => verdictIds.has(i))
22355
+ );
22356
+ }
22357
+ const cycle = findCycle(adj);
22358
+ if (cycle) {
22359
+ issues.push({
22360
+ check: "C117",
22361
+ severity: "error",
22362
+ message: `verdict chain cycle: ${cycle.join(" \u2192 ")} \u2014 the acceptance chain is a graph a consumer traverses, so it must be acyclic (verdict-chain-acyclic)`
22363
+ });
22364
+ }
22365
+ return issues;
22366
+ }
21489
22367
  function checkEditionLifecycle(dir, standard) {
21490
22368
  const issues = [];
21491
22369
  const err = (check, message) => issues.push({ check, severity: "error", message });
@@ -21541,7 +22419,10 @@ function checkEditionLifecycle(dir, standard) {
21541
22419
  }
21542
22420
  const relations = [
21543
22421
  ...(m.supersedes ?? []).map((t) => ["supersedes", t]),
21544
- ...(m.replaces ?? []).map((t) => ["replaces", t])
22422
+ ...(m.replaces ?? []).map((t) => ["replaces", t]),
22423
+ ...(m.supersededBy ?? []).map(
22424
+ (t) => ["superseded_by", t]
22425
+ )
21545
22426
  ];
21546
22427
  const ownBasis = normalizeSourceRef(m.baseUrn ?? "", "").basis;
21547
22428
  for (const [rel, target] of relations) {
@@ -21560,7 +22441,7 @@ function checkEditionLifecycle(dir, standard) {
21560
22441
  continue;
21561
22442
  }
21562
22443
  const tNorm = normalizeSourceRef(target, "");
21563
- if (tNorm.basis === ownBasis && tNorm.edition) {
22444
+ if (rel !== "superseded_by" && tNorm.basis === ownBasis && tNorm.edition) {
21564
22445
  if (!register.has(tNorm.edition)) {
21565
22446
  warn(
21566
22447
  "C79",
@@ -21571,6 +22452,7 @@ function checkEditionLifecycle(dir, standard) {
21571
22452
  }
21572
22453
  if (relations.length > 0) {
21573
22454
  const nodes = /* @__PURE__ */ new Map();
22455
+ const forwardByNode = /* @__PURE__ */ new Map();
21574
22456
  const parent = dirname2(resolve4(dir));
21575
22457
  for (const entry of readdirSync3(parent).sort()) {
21576
22458
  const full = join4(parent, entry);
@@ -21586,6 +22468,7 @@ function checkEditionLifecycle(dir, standard) {
21586
22468
  ),
21587
22469
  ...(sib.replaces ?? []).map((t) => ["replaces", t])
21588
22470
  ]);
22471
+ forwardByNode.set(key, new Set(sib.supersededBy ?? []));
21589
22472
  } catch {
21590
22473
  }
21591
22474
  }
@@ -21603,6 +22486,29 @@ function checkEditionLifecycle(dir, standard) {
21603
22486
  `supersedes cycle: ${cycle.join(" \u2192 ")} \u2014 the supersedes graph must be acyclic; a package cannot supersede itself through a chain (edition-supersedes-resolves)`
21604
22487
  );
21605
22488
  }
22489
+ const ownKey = m.baseUrn || m.id;
22490
+ for (const target of [...m.supersedes ?? [], ...m.replaces ?? []]) {
22491
+ const fwd = forwardByNode.get(target);
22492
+ if (fwd !== void 0 && fwd.size > 0 && !fwd.has(ownKey)) {
22493
+ err(
22494
+ "C113",
22495
+ `package "${m.id}": supersedes/replaces ${target}, but that package declares superseded_by { ${[...fwd].join(" ")} } without ${ownKey} \u2014 opposite lineage edges between the same pair must agree (edition-lineage-coherent)`
22496
+ );
22497
+ }
22498
+ }
22499
+ for (const target of m.supersededBy ?? []) {
22500
+ const bwdRels = nodes.get(target);
22501
+ if (bwdRels === void 0) {
22502
+ continue;
22503
+ }
22504
+ const bwd = new Set(bwdRels.map(([, t]) => t));
22505
+ if (bwd.size > 0 && !bwd.has(ownKey)) {
22506
+ err(
22507
+ "C113",
22508
+ `package "${m.id}": superseded_by ${target}, but that package declares supersedes/replaces { ${[...bwd].join(" ")} } without ${ownKey} \u2014 opposite lineage edges between the same pair must agree (edition-lineage-coherent)`
22509
+ );
22510
+ }
22511
+ }
21606
22512
  }
21607
22513
  if (register.size > 0) {
21608
22514
  for (const inst of standard.instances ?? []) {
@@ -22715,7 +23621,7 @@ function exportStandardRdf(standard) {
22715
23621
  );
22716
23622
  }
22717
23623
  t(eIri, SKOSXL_PREF_LABEL, iri(prefIri));
22718
- (term.alt ?? []).forEach((a, i) => {
23624
+ (term.aliases ?? term.alt ?? []).forEach((a, i) => {
22719
23625
  const form = (term.abbreviations ?? []).includes(a) ? "abbreviation" : "";
22720
23626
  t(eIri, SKOSXL_ALT_LABEL, iri(labelNode(`alt-${i + 1}`, form, a)));
22721
23627
  });
@@ -22930,74 +23836,1113 @@ function renderJsonLd(prefixes, triples) {
22930
23836
  `;
22931
23837
  }
22932
23838
 
22933
- // src/package-diff.ts
22934
- import { existsSync as existsSync6, readdirSync as readdirSync4, readFileSync as readFileSync6 } from "fs";
22935
- import { join as join5 } from "path";
22936
- function packageMappings(dir, standard) {
22937
- const profiles = [...standard.mapProfiles ?? []];
22938
- if (existsSync6(dir)) {
22939
- for (const entry of readdirSync4(dir).sort()) {
22940
- if (!entry.endsWith(".prm")) {
22941
- continue;
23839
+ // src/export/retrieval.ts
23840
+ import { createHash } from "node:crypto";
23841
+ import { readdirSync as readdirSync4, readFileSync as readFileSync6, statSync as statSync3 } from "node:fs";
23842
+ import { join as join5, relative } from "node:path";
23843
+ var RETRIEVAL_PROJECTION = "primmel-retrieval/1";
23844
+ var RETRIEVAL_FACET_VERSION = "retrieval-facet/1";
23845
+ function sortDeep(v) {
23846
+ if (Array.isArray(v)) {
23847
+ return v.map(sortDeep);
23848
+ }
23849
+ if (v && typeof v === "object") {
23850
+ const out = {};
23851
+ for (const k of Object.keys(v).sort()) {
23852
+ const val = sortDeep(v[k]);
23853
+ if (val !== void 0) {
23854
+ out[k] = val;
22942
23855
  }
22943
- profiles.push(
22944
- ...prmToMapProfiles(loadPrm(readFileSync6(join5(dir, entry), "utf8")))
22945
- );
22946
23856
  }
22947
- }
22948
- const modelId = standard.packageManifest?.id ?? standard.meta?.namespace ?? "";
22949
- return profiles.flatMap((p) => mappingsFromProfile(p, modelId));
22950
- }
22951
- function packageClauseTexts(dir) {
22952
- const out = /* @__PURE__ */ new Map();
22953
- const prdDir = join5(dir, "sources-prd");
22954
- if (!existsSync6(prdDir)) {
22955
23857
  return out;
22956
23858
  }
22957
- for (const entry of readdirSync4(prdDir).sort()) {
22958
- if (!entry.endsWith(".sentences.json")) {
22959
- continue;
22960
- }
22961
- let payload;
22962
- try {
22963
- payload = JSON.parse(readFileSync6(join5(prdDir, entry), "utf8"));
22964
- } catch {
23859
+ return v;
23860
+ }
23861
+ function canonicalJson(value) {
23862
+ return JSON.stringify(sortDeep(value));
23863
+ }
23864
+ function retrievalDigest(value) {
23865
+ return createHash("sha256").update(canonicalJson(value), "utf8").digest("hex");
23866
+ }
23867
+ function* walkPackage(dir) {
23868
+ for (const entry of readdirSync4(dir).sort()) {
23869
+ if (entry === ".DS_Store") {
22965
23870
  continue;
22966
23871
  }
22967
- const urn = payload.document?.urn ?? "";
22968
- if (!urn) {
22969
- continue;
23872
+ const p = join5(dir, entry);
23873
+ if (statSync3(p).isDirectory()) {
23874
+ yield* walkPackage(p);
23875
+ } else {
23876
+ yield p;
22970
23877
  }
22971
- const basis = normalizeSourceRef(urn, "").basis;
22972
- const byClause = /* @__PURE__ */ new Map();
22973
- for (const s of payload.sentences ?? []) {
22974
- if (!s.clause || s.text === void 0) {
22975
- continue;
23878
+ }
23879
+ }
23880
+ function packageSourceHash(dir) {
23881
+ const h = createHash("sha256");
23882
+ for (const file of walkPackage(dir)) {
23883
+ h.update(relative(dir, file));
23884
+ h.update("\0");
23885
+ h.update(createHash("sha256").update(readFileSync6(file)).digest());
23886
+ h.update("\n");
23887
+ }
23888
+ return h.digest("hex");
23889
+ }
23890
+ var UUID_ANCHOR = /^_?[0-9a-f]{8}-[0-9a-f]{4}-/i;
23891
+ var DOC_FRAGMENT2 = /#([^#]*)$/;
23892
+ function normalizeClause(doc, clause, fragment = "") {
23893
+ let rest = doc ?? "";
23894
+ let clauseOut = clause ?? "";
23895
+ let frag = fragment ?? "";
23896
+ let anchor;
23897
+ const hash = DOC_FRAGMENT2.exec(rest);
23898
+ if (hash) {
23899
+ rest = rest.slice(0, hash.index);
23900
+ const embedded = hash[1] ?? "";
23901
+ if (!clauseOut && embedded.startsWith("clause-")) {
23902
+ const tail = embedded.slice("clause-".length);
23903
+ const slash = tail.indexOf("/");
23904
+ if (slash >= 0) {
23905
+ clauseOut = tail.slice(0, slash);
23906
+ if (!frag) {
23907
+ frag = tail.slice(slash + 1);
23908
+ }
23909
+ } else {
23910
+ clauseOut = tail;
22976
23911
  }
22977
- (byClause.get(s.clause) ?? byClause.set(s.clause, []).get(s.clause)).push(s.text);
22978
- }
22979
- for (const [clause, texts] of byClause) {
22980
- out.set(clauseTextKey(basis, clause), texts.join("\n"));
23912
+ } else if (embedded && !frag) {
23913
+ anchor = embedded;
23914
+ } else if (embedded) {
23915
+ anchor = embedded;
22981
23916
  }
22982
23917
  }
23918
+ if (clauseOut && UUID_ANCHOR.test(clauseOut)) {
23919
+ anchor = anchor ?? clauseOut;
23920
+ clauseOut = "";
23921
+ }
23922
+ const urn = rest + (clauseOut ? `#clause-${clauseOut}${frag ? `/${frag}` : ""}` : anchor && !UUID_ANCHOR.test(anchor) ? `#${anchor}` : "");
23923
+ const out = { doc: rest, clause: clauseOut, urn };
23924
+ if (anchor !== void 0) {
23925
+ out.anchor = anchor;
23926
+ }
23927
+ if (frag) {
23928
+ out.fragment = frag;
23929
+ }
22983
23930
  return out;
22984
23931
  }
22985
- function diffPackageDirs(dirA, dirB, options = {}) {
22986
- const loadedA = loadPackageWithIssues(dirA, {
22987
- resolvePackage: options.resolvePackage
22988
- });
22989
- const loadedB = loadPackageWithIssues(dirB, {
22990
- resolvePackage: options.resolvePackage
22991
- });
22992
- const diff = diffStandards(loadedA.standard, loadedB.standard, {
22993
- ...options,
22994
- mappingsA: packageMappings(dirA, loadedA.standard),
22995
- mappingsB: packageMappings(dirB, loadedB.standard),
22996
- ...options.compareTexts ? {
22997
- sentencesA: packageClauseTexts(dirA),
22998
- sentencesB: packageClauseTexts(dirB)
22999
- } : {}
23000
- });
23932
+ function refTargetClause(target) {
23933
+ const m = /^(urn:[^#]+)(?:#(.+))?$/.exec(target);
23934
+ if (!m) {
23935
+ return null;
23936
+ }
23937
+ return { doc: m[1], clause: "", fragment: m[2] ?? "" };
23938
+ }
23939
+ function collectClauses(el) {
23940
+ const out = [];
23941
+ const seen = /* @__PURE__ */ new Set();
23942
+ const push = (r) => {
23943
+ if (!r || !r.doc && !r.clause) {
23944
+ return;
23945
+ }
23946
+ const c = normalizeClause(r.doc ?? "", r.clause ?? "", r.fragment);
23947
+ if (!seen.has(c.urn)) {
23948
+ seen.add(c.urn);
23949
+ out.push(c);
23950
+ }
23951
+ };
23952
+ push(el.source);
23953
+ push(el.sourceRef);
23954
+ for (const r of el.sourceRefs ?? []) {
23955
+ push(r);
23956
+ }
23957
+ const reference = (el.reference ?? "").replace(/^"|"$/g, "");
23958
+ if (reference.startsWith("urn:")) {
23959
+ push(refTargetClause(reference));
23960
+ }
23961
+ for (const r of el.refs ?? []) {
23962
+ if (r && typeof r.target === "string" && r.target.startsWith("urn:")) {
23963
+ push(refTargetClause(r.target));
23964
+ }
23965
+ }
23966
+ return out;
23967
+ }
23968
+ function termClauses(term, baseUrn) {
23969
+ const out = [];
23970
+ const seen = /* @__PURE__ */ new Set();
23971
+ const push = (c) => {
23972
+ if (c && !seen.has(c.urn)) {
23973
+ seen.add(c.urn);
23974
+ out.push(c);
23975
+ }
23976
+ };
23977
+ for (const token of (term.source ?? "").split(/\s+/).filter((t) => t)) {
23978
+ push(token.startsWith("urn:") ? normalizeClause(token, "") : null);
23979
+ }
23980
+ if (term.section && !out.some((c) => c.clause)) {
23981
+ push(normalizeClause(baseUrn, term.section));
23982
+ }
23983
+ return out;
23984
+ }
23985
+ function applicabilitySummary(entries) {
23986
+ return (entries ?? []).map((e) => {
23987
+ const mode = e.match && e.match !== "any" ? `(${e.match})` : "";
23988
+ return `${e.dimension}${mode}=${[...e.values].sort().join("|")}`;
23989
+ }).sort().join(";");
23990
+ }
23991
+ function passportOf(unit) {
23992
+ return {
23993
+ v: 1,
23994
+ kind: unit.kind,
23995
+ id: unit.id,
23996
+ text: unit.statement ?? unit.definition ?? unit.name ?? "",
23997
+ expression: unit.expression ?? "",
23998
+ units: unit.units ?? [],
23999
+ applicability: applicabilitySummary(unit.applicability),
24000
+ acceptance: unit.acceptance ?? "",
24001
+ provenance: (unit.clauses ?? []).map((c) => c.urn),
24002
+ content_hash: unit.content_hash
24003
+ };
24004
+ }
24005
+ var BASE_URN_PARTS = /^urn:oiml:pub:([rdbge]):(\d[\d-]*)(?::(\d{4}))?$/i;
24006
+ function retrievalDocParts(baseUrn) {
24007
+ const m = BASE_URN_PARTS.exec(baseUrn);
24008
+ if (!m) {
24009
+ return { doctype: "", doc_number: "", year: "", label: "" };
24010
+ }
24011
+ const doctype = (m[1] ?? "").toLowerCase();
24012
+ const docNumber = m[2] ?? "";
24013
+ const year = m[3] ?? "";
24014
+ return {
24015
+ doctype,
24016
+ doc_number: docNumber,
24017
+ year,
24018
+ label: `OIML ${doctype.toUpperCase()} ${docNumber}${year ? `:${year}` : ""}`
24019
+ };
24020
+ }
24021
+ function retrievalFacet(unit, pkg) {
24022
+ const parts = retrievalDocParts(pkg.base_urn);
24023
+ const facet = {
24024
+ unit_id: unit.id,
24025
+ unit_hash: unit.content_hash,
24026
+ block: unit.kind,
24027
+ doc_id: pkg.id,
24028
+ docidentifier: parts.label || pkg.title,
24029
+ doctype: parts.doctype,
24030
+ doc_number: parts.doc_number,
24031
+ edition: pkg.edition,
24032
+ model_version: pkg.model_version,
24033
+ language: pkg.default_spelling,
24034
+ clause_anchor: unit.clause?.clause ?? "",
24035
+ clause_title: unit.name ?? unit.id,
24036
+ ...present(pkg.status) ? { status: pkg.status } : {}
24037
+ };
24038
+ const valuesByDim = /* @__PURE__ */ new Map();
24039
+ const matchByDim = /* @__PURE__ */ new Map();
24040
+ for (const entry of unit.applicability ?? []) {
24041
+ const values = entry.values.length > 0 ? entry.values : Object.keys(entry.mapping ?? {});
24042
+ const set = valuesByDim.get(entry.dimension) ?? /* @__PURE__ */ new Set();
24043
+ for (const v of values) {
24044
+ set.add(v);
24045
+ }
24046
+ valuesByDim.set(entry.dimension, set);
24047
+ if (entry.match && entry.match !== "any" && !matchByDim.has(entry.dimension)) {
24048
+ matchByDim.set(entry.dimension, entry.match);
24049
+ }
24050
+ }
24051
+ for (const dim of [...valuesByDim.keys()].sort()) {
24052
+ facet[`app_${dim}`] = [...valuesByDim.get(dim)].sort().join("|");
24053
+ const match = matchByDim.get(dim);
24054
+ if (match) {
24055
+ facet[`app_${dim}_match`] = match;
24056
+ }
24057
+ }
24058
+ return facet;
24059
+ }
24060
+ function resolveTextAddress(address, elementIds) {
24061
+ const segments = address.split(".");
24062
+ if (segments.length < 2 || segments.some((s) => s === "")) {
24063
+ return null;
24064
+ }
24065
+ for (let i = segments.length - 1; i >= 1; i--) {
24066
+ const candidate = segments.slice(0, i).join(".");
24067
+ if (elementIds.has(candidate)) {
24068
+ return { elementId: candidate, path: segments.slice(i).join(".") };
24069
+ }
24070
+ }
24071
+ return null;
24072
+ }
24073
+ var TEXT_ADDRESS_COLLECTIONS = [
24074
+ "requirements",
24075
+ "requirementClasses",
24076
+ "conformanceTests",
24077
+ "conformanceClasses",
24078
+ "terms",
24079
+ "forms",
24080
+ "subforms",
24081
+ "symbols",
24082
+ "tables",
24083
+ "calculations",
24084
+ "notes",
24085
+ "provisions",
24086
+ "processes",
24087
+ "instruments",
24088
+ "attributeDefinitions",
24089
+ "capabilities",
24090
+ "behaviors",
24091
+ "conditionSets",
24092
+ "subjects",
24093
+ "referenceMaterials",
24094
+ "artifactDefinitions",
24095
+ "monitors",
24096
+ "passports",
24097
+ "invariants",
24098
+ "testSequences",
24099
+ "formulasUsed",
24100
+ "stateMachines",
24101
+ "figures",
24102
+ "links"
24103
+ ];
24104
+ function attachVariants(built, standard, pkg) {
24105
+ if (present(pkg.default_spelling)) {
24106
+ for (const b of built) {
24107
+ b.content.language = pkg.default_spelling;
24108
+ }
24109
+ }
24110
+ const texts = standard.texts ?? [];
24111
+ if (texts.length === 0) {
24112
+ return 0;
24113
+ }
24114
+ const registry = /* @__PURE__ */ new Set();
24115
+ for (const field of TEXT_ADDRESS_COLLECTIONS) {
24116
+ for (const item of standard[field] ?? []) {
24117
+ if (item?.id) {
24118
+ registry.add(item.id);
24119
+ }
24120
+ }
24121
+ }
24122
+ const unitByElement = new Map(built.map((b) => [b.elementId, b.content]));
24123
+ let dropped = 0;
24124
+ for (const t of texts) {
24125
+ const resolved = resolveTextAddress(t.id, registry);
24126
+ const content = resolved ? unitByElement.get(resolved.elementId) : void 0;
24127
+ if (!resolved || !content) {
24128
+ dropped++;
24129
+ continue;
24130
+ }
24131
+ const variants = content.variants ??= {};
24132
+ variants[resolved.path] = [
24133
+ ...variants[resolved.path] ?? [],
24134
+ ...t.entries
24135
+ ];
24136
+ }
24137
+ return dropped;
24138
+ }
24139
+ function assemble(content, clauses) {
24140
+ if (clauses.length > 0) {
24141
+ content.clause = clauses[0];
24142
+ content.clauses = clauses;
24143
+ }
24144
+ return content;
24145
+ }
24146
+ function completeUnit(content, pkg) {
24147
+ const hash = retrievalDigest(content);
24148
+ const unit = {
24149
+ ...content,
24150
+ content_hash: hash
24151
+ };
24152
+ unit.passport = passportOf(unit);
24153
+ unit.facet = retrievalFacet(unit, pkg);
24154
+ return unit;
24155
+ }
24156
+ function scopeOf(id) {
24157
+ const slash = id.lastIndexOf("/");
24158
+ return slash > 0 ? id.slice(0, slash) : void 0;
24159
+ }
24160
+ var present = (s) => typeof s === "string" && s.length > 0;
24161
+ var presentList = (xs) => xs && xs.length > 0 ? xs : void 0;
24162
+ function requirementUnit(r) {
24163
+ return assemble(
24164
+ {
24165
+ id: r.id,
24166
+ kind: "requirement",
24167
+ ...scopeOf(r.id) ? { class: scopeOf(r.id) } : {},
24168
+ ...present(r.name) ? { name: r.name } : {},
24169
+ ...present(r.statement) ? { statement: r.statement } : {},
24170
+ ...present(r.guidance) ? { guidance: r.guidance } : {},
24171
+ ...present(r.obligation) ? { obligation: r.obligation } : {},
24172
+ modality: r.limit?.modality || "shall",
24173
+ ...r.limit?.expression ? {
24174
+ expression: r.limit.expression,
24175
+ ...presentList(r.limit.uses) ? { expression_inputs: r.limit.uses } : {}
24176
+ } : {},
24177
+ ...presentList(r.applicability) ? { applicability: r.applicability } : {},
24178
+ ...presentList(r.bindsTo) ? { binds_to: r.bindsTo } : {},
24179
+ ...r.limit?.accepts ? {
24180
+ acceptance: `${r.limit.accepts.verdict} ${r.limit.accepts.op} ${r.limit.accepts.limit}`
24181
+ } : {},
24182
+ ...present(r.acceptanceCriteria) ? { acceptance_criteria: r.acceptanceCriteria } : {},
24183
+ ...present(r.verificationMethod) ? {
24184
+ verification: {
24185
+ method: r.verificationMethod,
24186
+ description: r.verificationDescription ?? ""
24187
+ }
24188
+ } : {},
24189
+ ...present(r.channel) ? { channel: r.channel } : {},
24190
+ ...presentList(r.dependencies) ? { dependencies: r.dependencies } : {}
24191
+ },
24192
+ collectClauses(r)
24193
+ );
24194
+ }
24195
+ function conformanceTestUnit(t) {
24196
+ const payload = {
24197
+ ...present(t.kind) ? { test_kind: t.kind } : {},
24198
+ ...present(t.methodRef) ? { method_ref: t.methodRef } : {},
24199
+ ...presentList(t.preconditions) ? {
24200
+ preconditions: t.preconditions.map((p) => ({
24201
+ id: p.id,
24202
+ check: p.check,
24203
+ description: p.description,
24204
+ on_violation: p.onViolation
24205
+ }))
24206
+ } : {}
24207
+ };
24208
+ return assemble(
24209
+ {
24210
+ id: t.id,
24211
+ kind: "conformance_test",
24212
+ ...scopeOf(t.id) ? { class: scopeOf(t.id) } : {},
24213
+ ...present(t.name) ? { name: t.name } : {},
24214
+ ...present(t.purpose) ? { statement: t.purpose } : {},
24215
+ ...present(t.method) ? { definition: t.method } : {},
24216
+ ...present(t.guidance) ? { guidance: t.guidance } : {},
24217
+ ...present(t.obligation) ? { obligation: t.obligation } : {},
24218
+ ...presentList(t.applicability) ? { applicability: t.applicability } : {},
24219
+ ...presentList(t.targets) ? { targets: t.targets } : {},
24220
+ ...presentList(t.bindsTo) ? { binds_to: t.bindsTo } : {},
24221
+ ...present(t.acceptancePassIf) ? { acceptance: t.acceptancePassIf } : present(t.acceptanceCriteriaDescription) ? { acceptance: t.acceptanceCriteriaDescription } : {},
24222
+ ...presentList(t.dependencies) ? { dependencies: t.dependencies } : {},
24223
+ ...Object.keys(payload).length > 0 ? { payload } : {}
24224
+ },
24225
+ collectClauses(t)
24226
+ );
24227
+ }
24228
+ function termUnit(t, baseUrn) {
24229
+ const payload = {
24230
+ ...present(t.section) ? { section: t.section } : {},
24231
+ ...present(t.language) ? { language: t.language } : {},
24232
+ ...t.vocabRef ? { vocab_ref: t.vocabRef } : {},
24233
+ // The alias family (MN 114 v3.2, clause 13.10.1): the parser folds
24234
+ // the v2 `alt` spelling into the canonical aliases channel; the
24235
+ // payload keeps the deployed `alt` key (contract stability) and adds
24236
+ // the v3.2 facets.
24237
+ ...presentList(t.aliases ?? t.alt) ? { alt: t.aliases ?? t.alt } : {},
24238
+ ...presentList(t.colloquial) ? { colloquial: t.colloquial } : {},
24239
+ ...t.aliasSpellings && Object.keys(t.aliasSpellings).length > 0 ? { alias_spellings: t.aliasSpellings } : {},
24240
+ ...presentList(t.abbreviations) ? { abbreviations: t.abbreviations } : {},
24241
+ ...presentList(t.seeAlso) ? { see_also: t.seeAlso } : {}
24242
+ };
24243
+ return assemble(
24244
+ {
24245
+ id: `/term/${t.id}`,
24246
+ kind: "term",
24247
+ ...present(t.label) ? { name: t.label } : {},
24248
+ ...present(t.definition) ? { definition: t.definition } : {},
24249
+ ...Object.keys(payload).length > 0 ? { payload } : {}
24250
+ },
24251
+ termClauses(t, baseUrn)
24252
+ );
24253
+ }
24254
+ function attributeUnit(a) {
24255
+ const payload = {
24256
+ ...present(a.symbol) ? { symbol: a.symbol } : {},
24257
+ ...present(a.quantityKind) ? { quantity_kind: a.quantityKind } : {},
24258
+ ...present(a.valueType) ? { value_type: a.valueType } : {},
24259
+ ...present(a.origin) ? { origin: a.origin } : {},
24260
+ ...present(a.scope) ? { scope: a.scope } : {},
24261
+ ...present(a.category) ? { category: a.category } : {},
24262
+ ...present(a.irdi) ? { irdi: a.irdi } : {},
24263
+ ...presentList(a.enumValues) ? { enum_values: a.enumValues } : {}
24264
+ };
24265
+ return assemble(
24266
+ {
24267
+ id: `/attribute/${a.id}`,
24268
+ kind: "attribute",
24269
+ ...present(a.name) ? { name: a.name } : {},
24270
+ ...present(a.definition) ? { definition: a.definition } : {},
24271
+ ...present(a.unit) && a.unit !== "1" ? { units: [a.unit] } : {},
24272
+ ...Object.keys(payload).length > 0 ? { payload } : {}
24273
+ },
24274
+ collectClauses(a)
24275
+ );
24276
+ }
24277
+ function behaviorUnit(b) {
24278
+ const payload = {
24279
+ ...present(b.kind) ? { behavior_kind: b.kind } : {},
24280
+ ...present(b.stimulus) ? { stimulus: b.stimulus } : {}
24281
+ };
24282
+ return assemble(
24283
+ {
24284
+ id: `/behavior/${b.id}`,
24285
+ kind: "behavior",
24286
+ name: b.id,
24287
+ ...present(b.response) ? { statement: b.response } : {},
24288
+ ...Object.keys(payload).length > 0 ? { payload } : {}
24289
+ },
24290
+ collectClauses(b)
24291
+ );
24292
+ }
24293
+ function calculationUnits(c) {
24294
+ const out = /* @__PURE__ */ new Set();
24295
+ for (const i of c.inputs ?? []) {
24296
+ if (present(i.unit) && i.unit !== "1") {
24297
+ out.add(i.unit);
24298
+ }
24299
+ }
24300
+ if (c.output && present(c.output.unit) && c.output.unit !== "1") {
24301
+ out.add(c.output.unit);
24302
+ }
24303
+ return [...out].sort();
24304
+ }
24305
+ function calculationUnit(c) {
24306
+ const kind = present(c.ruleType) ? "formula" : "calculation";
24307
+ const units = calculationUnits(c);
24308
+ const payload = {
24309
+ name: c.name,
24310
+ ...present(c.ruleType) ? { rule_type: c.ruleType } : {},
24311
+ ...present(c.category) ? { category: c.category } : {},
24312
+ ...presentList(c.inputs) ? {
24313
+ inputs: c.inputs.map((i) => ({
24314
+ name: i.name,
24315
+ type: i.type,
24316
+ ...present(i.unit) ? { unit: i.unit } : {}
24317
+ }))
24318
+ } : {},
24319
+ ...c.output && present(c.output.type) ? { output: c.output } : {},
24320
+ ...c.lookup ? { lookup: c.lookup } : {},
24321
+ ...present(c.profile) ? { profile: c.profile } : {}
24322
+ };
24323
+ return assemble(
24324
+ {
24325
+ id: present(c.identifier) ? c.identifier : `/calculation/${c.id}`,
24326
+ kind,
24327
+ name: c.label || c.name || c.id,
24328
+ ...present(c.description) ? { definition: c.description } : {},
24329
+ ...present(c.expression) ? { expression: c.expression } : {},
24330
+ ...presentList(c.params) ? { expression_inputs: c.params } : {},
24331
+ ...units.length > 0 ? { units } : {},
24332
+ payload
24333
+ },
24334
+ collectClauses({
24335
+ sourceRef: c.sourceRef,
24336
+ sourceRefs: c.sourceRefs,
24337
+ refs: c.refs
24338
+ })
24339
+ );
24340
+ }
24341
+ function symbolUnit(s) {
24342
+ const units = present(s.unit) && s.unit !== "1" ? [s.unit] : void 0;
24343
+ const payload = {
24344
+ ...present(s.type) ? { symbol_type: s.type } : {},
24345
+ ...present(s.kind) ? { symbol_kind: s.kind } : {},
24346
+ ...present(s.quantityKind) ? { quantity_kind: s.quantityKind } : {},
24347
+ ...present(s.origin) ? { origin: s.origin } : {},
24348
+ ...present(s.latex) ? { latex: s.latex } : {},
24349
+ ...s.formula && present(s.formula.display) ? { display: s.formula.display } : {},
24350
+ ...present(s.calculation) ? { calculation: s.calculation } : {}
24351
+ };
24352
+ return assemble(
24353
+ {
24354
+ id: `/symbol/${s.id}`,
24355
+ kind: "symbol",
24356
+ ...present(s.name) ? { name: s.name } : {},
24357
+ ...present(s.definition) ? { definition: s.definition } : {},
24358
+ ...s.formula && present(s.formula.expression) ? {
24359
+ expression: s.formula.expression,
24360
+ ...presentList(s.formula.inputs) ? { expression_inputs: s.formula.inputs } : {}
24361
+ } : {},
24362
+ ...units ? { units } : {},
24363
+ ...Object.keys(payload).length > 0 ? { payload } : {}
24364
+ },
24365
+ collectClauses({
24366
+ sourceRef: s.sourceRef,
24367
+ sourceRefs: s.sourceRefs,
24368
+ refs: s.refs
24369
+ })
24370
+ );
24371
+ }
24372
+ function constraintUnit(c) {
24373
+ return assemble(
24374
+ {
24375
+ id: `/constraint/${c.id}`,
24376
+ kind: "constraint",
24377
+ ...present(c.name) ? { name: c.name } : {},
24378
+ ...present(c.violationMeaning) ? { statement: c.violationMeaning } : {},
24379
+ ...present(c.check) ? { expression: c.check } : {},
24380
+ payload: {
24381
+ ...present(c.stereotype) ? { stereotype: c.stereotype } : {},
24382
+ ...present(c.onViolation) ? { on_violation: c.onViolation } : {}
24383
+ }
24384
+ },
24385
+ collectClauses(c)
24386
+ );
24387
+ }
24388
+ function characteristicUnit(v) {
24389
+ const units = present(v.unit) && v.unit !== "1" ? [v.unit] : void 0;
24390
+ const payload = {
24391
+ ...present(v.behavior) ? { behavior: v.behavior } : {},
24392
+ ...present(v.quantityKind) ? { quantity_kind: v.quantityKind } : {},
24393
+ ...v.seriesReduction ? { series_reduction: v.seriesReduction } : {}
24394
+ };
24395
+ return assemble(
24396
+ {
24397
+ id: `/characteristic/${v.id}`,
24398
+ kind: "characteristic",
24399
+ ...present(v.symbol) ? { name: v.symbol } : {},
24400
+ ...present(v.derive) ? {
24401
+ expression: v.derive,
24402
+ ...presentList(v.inputs) ? { expression_inputs: v.inputs } : {}
24403
+ } : {},
24404
+ ...units ? { units } : {},
24405
+ ...v.acceptance && present(v.acceptance.rule) ? { acceptance: v.acceptance.rule } : {},
24406
+ ...Object.keys(payload).length > 0 ? { payload } : {}
24407
+ },
24408
+ collectClauses(v)
24409
+ );
24410
+ }
24411
+ function tableUnit(t) {
24412
+ const units = (t.columnDefs ?? []).map((c) => c.unit).filter((u) => present(u) && u !== "1").sort();
24413
+ const payload = {
24414
+ ...presentList(t.columnDefs) ? {
24415
+ columns: t.columnDefs.map((c) => ({
24416
+ name: c.name,
24417
+ type: c.type,
24418
+ ...present(c.unit) ? { unit: c.unit } : {}
24419
+ }))
24420
+ } : present(t.columns) ? { columns: t.columns } : {},
24421
+ ...presentList(t.data) ? { rows: t.data } : {},
24422
+ ...t.profiles ? { profiles: t.profiles } : {}
24423
+ };
24424
+ return assemble(
24425
+ {
24426
+ id: `/table/${t.id}`,
24427
+ kind: "table",
24428
+ ...present(t.title) ? { name: t.title } : {},
24429
+ ...present(t.description) ? { definition: t.description } : {},
24430
+ ...units.length > 0 ? { units: [...new Set(units)] } : {},
24431
+ ...Object.keys(payload).length > 0 ? { payload } : {}
24432
+ },
24433
+ collectClauses({
24434
+ sourceRef: t.sourceRef,
24435
+ sourceRefs: t.sourceRefs,
24436
+ refs: t.refs
24437
+ })
24438
+ );
24439
+ }
24440
+ function sequenceUnit(s) {
24441
+ const payload = {
24442
+ steps: s.steps.map((st) => ({
24443
+ order: st.order,
24444
+ ...present(st.test) ? { test: st.test } : {},
24445
+ ...present(st.phase) ? { phase: st.phase } : {},
24446
+ ...present(st.role) ? { role: st.role } : {},
24447
+ ...st.dependsOn !== null ? { depends_on: st.dependsOn } : {}
24448
+ })),
24449
+ ...present(s.sampleApplicability) ? { sample_applicability: s.sampleApplicability } : {}
24450
+ };
24451
+ return assemble(
24452
+ {
24453
+ id: `/sequence/${s.id}`,
24454
+ kind: "sequence",
24455
+ ...present(s.name) ? { name: s.name } : {},
24456
+ ...present(s.description) ? { statement: s.description } : {},
24457
+ payload
24458
+ },
24459
+ collectClauses({ sourceRefs: s.sourceRefs, refs: s.refs })
24460
+ );
24461
+ }
24462
+ function noteUnit(n) {
24463
+ return assemble(
24464
+ {
24465
+ id: `/note/${n.id}`,
24466
+ kind: "note",
24467
+ name: n.type,
24468
+ ...present(n.message) ? { statement: n.message } : {}
24469
+ },
24470
+ []
24471
+ );
24472
+ }
24473
+ function stateMachineUnit(m) {
24474
+ const id = m.entityName;
24475
+ const payload = {
24476
+ ...present(m.kind) ? { machine_kind: m.kind } : {},
24477
+ ...present(m.initialState) ? { initial: m.initialState } : {},
24478
+ ...presentList(m.states) ? { states: m.states.map((s) => s.name) } : {},
24479
+ ...presentList(m.transitions) ? {
24480
+ transitions: m.transitions.map((t) => ({
24481
+ from: t.from,
24482
+ to: t.to,
24483
+ ...present(t.actionName) ? { action: t.actionName } : {},
24484
+ ...present(t.guard) ? { guard: t.guard } : {}
24485
+ }))
24486
+ } : {}
24487
+ };
24488
+ return assemble(
24489
+ {
24490
+ id: `/state-machine/${id}`,
24491
+ kind: "state_machine",
24492
+ name: id,
24493
+ ...Object.keys(payload).length > 0 ? { payload } : {}
24494
+ },
24495
+ []
24496
+ );
24497
+ }
24498
+ function dimensionUnit(d) {
24499
+ const payload = {
24500
+ ...present(d.scope) ? { scope: d.scope } : {},
24501
+ ...present(d.cardinality) ? { cardinality: d.cardinality } : {},
24502
+ values: d.values.map((v) => ({
24503
+ id: v.id,
24504
+ ...present(v.label) ? { label: v.label } : {},
24505
+ ...presentList(v.implies) ? { implies: v.implies } : {},
24506
+ ...present(v.termRef) ? { term_ref: v.termRef } : {}
24507
+ }))
24508
+ };
24509
+ return assemble(
24510
+ {
24511
+ id: `/dimension/${d.id}`,
24512
+ kind: "dimension",
24513
+ ...present(d.label) ? { name: d.label } : {},
24514
+ ...present(d.description) ? { definition: d.description } : {},
24515
+ payload
24516
+ },
24517
+ collectClauses(d)
24518
+ );
24519
+ }
24520
+ function packageEdition(manifest) {
24521
+ const first = manifest?.editions?.[0];
24522
+ if (present(first)) {
24523
+ return first;
24524
+ }
24525
+ const tail = /:(\d{4})$/.exec(manifest?.baseUrn ?? "");
24526
+ return tail?.[1] ?? "";
24527
+ }
24528
+ function packageBlock(standard) {
24529
+ const m = standard.packageManifest;
24530
+ if (m) {
24531
+ return {
24532
+ id: m.id,
24533
+ title: m.title,
24534
+ kind: m.kind ?? "rec",
24535
+ edition: packageEdition(m),
24536
+ model_version: m.version,
24537
+ editions: [...m.editions ?? []],
24538
+ base_urn: m.baseUrn,
24539
+ ...present(m.status) ? { status: m.status } : {},
24540
+ default_spelling: m.defaultSpelling ?? "",
24541
+ spellings: [
24542
+ ...m.spellings ?? (m.defaultSpelling ? [m.defaultSpelling] : [])
24543
+ ],
24544
+ ...presentList(m.supersedes) ? { supersedes: [...m.supersedes] } : {}
24545
+ };
24546
+ }
24547
+ const meta = standard.meta;
24548
+ return {
24549
+ id: meta?.namespace ?? "",
24550
+ title: meta?.title ?? "",
24551
+ kind: "",
24552
+ edition: meta?.edition ?? "",
24553
+ model_version: "",
24554
+ editions: present(meta?.edition) ? [meta.edition] : [],
24555
+ base_urn: "",
24556
+ default_spelling: "",
24557
+ spellings: []
24558
+ };
24559
+ }
24560
+ function exportStandardRetrieval(standard, options = {}) {
24561
+ const pkg = packageBlock(standard);
24562
+ const built = [];
24563
+ const push = (content, elementId) => {
24564
+ built.push({ content, elementId });
24565
+ };
24566
+ for (const r of standard.requirements ?? []) {
24567
+ push(requirementUnit(r), r.id);
24568
+ }
24569
+ for (const t of standard.conformanceTests ?? []) {
24570
+ push(conformanceTestUnit(t), t.id);
24571
+ }
24572
+ for (const t of standard.terms ?? []) {
24573
+ push(termUnit(t, pkg.base_urn), t.id);
24574
+ }
24575
+ for (const a of standard.attributeDefinitions ?? []) {
24576
+ push(attributeUnit(a), a.id);
24577
+ }
24578
+ for (const b of standard.behaviors ?? []) {
24579
+ push(behaviorUnit(b), b.id);
24580
+ }
24581
+ for (const c of standard.calculations ?? []) {
24582
+ push(calculationUnit(c), c.id);
24583
+ }
24584
+ for (const s of standard.symbols ?? []) {
24585
+ push(symbolUnit(s), s.id);
24586
+ }
24587
+ for (const c of standard.constraints ?? []) {
24588
+ push(constraintUnit(c), c.id);
24589
+ }
24590
+ for (const v of standard.verdicts ?? []) {
24591
+ push(characteristicUnit(v), v.id);
24592
+ }
24593
+ for (const t of standard.tables ?? []) {
24594
+ push(tableUnit(t), t.id);
24595
+ }
24596
+ for (const s of standard.testSequences ?? []) {
24597
+ push(sequenceUnit(s), s.id);
24598
+ }
24599
+ for (const n of standard.notes ?? []) {
24600
+ push(noteUnit(n), n.id);
24601
+ }
24602
+ for (const m of standard.stateMachines ?? []) {
24603
+ push(stateMachineUnit(m), m.entityName);
24604
+ }
24605
+ for (const i of standard.instruments ?? []) {
24606
+ for (const d of i.dimensions ?? []) {
24607
+ push(dimensionUnit(d), d.id);
24608
+ }
24609
+ }
24610
+ const droppedTextBlocks = attachVariants(built, standard, pkg);
24611
+ const units = built.map((b) => completeUnit(b.content, pkg));
24612
+ const byKind = {};
24613
+ let withClause = 0;
24614
+ let anchorOnlyProvenance = 0;
24615
+ let nonUrnDocRefs = 0;
24616
+ let withoutProvenance = 0;
24617
+ let withVariants = 0;
24618
+ for (const u of units) {
24619
+ byKind[u.kind] = (byKind[u.kind] ?? 0) + 1;
24620
+ if (u.variants && Object.keys(u.variants).length > 0) {
24621
+ withVariants++;
24622
+ }
24623
+ const clauses = u.clauses ?? [];
24624
+ if (clauses.some((c) => c.clause)) {
24625
+ withClause++;
24626
+ } else if (clauses.length > 0) {
24627
+ anchorOnlyProvenance++;
24628
+ } else {
24629
+ withoutProvenance++;
24630
+ }
24631
+ if (clauses.some((c) => c.doc && !c.doc.startsWith("urn:"))) {
24632
+ nonUrnDocRefs++;
24633
+ }
24634
+ }
24635
+ const document = {
24636
+ projection: RETRIEVAL_PROJECTION,
24637
+ facet_version: RETRIEVAL_FACET_VERSION,
24638
+ package: pkg,
24639
+ ...options.sourceHash !== void 0 ? { source_hash: options.sourceHash } : {},
24640
+ units
24641
+ };
24642
+ return {
24643
+ document,
24644
+ json: JSON.stringify(sortDeep(document), null, 2) + "\n",
24645
+ stats: {
24646
+ units: units.length,
24647
+ byKind,
24648
+ withClause,
24649
+ anchorOnlyProvenance,
24650
+ nonUrnDocRefs,
24651
+ withoutProvenance,
24652
+ withVariants,
24653
+ droppedTextBlocks
24654
+ }
24655
+ };
24656
+ }
24657
+ function exportPackageRetrieval(dir) {
24658
+ const { standard } = loadPackageWithIssues(dir);
24659
+ return exportStandardRetrieval(standard, {
24660
+ sourceHash: packageSourceHash(dir)
24661
+ });
24662
+ }
24663
+
24664
+ // src/export/impact.ts
24665
+ var IMPACT_GRAPH_VERSION = "impact-graph/1";
24666
+ function provenanceOf2(el) {
24667
+ const first = el.sourceRefs?.[0] ?? (el.sourceRef && typeof el.sourceRef === "object" ? el.sourceRef : null) ?? (el.source && typeof el.source === "object" ? el.source : null);
24668
+ if (first && (first.doc || first.clause)) {
24669
+ return { source: { doc: first.doc ?? "", clause: first.clause ?? "" } };
24670
+ }
24671
+ const ref = (el.refs ?? []).find((r) => r.predicate === "derives-from");
24672
+ return ref ? { derivesFrom: ref.target } : {};
24673
+ }
24674
+ function impactGraph(standard) {
24675
+ const forward = /* @__PURE__ */ new Map();
24676
+ const add = (element, carrier, kind, facet, target, via) => {
24677
+ if (target === void 0 || target === "") {
24678
+ return;
24679
+ }
24680
+ const edge = { kind, facet, target, ...provenanceOf2(carrier) };
24681
+ if (via !== void 0) {
24682
+ edge.via = via;
24683
+ }
24684
+ const list = forward.get(element);
24685
+ if (list) {
24686
+ list.push(edge);
24687
+ } else {
24688
+ forward.set(element, [edge]);
24689
+ }
24690
+ };
24691
+ const verdictIds = new Set((standard.verdicts ?? []).map((v) => v.id));
24692
+ for (const r of standard.requirements ?? []) {
24693
+ for (const p of r.bindsTo ?? []) {
24694
+ add(r.id, r, "binding", "binds_to", p);
24695
+ }
24696
+ for (const d of r.dependencies ?? []) {
24697
+ add(r.id, r, "prerequisite", "dependencies", d);
24698
+ }
24699
+ if (r.limit?.accepts?.verdict) {
24700
+ add(
24701
+ r.id,
24702
+ r,
24703
+ "acceptance",
24704
+ "limit.accepts.verdict",
24705
+ r.limit.accepts.verdict
24706
+ );
24707
+ }
24708
+ for (const a of r.applicability ?? []) {
24709
+ add(r.id, r, "classification", "applicability", a.dimension);
24710
+ }
24711
+ if (r.channel) {
24712
+ add(r.id, r, "evidence channel", "channel", r.channel);
24713
+ }
24714
+ }
24715
+ for (const t of standard.conformanceTests ?? []) {
24716
+ for (const target of t.targets ?? []) {
24717
+ add(t.id, t, "coverage", "targets", target);
24718
+ }
24719
+ add(
24720
+ t.id,
24721
+ t,
24722
+ "specialization",
24723
+ "inherits_from",
24724
+ t.inheritsFrom || void 0
24725
+ );
24726
+ for (const d of t.dependencies ?? []) {
24727
+ add(t.id, t, "prerequisite", "dependencies", d);
24728
+ }
24729
+ if (t.instances?.by) {
24730
+ add(t.id, t, "instantiation", "instances.by", t.instances.by);
24731
+ }
24732
+ for (const f of t.resultForms ?? []) {
24733
+ add(t.id, t, "evidence view", "result_forms", f);
24734
+ }
24735
+ for (const a of t.producesArtifacts ?? []) {
24736
+ add(t.id, t, "issuance", "produces_artifacts", a);
24737
+ }
24738
+ }
24739
+ for (const v of standard.verdicts ?? []) {
24740
+ for (const inp of v.inputs ?? []) {
24741
+ add(
24742
+ v.id,
24743
+ v,
24744
+ verdictIds.has(inp) ? "acceptance chain" : "derivation",
24745
+ "inputs",
24746
+ inp
24747
+ );
24748
+ }
24749
+ add(v.id, v, "state transition", "behavior", v.behavior || void 0);
24750
+ }
24751
+ for (const c of standard.calculations ?? []) {
24752
+ for (const inp of c.inputs ?? []) {
24753
+ add(c.id, c, "derivation", "inputs", inp.name);
24754
+ }
24755
+ if (c.lookup?.key) {
24756
+ add(c.id, c, "data source", "lookup", c.lookup.key);
24757
+ }
24758
+ add(c.id, c, "data source", "profile", c.profile || void 0);
24759
+ for (const p of c.params ?? []) {
24760
+ add(c.id, c, "parameterization", "params", p);
24761
+ }
24762
+ }
24763
+ for (const f of standard.forms ?? []) {
24764
+ for (const r of f.requirements ?? []) {
24765
+ add(f.id, f, "evidence scope", "requirements", r);
24766
+ }
24767
+ for (const table of f.calculationContext?.tables ?? []) {
24768
+ add(f.id, f, "derivation context", "calculation_context", table);
24769
+ }
24770
+ const fields = (list) => {
24771
+ for (const fld of list ?? []) {
24772
+ add(f.id, f, "binding", "field.bind", fld.bind, fld.name);
24773
+ add(
24774
+ f.id,
24775
+ f,
24776
+ "binding",
24777
+ "field.verdict",
24778
+ fld.verdict || void 0,
24779
+ fld.name
24780
+ );
24781
+ for (const t of fld.targets ?? []) {
24782
+ add(f.id, f, "binding", "field.targets", t, fld.name);
24783
+ }
24784
+ fields(fld.fields);
24785
+ }
24786
+ };
24787
+ fields(f.fields);
24788
+ }
24789
+ for (const fu of standard.formulasUsed ?? []) {
24790
+ for (const formula of fu.formulas ?? []) {
24791
+ add(fu.id, fu, "derivation", "formulas_used", formula);
24792
+ }
24793
+ }
24794
+ const dims = [
24795
+ ...standard.dimensions ?? [],
24796
+ ...(standard.instruments ?? []).flatMap((i) => i.dimensions ?? [])
24797
+ ];
24798
+ for (const d of dims) {
24799
+ for (const v of d.values ?? []) {
24800
+ for (const target of v.implies ?? []) {
24801
+ add(
24802
+ d.id,
24803
+ d,
24804
+ "subsumption",
24805
+ "values.implies",
24806
+ `${d.id}.${target}`,
24807
+ v.id
24808
+ );
24809
+ }
24810
+ }
24811
+ }
24812
+ for (const i of standard.instances ?? []) {
24813
+ add(i.id, {}, "instantiation", "of", i.of);
24814
+ add(i.id, {}, "instantiation", "model", i.model || void 0);
24815
+ add(i.id, {}, "instantiation", "group", i.group || void 0);
24816
+ add(i.id, {}, "instantiation", "family", i.family || void 0);
24817
+ }
24818
+ const m = standard.packageManifest;
24819
+ if (m) {
24820
+ for (const u of m.uses ?? []) {
24821
+ add(m.id, {}, "composition", "uses", u);
24822
+ }
24823
+ for (const mt of m.mapsTo ?? []) {
24824
+ add(m.id, {}, "composition", "maps_to", mt);
24825
+ }
24826
+ for (const s of m.supersedes ?? []) {
24827
+ add(m.id, {}, "edition lineage", "supersedes", s);
24828
+ }
24829
+ for (const s of m.replaces ?? []) {
24830
+ add(m.id, {}, "edition lineage", "replaces", s);
24831
+ }
24832
+ for (const s of m.supersededBy ?? []) {
24833
+ add(m.id, {}, "edition lineage", "superseded_by", s);
24834
+ }
24835
+ }
24836
+ const reverse = {};
24837
+ const forwardObj = {};
24838
+ for (const [element, edges] of [...forward.entries()].sort()) {
24839
+ forwardObj[element] = edges;
24840
+ for (const e of edges) {
24841
+ (reverse[e.target] ??= []).push({ ...e, element });
24842
+ }
24843
+ }
24844
+ return {
24845
+ version: IMPACT_GRAPH_VERSION,
24846
+ package: {
24847
+ id: m?.id ?? "",
24848
+ version: m?.version ?? "",
24849
+ baseUrn: m?.baseUrn ?? ""
24850
+ },
24851
+ forward: forwardObj,
24852
+ reverse
24853
+ };
24854
+ }
24855
+ function exportPackageImpact(dir) {
24856
+ const standard = loadPackage(dir);
24857
+ const graph = impactGraph(standard);
24858
+ const byKind = {};
24859
+ let edges = 0;
24860
+ for (const list of Object.values(graph.forward)) {
24861
+ for (const e of list) {
24862
+ edges++;
24863
+ byKind[e.kind] = (byKind[e.kind] ?? 0) + 1;
24864
+ }
24865
+ }
24866
+ return {
24867
+ graph,
24868
+ json: JSON.stringify(graph, null, 2) + "\n",
24869
+ stats: {
24870
+ edges,
24871
+ elements: Object.keys(graph.forward).length,
24872
+ targets: Object.keys(graph.reverse).length,
24873
+ byKind
24874
+ }
24875
+ };
24876
+ }
24877
+
24878
+ // src/package-diff.ts
24879
+ import { existsSync as existsSync6, readdirSync as readdirSync5, readFileSync as readFileSync7 } from "fs";
24880
+ import { join as join6 } from "path";
24881
+ function packageMappings(dir, standard) {
24882
+ const profiles = [...standard.mapProfiles ?? []];
24883
+ if (existsSync6(dir)) {
24884
+ for (const entry of readdirSync5(dir).sort()) {
24885
+ if (!entry.endsWith(".prm")) {
24886
+ continue;
24887
+ }
24888
+ profiles.push(
24889
+ ...prmToMapProfiles(loadPrm(readFileSync7(join6(dir, entry), "utf8")))
24890
+ );
24891
+ }
24892
+ }
24893
+ const modelId = standard.packageManifest?.id ?? standard.meta?.namespace ?? "";
24894
+ return profiles.flatMap((p) => mappingsFromProfile(p, modelId));
24895
+ }
24896
+ function packageClauseTexts(dir) {
24897
+ const out = /* @__PURE__ */ new Map();
24898
+ const prdDir = join6(dir, "sources-prd");
24899
+ if (!existsSync6(prdDir)) {
24900
+ return out;
24901
+ }
24902
+ for (const entry of readdirSync5(prdDir).sort()) {
24903
+ if (!entry.endsWith(".sentences.json")) {
24904
+ continue;
24905
+ }
24906
+ let payload;
24907
+ try {
24908
+ payload = JSON.parse(readFileSync7(join6(prdDir, entry), "utf8"));
24909
+ } catch {
24910
+ continue;
24911
+ }
24912
+ const urn = payload.document?.urn ?? "";
24913
+ if (!urn) {
24914
+ continue;
24915
+ }
24916
+ const basis = normalizeSourceRef(urn, "").basis;
24917
+ const byClause = /* @__PURE__ */ new Map();
24918
+ for (const s of payload.sentences ?? []) {
24919
+ if (!s.clause || s.text === void 0) {
24920
+ continue;
24921
+ }
24922
+ (byClause.get(s.clause) ?? byClause.set(s.clause, []).get(s.clause)).push(s.text);
24923
+ }
24924
+ for (const [clause, texts] of byClause) {
24925
+ out.set(clauseTextKey(basis, clause), texts.join("\n"));
24926
+ }
24927
+ }
24928
+ return out;
24929
+ }
24930
+ function diffPackageDirs(dirA, dirB, options = {}) {
24931
+ const loadedA = loadPackageWithIssues(dirA, {
24932
+ resolvePackage: options.resolvePackage
24933
+ });
24934
+ const loadedB = loadPackageWithIssues(dirB, {
24935
+ resolvePackage: options.resolvePackage
24936
+ });
24937
+ const diff = diffStandards(loadedA.standard, loadedB.standard, {
24938
+ ...options,
24939
+ mappingsA: packageMappings(dirA, loadedA.standard),
24940
+ mappingsB: packageMappings(dirB, loadedB.standard),
24941
+ ...options.compareTexts ? {
24942
+ sentencesA: packageClauseTexts(dirA),
24943
+ sentencesB: packageClauseTexts(dirB)
24944
+ } : {}
24945
+ });
23001
24946
  return {
23002
24947
  diff,
23003
24948
  standardA: loadedA.standard,
@@ -23010,18 +24955,18 @@ function diffPackageDirs(dirA, dirB, options = {}) {
23010
24955
  // scripts/check.mts
23011
24956
  var CHECK_USAGE = "Usage: primmel check [--strict] [--audit] [--coverage] [--rules] [--with <pkg-id>=<dir>]\u2026 <package-dir>";
23012
24957
  var DIFF_USAGE = "Usage: primmel diff [--json] [--exit-code] [--compare-texts] [--with <pkg-id>=<dir>]\u2026 <a> <b>";
23013
- var EXPORT_USAGE = "Usage: primmel export reqif|rdf <package-dir> [--out <file>] [--format turtle|jsonld]";
24958
+ var EXPORT_USAGE = "Usage: primmel export reqif|rdf|retrieval|impact <package-dir> [--out <file>] [--format turtle|jsonld]";
23014
24959
  function readablePackageDirProblem(target, needsManifest) {
23015
24960
  try {
23016
- if (!statSync3(target).isDirectory()) {
24961
+ if (!statSync4(target).isDirectory()) {
23017
24962
  return "not a directory";
23018
24963
  }
23019
- readdirSync5(target);
24964
+ readdirSync6(target);
23020
24965
  } catch (e) {
23021
24966
  const err = e;
23022
24967
  return err.code === "ENOENT" ? "no such directory" : err.message;
23023
24968
  }
23024
- if (needsManifest && !existsSync7(join6(target, "package.primmel"))) {
24969
+ if (needsManifest && !existsSync7(join7(target, "package.primmel"))) {
23025
24970
  return "no package.primmel found";
23026
24971
  }
23027
24972
  return null;
@@ -23180,7 +25125,7 @@ function diffCli(args2) {
23180
25125
  }
23181
25126
  function exportCli(args2) {
23182
25127
  const surface = args2[0];
23183
- if (surface !== "reqif" && surface !== "rdf") {
25128
+ if (surface !== "reqif" && surface !== "rdf" && surface !== "retrieval" && surface !== "impact") {
23184
25129
  console.error(EXPORT_USAGE);
23185
25130
  process.exit(2);
23186
25131
  }
@@ -23196,7 +25141,7 @@ function exportCli(args2) {
23196
25141
  process.exit(2);
23197
25142
  }
23198
25143
  const rdfFormat = values.get("--format") ?? "turtle";
23199
- if (surface === "reqif" && values.has("--format")) {
25144
+ if (surface !== "rdf" && values.has("--format")) {
23200
25145
  console.error("--format applies to `primmel export rdf` only");
23201
25146
  console.error(EXPORT_USAGE);
23202
25147
  process.exit(2);
@@ -23215,7 +25160,17 @@ function exportCli(args2) {
23215
25160
  let document;
23216
25161
  let summary;
23217
25162
  try {
23218
- if (surface === "reqif") {
25163
+ if (surface === "impact") {
25164
+ const result = exportPackageImpact(dir);
25165
+ document = result.json;
25166
+ const s = result.stats;
25167
+ summary = `${n(s.edges, "edge", "edges")} (${Object.entries(s.byKind).map(([k, c]) => `${c} ${k}`).join(", ")}), ${n(s.elements, "element", "elements")} declaring, ${n(s.targets, "target", "targets")} indexed`;
25168
+ } else if (surface === "retrieval") {
25169
+ const result = exportPackageRetrieval(dir);
25170
+ document = result.json;
25171
+ const s = result.stats;
25172
+ summary = `${n(s.units, "unit", "units")} (${Object.entries(s.byKind).map(([k, c]) => `${c} ${k}`).join(", ")}), ${n(s.withClause, "unit", "units")} clause-cited` + (s.anchorOnlyProvenance > 0 ? `, ${n(s.anchorOnlyProvenance, "unit", "units")} with anchor-only provenance (ask-1 debt)` : "") + (s.nonUrnDocRefs > 0 ? `, ${n(s.nonUrnDocRefs, "unit", "units")} with legacy non-URN doc refs` : "") + (s.withoutProvenance > 0 ? `, ${n(s.withoutProvenance, "unit", "units")} without provenance` : "") + (s.withVariants > 0 ? `, ${n(s.withVariants, "unit", "units")} with language variants` : "") + (s.droppedTextBlocks > 0 ? `, ${n(s.droppedTextBlocks, "text block", "text blocks")} addressed at unprojected elements (dropped)` : "");
25173
+ } else if (surface === "reqif") {
23219
25174
  const result = exportPackageReqif(dir);
23220
25175
  document = result.xml;
23221
25176
  const s = result.stats;