@primmel/primmel 1.8.2 → 1.9.0

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