@primmel/primmel 1.4.1 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/dist/src/check-rules.d.ts.map +1 -1
  2. package/dist/src/check-rules.js +7 -1
  3. package/dist/src/check-rules.js.map +1 -1
  4. package/dist/src/check.d.ts +13 -0
  5. package/dist/src/check.d.ts.map +1 -1
  6. package/dist/src/check.js +91 -0
  7. package/dist/src/check.js.map +1 -1
  8. package/dist/src/ser-des/config/artifact.d.ts.map +1 -1
  9. package/dist/src/ser-des/config/artifact.js +29 -12
  10. package/dist/src/ser-des/config/artifact.js.map +1 -1
  11. package/dist/src/ser-des/config/calculation.d.ts.map +1 -1
  12. package/dist/src/ser-des/config/calculation.js +21 -6
  13. package/dist/src/ser-des/config/calculation.js.map +1 -1
  14. package/dist/src/ser-des/config/competenceKind.d.ts.map +1 -1
  15. package/dist/src/ser-des/config/competenceKind.js +9 -0
  16. package/dist/src/ser-des/config/competenceKind.js.map +1 -1
  17. package/dist/src/ser-des/config/conformanceClass.d.ts.map +1 -1
  18. package/dist/src/ser-des/config/conformanceClass.js +2 -1
  19. package/dist/src/ser-des/config/conformanceClass.js.map +1 -1
  20. package/dist/src/ser-des/config/conformanceTest.d.ts.map +1 -1
  21. package/dist/src/ser-des/config/conformanceTest.js +26 -19
  22. package/dist/src/ser-des/config/conformanceTest.js.map +1 -1
  23. package/dist/src/ser-des/config/constraint.d.ts.map +1 -1
  24. package/dist/src/ser-des/config/constraint.js +9 -0
  25. package/dist/src/ser-des/config/constraint.js.map +1 -1
  26. package/dist/src/ser-des/config/field-parser.d.ts.map +1 -1
  27. package/dist/src/ser-des/config/field-parser.js +47 -1
  28. package/dist/src/ser-des/config/field-parser.js.map +1 -1
  29. package/dist/src/ser-des/config/form.d.ts.map +1 -1
  30. package/dist/src/ser-des/config/form.js +33 -1
  31. package/dist/src/ser-des/config/form.js.map +1 -1
  32. package/dist/src/ser-des/config/formulasUsed.d.ts.map +1 -1
  33. package/dist/src/ser-des/config/formulasUsed.js +20 -9
  34. package/dist/src/ser-des/config/formulasUsed.js.map +1 -1
  35. package/dist/src/ser-des/config/index.d.ts.map +1 -1
  36. package/dist/src/ser-des/config/index.js +9 -0
  37. package/dist/src/ser-des/config/index.js.map +1 -1
  38. package/dist/src/ser-des/config/packageManifest.d.ts.map +1 -1
  39. package/dist/src/ser-des/config/packageManifest.js +26 -1
  40. package/dist/src/ser-des/config/packageManifest.js.map +1 -1
  41. package/dist/src/ser-des/config/predicate.d.ts +5 -0
  42. package/dist/src/ser-des/config/predicate.d.ts.map +1 -0
  43. package/dist/src/ser-des/config/predicate.js +111 -0
  44. package/dist/src/ser-des/config/predicate.js.map +1 -0
  45. package/dist/src/ser-des/config/process.d.ts.map +1 -1
  46. package/dist/src/ser-des/config/process.js +15 -12
  47. package/dist/src/ser-des/config/process.js.map +1 -1
  48. package/dist/src/ser-des/config/ref.d.ts +70 -0
  49. package/dist/src/ser-des/config/ref.d.ts.map +1 -0
  50. package/dist/src/ser-des/config/ref.js +165 -0
  51. package/dist/src/ser-des/config/ref.js.map +1 -0
  52. package/dist/src/ser-des/config/referenceMaterial.d.ts.map +1 -1
  53. package/dist/src/ser-des/config/referenceMaterial.js +43 -19
  54. package/dist/src/ser-des/config/referenceMaterial.js.map +1 -1
  55. package/dist/src/ser-des/config/requirement.d.ts.map +1 -1
  56. package/dist/src/ser-des/config/requirement.js +25 -10
  57. package/dist/src/ser-des/config/requirement.js.map +1 -1
  58. package/dist/src/ser-des/config/subject.d.ts.map +1 -1
  59. package/dist/src/ser-des/config/subject.js +160 -21
  60. package/dist/src/ser-des/config/subject.js.map +1 -1
  61. package/dist/src/ser-des/config/symbol.d.ts.map +1 -1
  62. package/dist/src/ser-des/config/symbol.js +10 -1
  63. package/dist/src/ser-des/config/symbol.js.map +1 -1
  64. package/dist/src/ser-des/config/table.d.ts.map +1 -1
  65. package/dist/src/ser-des/config/table.js +10 -8
  66. package/dist/src/ser-des/config/table.js.map +1 -1
  67. package/dist/src/ser-des/config/term.d.ts.map +1 -1
  68. package/dist/src/ser-des/config/term.js +18 -1
  69. package/dist/src/ser-des/config/term.js.map +1 -1
  70. package/dist/src/ser-des/config/testPointSet.d.ts.map +1 -1
  71. package/dist/src/ser-des/config/testPointSet.js +24 -13
  72. package/dist/src/ser-des/config/testPointSet.js.map +1 -1
  73. package/dist/src/ser-des/config/testSequence.d.ts.map +1 -1
  74. package/dist/src/ser-des/config/testSequence.js +19 -7
  75. package/dist/src/ser-des/config/testSequence.js.map +1 -1
  76. package/dist/src/ser-des/config/verdict.d.ts.map +1 -1
  77. package/dist/src/ser-des/config/verdict.js +24 -13
  78. package/dist/src/ser-des/config/verdict.js.map +1 -1
  79. package/dist/src/ser-des/parse-block.d.ts +16 -5
  80. package/dist/src/ser-des/parse-block.d.ts.map +1 -1
  81. package/dist/src/ser-des/parse-block.js +45 -6
  82. package/dist/src/ser-des/parse-block.js.map +1 -1
  83. package/dist/src/ser-des/parse.d.ts.map +1 -1
  84. package/dist/src/ser-des/parse.js +1 -0
  85. package/dist/src/ser-des/parse.js.map +1 -1
  86. package/dist/src/ser-des/types.d.ts +2 -0
  87. package/dist/src/ser-des/types.d.ts.map +1 -1
  88. package/dist/src/types/Artifact.d.ts +6 -0
  89. package/dist/src/types/Artifact.d.ts.map +1 -1
  90. package/dist/src/types/Calculation.d.ts +2 -0
  91. package/dist/src/types/Calculation.d.ts.map +1 -1
  92. package/dist/src/types/CompetenceKind.d.ts +3 -0
  93. package/dist/src/types/CompetenceKind.d.ts.map +1 -1
  94. package/dist/src/types/ConformanceTest.d.ts +3 -0
  95. package/dist/src/types/ConformanceTest.d.ts.map +1 -1
  96. package/dist/src/types/Constraint.d.ts +3 -0
  97. package/dist/src/types/Constraint.d.ts.map +1 -1
  98. package/dist/src/types/Form.d.ts +9 -0
  99. package/dist/src/types/Form.d.ts.map +1 -1
  100. package/dist/src/types/FormulasUsed.d.ts +2 -0
  101. package/dist/src/types/FormulasUsed.d.ts.map +1 -1
  102. package/dist/src/types/Invariant.d.ts +1 -0
  103. package/dist/src/types/Invariant.d.ts.map +1 -1
  104. package/dist/src/types/Package.d.ts +4 -0
  105. package/dist/src/types/Package.d.ts.map +1 -1
  106. package/dist/src/types/Ref.d.ts +11 -0
  107. package/dist/src/types/Ref.d.ts.map +1 -0
  108. package/dist/src/types/Ref.js +3 -0
  109. package/dist/src/types/Ref.js.map +1 -0
  110. package/dist/src/types/RefPredicate.d.ts +22 -0
  111. package/dist/src/types/RefPredicate.d.ts.map +1 -0
  112. package/dist/src/types/RefPredicate.js +3 -0
  113. package/dist/src/types/RefPredicate.js.map +1 -0
  114. package/dist/src/types/ReferenceMaterial.d.ts +7 -0
  115. package/dist/src/types/ReferenceMaterial.d.ts.map +1 -1
  116. package/dist/src/types/Requirement.d.ts +3 -0
  117. package/dist/src/types/Requirement.d.ts.map +1 -1
  118. package/dist/src/types/Standard.d.ts +3 -0
  119. package/dist/src/types/Standard.d.ts.map +1 -1
  120. package/dist/src/types/Subject.d.ts +22 -0
  121. package/dist/src/types/Subject.d.ts.map +1 -1
  122. package/dist/src/types/Symbol.d.ts +4 -0
  123. package/dist/src/types/Symbol.d.ts.map +1 -1
  124. package/dist/src/types/Table.d.ts +4 -0
  125. package/dist/src/types/Table.d.ts.map +1 -1
  126. package/dist/src/types/Term.d.ts +2 -0
  127. package/dist/src/types/Term.d.ts.map +1 -1
  128. package/dist/src/types/TestPointSet.d.ts +4 -0
  129. package/dist/src/types/TestPointSet.d.ts.map +1 -1
  130. package/dist/src/types/TestSequence.d.ts +2 -0
  131. package/dist/src/types/TestSequence.d.ts.map +1 -1
  132. package/dist/src/types/Verdict.d.ts +4 -0
  133. package/dist/src/types/Verdict.d.ts.map +1 -1
  134. package/dist/src/types/process.d.ts +3 -0
  135. package/dist/src/types/process.d.ts.map +1 -1
  136. package/dist/src/validate.js +9 -1
  137. package/dist/src/validate.js.map +1 -1
  138. package/dist-browser/index.mjs +1543 -1227
  139. package/dist-cli/primmel.mjs +696 -101
  140. package/package.json +1 -1
@@ -222,6 +222,7 @@ function parse(mmelString, parsers, options = {}) {
222
222
  referenceMaterials: {},
223
223
  testPointSets: {},
224
224
  competenceKinds: {},
225
+ predicates: {},
225
226
  constraints: {},
226
227
  discrepancyRecords: {},
227
228
  stateMachines: {},
@@ -388,11 +389,39 @@ function forEachEntry(data, visitor, errCtx) {
388
389
  `Parsing error: ${errCtx.construct}. ID ${errCtx.id}: Expecting value for ${keyword}`
389
390
  );
390
391
  }
391
- const claimed = visitor(keyword, () => t[i++]);
392
+ const claimed = visitor(
393
+ keyword,
394
+ () => t[i++],
395
+ () => t[i]
396
+ );
392
397
  if (!claimed) {
398
+ if (keyword === "ref") {
399
+ i++;
400
+ i++;
401
+ if (i < t.length && t[i].startsWith("{")) {
402
+ i++;
403
+ }
404
+ } else {
405
+ i++;
406
+ }
407
+ }
408
+ }
409
+ }
410
+ function skipUnknownValue(t, i, keyword) {
411
+ if (keyword === "ref") {
412
+ i++;
413
+ if (i < t.length) {
393
414
  i++;
394
415
  }
416
+ if (i < t.length && t[i].startsWith("{")) {
417
+ i++;
418
+ }
419
+ return i;
420
+ }
421
+ if (i < t.length) {
422
+ i++;
395
423
  }
424
+ return i;
396
425
  }
397
426
  function forEachAttribute(data, visitor, errCtx) {
398
427
  if (data === "") {
@@ -1079,6 +1108,119 @@ var parseMetadata = function(token) {
1079
1108
  };
1080
1109
  };
1081
1110
 
1111
+ // src/ser-des/config/ref.ts
1112
+ function parseRef(t, i, stripWrapping2, unwrapBlock2) {
1113
+ const predicate = stripWrapping2(t[i++] ?? "");
1114
+ const target = stripWrapping2(t[i++] ?? "");
1115
+ const ref = { predicate, target };
1116
+ if (i < t.length && t[i].startsWith("{")) {
1117
+ const block = unwrapBlock2(t[i++]);
1118
+ const m = /note\s+"([^"]*)"/.exec(block) ?? /note\s+(\S+)/.exec(block);
1119
+ if (m) {
1120
+ ref.note = m[1];
1121
+ }
1122
+ }
1123
+ return { ref, next: i };
1124
+ }
1125
+ function parseRefFromReaders(value, peek, stripWrapping2, unwrapBlock2) {
1126
+ const parts = [value(), value()];
1127
+ const next = peek();
1128
+ if (next && next.startsWith("{")) {
1129
+ parts.push(value());
1130
+ }
1131
+ return parseRef(parts, 0, stripWrapping2, unwrapBlock2).ref;
1132
+ }
1133
+ function dumpRefs(refs, indent, escapeString2) {
1134
+ if (!refs || refs.length === 0) {
1135
+ return "";
1136
+ }
1137
+ let out = "";
1138
+ for (const r of refs) {
1139
+ out += `${indent}ref ${r.predicate} "${escapeString2(r.target)}"`;
1140
+ out += r.note ? ` {
1141
+ ${indent} note "${escapeString2(r.note)}"
1142
+ ${indent}}
1143
+ ` : "\n";
1144
+ }
1145
+ return out;
1146
+ }
1147
+ function refTargetToSourceRef(target) {
1148
+ const m = /^(urn:[^#]+)(?:#(.+))?$/.exec(target);
1149
+ if (!m) {
1150
+ return null;
1151
+ }
1152
+ const anchor = m[2];
1153
+ if (!anchor) {
1154
+ return { doc: target, clause: "" };
1155
+ }
1156
+ if (anchor.startsWith("clause-")) {
1157
+ const rest = anchor.slice("clause-".length);
1158
+ const slash = rest.indexOf("/");
1159
+ if (slash >= 0) {
1160
+ return {
1161
+ doc: m[1],
1162
+ clause: rest.slice(0, slash),
1163
+ fragment: rest.slice(slash + 1)
1164
+ };
1165
+ }
1166
+ return { doc: m[1], clause: rest };
1167
+ }
1168
+ return { doc: target, clause: "" };
1169
+ }
1170
+ function foldRefIntoLegacy(el, ref) {
1171
+ if (ref.predicate === "derives-from") {
1172
+ const b = refTargetToSourceRef(ref.target);
1173
+ if (!b) {
1174
+ return false;
1175
+ }
1176
+ (el.sourceRefs ??= []).push(b);
1177
+ if ("source" in el && !el.source) {
1178
+ el.source = b;
1179
+ }
1180
+ if ("sourceRef" in el && !el.sourceRef) {
1181
+ el.sourceRef = b;
1182
+ }
1183
+ if ("reference" in el && !el.reference) {
1184
+ el.reference = b.doc;
1185
+ }
1186
+ return true;
1187
+ }
1188
+ if (ref.predicate === "cites") {
1189
+ if (el.referenceIds) {
1190
+ el.referenceIds.push(ref.target);
1191
+ } else if (el.fieldReferences) {
1192
+ el.fieldReferences.push({ urn: ref.target, role: "reference" });
1193
+ } else if (el.formReferences) {
1194
+ el.formReferences.push({ urn: ref.target, role: "reference" });
1195
+ }
1196
+ return true;
1197
+ }
1198
+ const CITATION_ROLES = [
1199
+ "requirement",
1200
+ "test-procedure",
1201
+ "calculation",
1202
+ "report-format",
1203
+ "method"
1204
+ ];
1205
+ if (CITATION_ROLES.includes(ref.predicate)) {
1206
+ const channel = el.fieldReferences ?? el.formReferences;
1207
+ if (!channel) {
1208
+ return false;
1209
+ }
1210
+ channel.push({ urn: ref.target, role: ref.predicate });
1211
+ return true;
1212
+ }
1213
+ return false;
1214
+ }
1215
+ function dumpSourceRefAsRef(src, indent, escapeString2) {
1216
+ if (src.doc && src.doc.startsWith("urn:")) {
1217
+ const anchor = `${src.doc}${src.clause ? "#clause-" + src.clause : ""}${src.fragment ? "/" + src.fragment : ""}`;
1218
+ return `${indent}ref derives-from "${escapeString2(anchor)}"
1219
+ `;
1220
+ }
1221
+ return `${indent}source { doc "${escapeString2(src.doc ?? "")}" clause "${escapeString2(String(src.clause ?? ""))}"` + (src.fragment ? ` fragment "${escapeString2(src.fragment)}"` : "") + " }\n";
1222
+ }
1223
+
1082
1224
  // src/ser-des/config/series.ts
1083
1225
  function parseSeriesDecl(block) {
1084
1226
  const decl = { axes: [], cellSymbol: "", cellUnit: "" };
@@ -1347,6 +1489,7 @@ function parseFormField(name, block, type) {
1347
1489
  pattern: "",
1348
1490
  required: false,
1349
1491
  requiredWhen: "",
1492
+ refs: [],
1350
1493
  measurementMethod: "",
1351
1494
  calculationId: null,
1352
1495
  calculationBindings: [],
@@ -1480,6 +1623,12 @@ function parseFormField(name, block, type) {
1480
1623
  field.referenceIds = tokenizePackage(t[i++]).map(stripWrapping);
1481
1624
  } else if (cmd === "references") {
1482
1625
  field.fieldReferences = parseRoleReferences(unwrapBlock(t[i++]));
1626
+ } else if (cmd === "ref") {
1627
+ const r = parseRef(t, i, stripWrapping, unwrapBlock);
1628
+ if (!foldRefIntoLegacy(field, r.ref)) {
1629
+ field.refs.push(r.ref);
1630
+ }
1631
+ i = r.next;
1483
1632
  } else if (cmd === "specification_reference") {
1484
1633
  field.specificationReference = stripWrapping(t[i++]);
1485
1634
  } else if (cmd === "applicability") {
@@ -1809,10 +1958,24 @@ function dumpFormField(field, indent) {
1809
1958
  if (field.targets.length > 0) {
1810
1959
  inner.push("targets { " + field.targets.join(" ") + " }");
1811
1960
  }
1961
+ if (field.sourceRefs && field.sourceRefs.length > 0) {
1962
+ for (const s of field.sourceRefs) {
1963
+ inner.push(dumpSourceRefAsRef(s, "", escapeString).trimEnd());
1964
+ }
1965
+ }
1812
1966
  if (field.fieldReferences.length > 0) {
1813
- inner.push(
1814
- "references { " + dumpRoleReferences(field.fieldReferences) + " }"
1815
- );
1967
+ for (const r of field.fieldReferences) {
1968
+ inner.push(
1969
+ "ref " + roleToPredicateForDump(r.role) + ' "' + escapeString(r.urn) + '"'
1970
+ );
1971
+ }
1972
+ }
1973
+ if (field.refs && field.refs.length > 0) {
1974
+ for (const r of field.refs) {
1975
+ inner.push(
1976
+ "ref " + r.predicate + ' "' + escapeString(r.target) + '"' + (r.note ? ' { note "' + escapeString(r.note) + '" }' : "")
1977
+ );
1978
+ }
1816
1979
  }
1817
1980
  if (field.specificationReference) {
1818
1981
  inner.push(
@@ -1880,19 +2043,14 @@ function parseRoleReferences(block) {
1880
2043
  }
1881
2044
  return out;
1882
2045
  }
1883
- function dumpRoleReferences(refs) {
1884
- const roles = [];
1885
- const byRole = /* @__PURE__ */ new Map();
1886
- for (const r of refs) {
1887
- if (!byRole.has(r.role)) {
1888
- byRole.set(r.role, []);
1889
- roles.push(r.role);
1890
- }
1891
- byRole.get(r.role).push(r.urn);
2046
+ function roleToPredicateForDump(role) {
2047
+ if (role === "source") {
2048
+ return "derives-from";
1892
2049
  }
1893
- return roles.map(
1894
- (role) => role + " { " + byRole.get(role).map((u) => '"' + escapeString(u) + '"').join(" ") + " }"
1895
- ).join(" ");
2050
+ if (role === "reference") {
2051
+ return "cites";
2052
+ }
2053
+ return role;
1896
2054
  }
1897
2055
 
1898
2056
  // src/ser-des/config/quantity.ts
@@ -2192,7 +2350,7 @@ function parseProcessInstances(block) {
2192
2350
  }
2193
2351
  }
2194
2352
  } else {
2195
- unwrapBlock(t[i++]);
2353
+ i = skipUnknownValue(t, i, cmd);
2196
2354
  }
2197
2355
  }
2198
2356
  return out;
@@ -2440,7 +2598,7 @@ var parseProcess = function(id, data) {
2440
2598
  }
2441
2599
  forEachEntry(
2442
2600
  data,
2443
- (keyword, value) => {
2601
+ (keyword, value, peek) => {
2444
2602
  if (keyword === "modality") {
2445
2603
  result.modality = value();
2446
2604
  } else if (keyword === "name") {
@@ -2509,6 +2667,11 @@ var parseProcess = function(id, data) {
2509
2667
  result.source = src;
2510
2668
  }
2511
2669
  (result.sourceRefs ??= []).push(src);
2670
+ } else if (keyword === "ref") {
2671
+ const r = parseRefFromReaders(value, peek, stripWrapping, unwrapBlock);
2672
+ if (!foldRefIntoLegacy(result, r)) {
2673
+ (result.refs ??= []).push(r);
2674
+ }
2512
2675
  } else {
2513
2676
  return false;
2514
2677
  }
@@ -2773,8 +2936,9 @@ var dumpProcess = function(process2, ctx) {
2773
2936
  out += dumpDoes(process2.does);
2774
2937
  }
2775
2938
  for (const src of process2.sourceRefs ?? (process2.source && (process2.source.doc || process2.source.clause) ? [process2.source] : [])) {
2776
- out += ' source { doc "' + escapeString(src.doc) + '" clause "' + escapeString(src.clause) + '"' + (src.fragment ? ' fragment "' + escapeString(src.fragment) + '"' : "") + " }\n";
2939
+ out += dumpSourceRefAsRef(src, " ", escapeString);
2777
2940
  }
2941
+ out += dumpRefs(process2.refs, " ", escapeString);
2778
2942
  if (process2.parent && (process2.children.length === 0 || !ctx?.nested)) {
2779
2943
  out += " parent " + process2.parent + "\n";
2780
2944
  }
@@ -3516,6 +3680,12 @@ var parseTable = function(id, data) {
3516
3680
  } else if (command === "data") {
3517
3681
  const dataBlock = unwrapBlock(t[i++]);
3518
3682
  result.data = parseTableData(dataBlock);
3683
+ } else if (command === "ref") {
3684
+ const rr = parseRef(t, i, stripWrapping, unwrapBlock);
3685
+ if (!foldRefIntoLegacy(result, rr.ref)) {
3686
+ (result.refs ??= []).push(rr.ref);
3687
+ }
3688
+ i = rr.next;
3519
3689
  } else {
3520
3690
  i++;
3521
3691
  }
@@ -3583,7 +3753,7 @@ var dumpTable = function(t) {
3583
3753
  out += ' display "' + t.display + '"\n';
3584
3754
  }
3585
3755
  for (const src of t.sourceRefs ?? (t.sourceRef && (t.sourceRef.doc || t.sourceRef.clause) ? [t.sourceRef] : [])) {
3586
- out += ' source { doc "' + escapeString(src.doc) + '" clause "' + escapeString(src.clause) + '"' + (src.fragment ? ' fragment "' + escapeString(src.fragment) + '"' : "") + " }\n";
3756
+ out += dumpSourceRefAsRef(src, " ", escapeString);
3587
3757
  }
3588
3758
  if (t.sourceDiscrepancy) {
3589
3759
  out += dumpSourceDiscrepancy(t.sourceDiscrepancy, " ") + "\n";
@@ -4104,6 +4274,12 @@ var parseForm = function(id, data) {
4104
4274
  result.reportRows = rr;
4105
4275
  } else if (command === "references") {
4106
4276
  result.formReferences = parseRoleReferences(unwrapBlock(t[i++]));
4277
+ } else if (command === "ref") {
4278
+ const r = parseRef(t, i, stripWrapping, unwrapBlock);
4279
+ if (!foldRefIntoLegacy(result, r.ref)) {
4280
+ result.refs = [...result.refs ?? [], r.ref];
4281
+ }
4282
+ i = r.next;
4107
4283
  } else if (command === "calculation_context") {
4108
4284
  result.calculationContext = parseCalculationContext(
4109
4285
  unwrapBlock(t[i++])
@@ -4347,6 +4523,7 @@ function makeSubformRefField(subformId, block) {
4347
4523
  defaultValue: "",
4348
4524
  hasDefault: false,
4349
4525
  referenceIds: [],
4526
+ refs: [],
4350
4527
  fieldReferences: [],
4351
4528
  specificationReference: "",
4352
4529
  applicability: [],
@@ -4385,7 +4562,15 @@ var dumpForm = function(f) {
4385
4562
  out += " report_rows { field " + f.reportRows.field + " item_key " + f.reportRows.itemKey + " }\n";
4386
4563
  }
4387
4564
  if (f.formReferences.length > 0) {
4388
- out += " references { " + dumpRoleReferences(f.formReferences) + " }\n";
4565
+ for (const r of f.formReferences) {
4566
+ const pred = r.role === "source" ? "derives-from" : r.role === "reference" ? "cites" : r.role;
4567
+ out += " ref " + pred + ' "' + escapeString(r.urn) + '"\n';
4568
+ }
4569
+ }
4570
+ if (f.refs && f.refs.length > 0) {
4571
+ for (const r of f.refs) {
4572
+ out += " ref " + r.predicate + ' "' + escapeString(r.target) + '"' + (r.note ? ' { note "' + escapeString(r.note) + '" }' : "") + "\n";
4573
+ }
4389
4574
  }
4390
4575
  if (f.calculationContext) {
4391
4576
  const cc = f.calculationContext;
@@ -4651,7 +4836,14 @@ var parseSymbol = function(id, data) {
4651
4836
  };
4652
4837
  forEachEntry(
4653
4838
  data,
4654
- (command, value) => {
4839
+ (command, value, peek) => {
4840
+ if (command === "ref") {
4841
+ const r = parseRefFromReaders(value, peek, stripWrapping, unwrapBlock);
4842
+ if (!foldRefIntoLegacy(result, r)) {
4843
+ (result.refs ??= []).push(r);
4844
+ }
4845
+ return true;
4846
+ }
4655
4847
  if (command === "name") {
4656
4848
  result.name = unwrapped(value);
4657
4849
  } else if (command === "definition") {
@@ -4821,7 +5013,11 @@ var parseCalculation = function(id, data) {
4821
5013
  ref: [],
4822
5014
  _relations: {
4823
5015
  ref: []
4824
- }
5016
+ },
5017
+ // Initialized so the ref fold (docs/primmel/18 §18.4) mirrors the
5018
+ // first derives-from block here — the fold only mirrors slots the
5019
+ // object already carries.
5020
+ sourceRef: null
4825
5021
  };
4826
5022
  if (data !== "") {
4827
5023
  const t = tokenizePackage(data);
@@ -4845,6 +5041,12 @@ var parseCalculation = function(id, data) {
4845
5041
  result.expression = unwrapBlock(t[i++]);
4846
5042
  } else if (command === "reference") {
4847
5043
  result._relations.ref = tokenizePackage(t[i++]);
5044
+ } else if (command === "ref") {
5045
+ const rr = parseRef(t, i, stripWrapping, unwrapBlock);
5046
+ if (!foldRefIntoLegacy(result, rr.ref)) {
5047
+ (result.refs ??= []).push(rr.ref);
5048
+ }
5049
+ i = rr.next;
4848
5050
  } else if (command === "source") {
4849
5051
  const inner = tokenize(unwrapBlock(t[i++]));
4850
5052
  const src = {
@@ -5111,7 +5313,10 @@ var dumpCalculation = function(c) {
5111
5313
  out += " profile " + c.profile + "\n";
5112
5314
  }
5113
5315
  for (const src of c.sourceRefs ?? (c.sourceRef && (c.sourceRef.doc || c.sourceRef.clause) ? [c.sourceRef] : [])) {
5114
- out += ' source { doc "' + escapeString(src.doc) + '" clause "' + escapeString(src.clause) + '"' + (src.fragment ? ' fragment "' + escapeString(src.fragment) + '"' : "") + " }\n";
5316
+ out += dumpSourceRefAsRef(src, " ", escapeString);
5317
+ }
5318
+ for (const r of c.refs ?? []) {
5319
+ out += " ref " + r.predicate + ' "' + escapeString(r.target) + '"' + (r.note ? ' { note "' + escapeString(r.note) + '" }' : "") + "\n";
5115
5320
  }
5116
5321
  if (c.ref.length > 0) {
5117
5322
  out += " reference {\n";
@@ -6392,6 +6597,12 @@ var parseCompetenceKind = function(id, data) {
6392
6597
  );
6393
6598
  }
6394
6599
  result.methodStandards.push({ id: stdId, title: readValue(t[i++]) });
6600
+ } else if (keyword === "ref") {
6601
+ const rr = parseRef(t, i, stripWrapping, unwrapBlock);
6602
+ if (!foldRefIntoLegacy(result, rr.ref)) {
6603
+ (result.refs ??= []).push(rr.ref);
6604
+ }
6605
+ i = rr.next;
6395
6606
  } else {
6396
6607
  i++;
6397
6608
  }
@@ -6796,11 +7007,15 @@ var parseConformanceTest = function(id, data) {
6796
7007
  inheritsFrom: "",
6797
7008
  resultForms: [],
6798
7009
  derivedValues: [],
6799
- sourceDiscrepancy: null
7010
+ sourceDiscrepancy: null,
7011
+ // The singular provenance slot is initialized so the ref fold
7012
+ // (docs/primmel/18 §18.4) mirrors the first derives-from block into
7013
+ // it — the fold only mirrors slots the object already carries.
7014
+ sourceRef: null
6800
7015
  };
6801
7016
  forEachEntry(
6802
7017
  data,
6803
- (keyword, value) => {
7018
+ (keyword, value, peek) => {
6804
7019
  if (keyword === "name") {
6805
7020
  result.name = unwrapped(value);
6806
7021
  } else if (keyword === "purpose") {
@@ -6850,6 +7065,11 @@ var parseConformanceTest = function(id, data) {
6850
7065
  }
6851
7066
  } else if (keyword === "targets") {
6852
7067
  result.targets = tokenizePackage(value());
7068
+ } else if (keyword === "ref") {
7069
+ const rr = parseRefFromReaders(value, peek, stripWrapping, unwrapBlock);
7070
+ if (!foldRefIntoLegacy(result, rr)) {
7071
+ (result.refs ??= []).push(rr);
7072
+ }
6853
7073
  } else if (keyword === "binds_to") {
6854
7074
  result.bindsTo = tokenizePackage(value());
6855
7075
  } else if (keyword === "applicability") {
@@ -6969,13 +7189,16 @@ var dumpConformanceTest = function(ct) {
6969
7189
  }
6970
7190
  if (ct.sourceRefs && ct.sourceRefs.length > 0) {
6971
7191
  for (const src of ct.sourceRefs) {
6972
- out += ' reference { doc "' + escapeString(src.doc) + '" clause "' + escapeString(src.clause) + '"' + (src.fragment ? ' fragment "' + escapeString(src.fragment) + '"' : "") + " }\n";
7192
+ out += dumpSourceRefAsRef(src, " ", escapeString);
6973
7193
  }
6974
7194
  } else if (ct.sourceRef && ct.sourceRef.doc) {
6975
- out += ' reference { doc "' + escapeString(ct.sourceRef.doc) + '" clause "' + escapeString(ct.sourceRef.clause) + '"' + (ct.sourceRef.fragment ? ' fragment "' + escapeString(ct.sourceRef.fragment) + '"' : "") + " }\n";
7195
+ out += dumpSourceRefAsRef(ct.sourceRef, " ", escapeString);
6976
7196
  } else if (ct.reference) {
6977
7197
  out += " reference " + ct.reference + "\n";
6978
7198
  }
7199
+ for (const r of ct.refs ?? []) {
7200
+ out += " ref " + r.predicate + ' "' + escapeString(r.target) + '"' + (r.note ? ' { note "' + escapeString(r.note) + '" }' : "") + "\n";
7201
+ }
6979
7202
  if (ct.targets.length > 0) {
6980
7203
  out += " targets {\n";
6981
7204
  for (const t of ct.targets) {
@@ -7221,7 +7444,18 @@ var parseTerm = function(id, data) {
7221
7444
  };
7222
7445
  forEachEntry(
7223
7446
  data,
7224
- (command, value) => {
7447
+ (command, value, peek) => {
7448
+ if (command === "ref") {
7449
+ const r = parseRefFromReaders(value, peek, stripWrapping, unwrapBlock);
7450
+ if (r.predicate === "derives-from" && !result.source) {
7451
+ result.source = r.target;
7452
+ } else if (r.predicate === "cites") {
7453
+ result.referenceIds.push(r.target);
7454
+ } else {
7455
+ (result.refs ??= []).push(r);
7456
+ }
7457
+ return true;
7458
+ }
7225
7459
  if (command === "label") {
7226
7460
  result.label = unwrapped(value);
7227
7461
  } else if (command === "definition") {
@@ -7367,7 +7601,7 @@ var parseVerdict = function(id, data) {
7367
7601
  };
7368
7602
  forEachEntry(
7369
7603
  data,
7370
- (keyword, value) => {
7604
+ (keyword, value, peek) => {
7371
7605
  if (keyword === "quantity") {
7372
7606
  const qt = tokenize(unwrapBlock(value()));
7373
7607
  let j = 0;
@@ -7405,7 +7639,16 @@ var parseVerdict = function(id, data) {
7405
7639
  } else if (keyword === "acceptance") {
7406
7640
  result.acceptance = parseAcceptance(unwrapBlock(value()));
7407
7641
  } else if (keyword === "source" || keyword === "reference") {
7408
- result.source = readSource(unwrapBlock(value()));
7642
+ const src = readSource(unwrapBlock(value()));
7643
+ (result.sourceRefs ??= []).push(src);
7644
+ if (!result.source) {
7645
+ result.source = src;
7646
+ }
7647
+ } else if (keyword === "ref") {
7648
+ const r = parseRefFromReaders(value, peek, stripWrapping, unwrapBlock);
7649
+ if (!foldRefIntoLegacy(result, r)) {
7650
+ (result.refs ??= []).push(r);
7651
+ }
7409
7652
  } else {
7410
7653
  return false;
7411
7654
  }
@@ -7445,9 +7688,11 @@ var dumpVerdict = function(v) {
7445
7688
  if (v.acceptance) {
7446
7689
  out += dumpAcceptance(v.acceptance, " ") + "\n";
7447
7690
  }
7448
- if (v.source && (v.source.doc || v.source.clause)) {
7449
- out += ' source { doc "' + escapeString(v.source.doc) + '" clause "' + escapeString(v.source.clause) + '"' + (v.source.fragment ? ' fragment "' + escapeString(v.source.fragment) + '"' : "") + " }\n";
7691
+ const verdictSources = v.sourceRefs && v.sourceRefs.length > 0 ? v.sourceRefs : v.source && (v.source.doc || v.source.clause) ? [v.source] : [];
7692
+ for (const s of verdictSources) {
7693
+ out += dumpSourceRefAsRef(s, " ", escapeString);
7450
7694
  }
7695
+ out += dumpRefs(v.refs, " ", escapeString);
7451
7696
  out += "}\n";
7452
7697
  return out;
7453
7698
  };
@@ -7489,7 +7734,7 @@ function parseIdentityFields(block) {
7489
7734
  } else if (fc === "required") {
7490
7735
  field.required = stripWrapping(ft[j++]) === "true";
7491
7736
  } else {
7492
- unwrapBlock(ft[j++]);
7737
+ j = skipUnknownValue(ft, j, fc);
7493
7738
  }
7494
7739
  }
7495
7740
  }
@@ -7569,8 +7814,17 @@ function parseConstraints(block) {
7569
7814
  c.onViolation = stripWrapping(ct[j++]);
7570
7815
  } else if (cc === "source") {
7571
7816
  c.source = readSource(unwrapBlock(ct[j++]));
7817
+ } else if (cc === "ref") {
7818
+ const rr = parseRef(ct, j, stripWrapping, unwrapBlock);
7819
+ j = rr.next;
7820
+ if (rr.ref.predicate === "derives-from" && !c.source) {
7821
+ const b = refTargetToSourceRef(rr.ref.target);
7822
+ if (b) {
7823
+ c.source = b;
7824
+ }
7825
+ }
7572
7826
  } else {
7573
- unwrapBlock(ct[j++]);
7827
+ j = skipUnknownValue(ct, j, cc);
7574
7828
  }
7575
7829
  }
7576
7830
  }
@@ -7590,7 +7844,7 @@ var parseReferenceMaterial = function(id, data) {
7590
7844
  };
7591
7845
  forEachEntry(
7592
7846
  data,
7593
- (keyword, value) => {
7847
+ (keyword, value, peek) => {
7594
7848
  if (keyword === "kind") {
7595
7849
  result.kind = stripWrapping(value());
7596
7850
  } else if (keyword === "name") {
@@ -7598,7 +7852,16 @@ var parseReferenceMaterial = function(id, data) {
7598
7852
  } else if (keyword === "definition") {
7599
7853
  result.definition = unwrapped(value);
7600
7854
  } else if (keyword === "source") {
7601
- result.source = readSource(unwrapBlock(value()));
7855
+ const src = readSource(unwrapBlock(value()));
7856
+ (result.sourceRefs ??= []).push(src);
7857
+ if (!result.source) {
7858
+ result.source = src;
7859
+ }
7860
+ } else if (keyword === "ref") {
7861
+ const r = parseRefFromReaders(value, peek, stripWrapping, unwrapBlock);
7862
+ if (!foldRefIntoLegacy(result, r)) {
7863
+ (result.refs ??= []).push(r);
7864
+ }
7602
7865
  } else if (keyword === "identity_fields") {
7603
7866
  result.identityFields = parseIdentityFields(unwrapBlock(value()));
7604
7867
  } else if (keyword === "constraints") {
@@ -7615,12 +7878,6 @@ var parseReferenceMaterial = function(id, data) {
7615
7878
  return ctx;
7616
7879
  };
7617
7880
  };
7618
- function dumpSource(src, indent) {
7619
- if (!src || !src.doc && !src.clause) {
7620
- return "";
7621
- }
7622
- return indent + 'source { doc "' + escapeString(src.doc) + '" clause "' + escapeString(src.clause) + '"' + (src.fragment ? ' fragment "' + escapeString(src.fragment) + '"' : "") + " }\n";
7623
- }
7624
7881
  var dumpReferenceMaterial = function(m) {
7625
7882
  let out = "reference_material " + m.id + " {\n";
7626
7883
  if (m.kind) {
@@ -7632,7 +7889,11 @@ var dumpReferenceMaterial = function(m) {
7632
7889
  if (m.definition) {
7633
7890
  out += ' definition "' + escapeString(m.definition) + '"\n';
7634
7891
  }
7635
- out += dumpSource(m.source, " ");
7892
+ const rmSources = m.sourceRefs && m.sourceRefs.length > 0 ? m.sourceRefs : m.source ? [m.source] : [];
7893
+ for (const s of rmSources) {
7894
+ out += dumpSourceRefAsRef(s, " ", escapeString);
7895
+ }
7896
+ out += dumpRefs(m.refs, " ", escapeString);
7636
7897
  if (m.identityFields.length > 0) {
7637
7898
  out += " identity_fields {\n";
7638
7899
  for (const f of m.identityFields) {
@@ -7678,7 +7939,9 @@ var dumpReferenceMaterial = function(m) {
7678
7939
  if (c.onViolation) {
7679
7940
  out += " on_violation " + c.onViolation + "\n";
7680
7941
  }
7681
- out += dumpSource(c.source, " ");
7942
+ if (c.source && (c.source.doc || c.source.clause)) {
7943
+ out += dumpSourceRefAsRef(c.source, " ", escapeString);
7944
+ }
7682
7945
  out += " }\n";
7683
7946
  }
7684
7947
  out += " }\n";
@@ -7687,6 +7950,94 @@ var dumpReferenceMaterial = function(m) {
7687
7950
  return out;
7688
7951
  };
7689
7952
 
7953
+ // src/ser-des/config/predicate.ts
7954
+ var parsePredicate = function(id, data) {
7955
+ const result = {
7956
+ id,
7957
+ kind: "",
7958
+ description: "",
7959
+ subjectKinds: [],
7960
+ targetKinds: [],
7961
+ resolution: "",
7962
+ inverse: "",
7963
+ transitive: false,
7964
+ symmetric: false
7965
+ };
7966
+ const t = tokenizePackage(data);
7967
+ let i = 0;
7968
+ while (i < t.length) {
7969
+ const keyword = t[i++];
7970
+ if (i >= t.length) {
7971
+ throw new Error(
7972
+ `Parsing error: predicate. ID ${id}: Expecting value for ${keyword}`
7973
+ );
7974
+ }
7975
+ if (keyword === "kind") {
7976
+ const v = stripWrapping(t[i++]);
7977
+ if (v !== "citation" && v !== "semantic") {
7978
+ throw new Error(
7979
+ `Parsing error: predicate. ID ${id}: kind must be citation|semantic (got '${v}')`
7980
+ );
7981
+ }
7982
+ result.kind = v;
7983
+ } else if (keyword === "description" || keyword === "definition") {
7984
+ result.description = stripWrapping(t[i++]);
7985
+ } else if (keyword === "subject_kinds") {
7986
+ result.subjectKinds = tokenizePackage(unwrapBlock(t[i++])).map(
7987
+ stripWrapping
7988
+ );
7989
+ } else if (keyword === "target_kinds") {
7990
+ result.targetKinds = tokenizePackage(unwrapBlock(t[i++])).map(
7991
+ stripWrapping
7992
+ );
7993
+ } else if (keyword === "resolution") {
7994
+ result.resolution = stripWrapping(t[i++]);
7995
+ } else if (keyword === "inverse") {
7996
+ result.inverse = stripWrapping(t[i++]);
7997
+ } else if (keyword === "transitive") {
7998
+ result.transitive = stripWrapping(t[i++]) === "true";
7999
+ } else if (keyword === "symmetric") {
8000
+ result.symmetric = stripWrapping(t[i++]) === "true";
8001
+ } else {
8002
+ i++;
8003
+ }
8004
+ }
8005
+ return (ctx) => {
8006
+ ctx.predicates ??= {};
8007
+ ctx.predicates[id] = result;
8008
+ return ctx;
8009
+ };
8010
+ };
8011
+ var dumpPredicate = function(p) {
8012
+ let out = "predicate " + p.id + " {\n";
8013
+ if (p.kind) {
8014
+ out += " kind " + p.kind + "\n";
8015
+ }
8016
+ if (p.description) {
8017
+ out += ' description "' + escapeString(p.description) + '"\n';
8018
+ }
8019
+ if (p.subjectKinds.length > 0) {
8020
+ out += " subject_kinds { " + p.subjectKinds.join(" ") + " }\n";
8021
+ }
8022
+ if (p.targetKinds.length > 0) {
8023
+ out += " target_kinds { " + p.targetKinds.join(" ") + " }\n";
8024
+ }
8025
+ if (p.resolution) {
8026
+ out += " resolution " + p.resolution + "\n";
8027
+ }
8028
+ if (p.inverse) {
8029
+ out += " inverse " + p.inverse + "\n";
8030
+ }
8031
+ if (p.transitive) {
8032
+ out += " transitive true\n";
8033
+ }
8034
+ if (p.symmetric) {
8035
+ out += " symmetric true\n";
8036
+ }
8037
+ out += "}\n";
8038
+ return out;
8039
+ };
8040
+
7690
8041
  // src/ser-des/config/constraint.ts
7691
8042
  function readValue2(raw) {
7692
8043
  if (raw.length >= 2 && raw.charAt(0) === '"' && raw.charAt(raw.length - 1) === '"') {
@@ -7725,6 +8076,12 @@ var parseConstraint = function(id, data) {
7725
8076
  result.onViolation = stripWrapping(t[i++]);
7726
8077
  } else if (keyword === "source") {
7727
8078
  result.source = readSource(unwrapBlock(t[i++]));
8079
+ } else if (keyword === "ref") {
8080
+ const rr = parseRef(t, i, stripWrapping, unwrapBlock);
8081
+ if (!foldRefIntoLegacy(result, rr.ref)) {
8082
+ (result.refs ??= []).push(rr.ref);
8083
+ }
8084
+ i = rr.next;
7728
8085
  } else {
7729
8086
  i++;
7730
8087
  }
@@ -7923,11 +8280,20 @@ var parseTestPointSet = function(id, data) {
7923
8280
  };
7924
8281
  forEachEntry(
7925
8282
  data,
7926
- (keyword, value) => {
8283
+ (keyword, value, peek) => {
7927
8284
  if (keyword === "description") {
7928
8285
  result.description = unwrapped(value);
7929
8286
  } else if (keyword === "source") {
7930
- result.source = readSource(unwrapBlock(value()));
8287
+ const src = readSource(unwrapBlock(value()));
8288
+ (result.sourceRefs ??= []).push(src);
8289
+ if (!result.source) {
8290
+ result.source = src;
8291
+ }
8292
+ } else if (keyword === "ref") {
8293
+ const r = parseRefFromReaders(value, peek, stripWrapping, unwrapBlock);
8294
+ if (!foldRefIntoLegacy(result, r)) {
8295
+ (result.refs ??= []).push(r);
8296
+ }
7931
8297
  } else if (keyword === "cardinality") {
7932
8298
  result.cardinality = parseCardinality(unwrapBlock(value()));
7933
8299
  } else if (keyword === "repetitions_per_point") {
@@ -7951,9 +8317,11 @@ var dumpTestPointSet = function(s) {
7951
8317
  if (s.description) {
7952
8318
  out += ' description "' + escapeString(s.description) + '"\n';
7953
8319
  }
7954
- if (s.source && (s.source.doc || s.source.clause)) {
7955
- out += ' source { doc "' + escapeString(s.source.doc) + '" clause "' + escapeString(s.source.clause) + '"' + (s.source.fragment ? ' fragment "' + escapeString(s.source.fragment) + '"' : "") + " }\n";
8320
+ const tpsSources = s.sourceRefs && s.sourceRefs.length > 0 ? s.sourceRefs : s.source && (s.source.doc || s.source.clause) ? [s.source] : [];
8321
+ for (const src of tpsSources) {
8322
+ out += dumpSourceRefAsRef(src, " ", escapeString);
7956
8323
  }
8324
+ out += dumpRefs(s.refs, " ", escapeString);
7957
8325
  const ckeys = Object.keys(s.cardinality);
7958
8326
  if (ckeys.length > 0) {
7959
8327
  out += " cardinality {\n";
@@ -8021,7 +8389,7 @@ function readAccepts(block) {
8021
8389
  } else if (cmd === "source_discrepancy") {
8022
8390
  accepts.sourceDiscrepancy = parseSourceDiscrepancy(unwrapBlock(t[i++]));
8023
8391
  } else {
8024
- unwrapBlock(t[i++]);
8392
+ i = skipUnknownValue(t, i, cmd);
8025
8393
  }
8026
8394
  }
8027
8395
  return accepts;
@@ -8061,7 +8429,7 @@ function readLimit(block) {
8061
8429
  } else if (cmd === "source_discrepancy") {
8062
8430
  limit.sourceDiscrepancy = parseSourceDiscrepancy(unwrapBlock(t[i++]));
8063
8431
  } else {
8064
- unwrapBlock(t[i++]);
8432
+ i = skipUnknownValue(t, i, cmd);
8065
8433
  }
8066
8434
  }
8067
8435
  return limit;
@@ -8253,8 +8621,14 @@ var parseRequirement = function(id, data) {
8253
8621
  result.source = src;
8254
8622
  }
8255
8623
  (result.sourceRefs ??= []).push(src);
8624
+ } else if (cmd === "ref") {
8625
+ const r = parseRef(t, i, stripWrapping, unwrapBlock);
8626
+ if (!foldRefIntoLegacy(result, r.ref)) {
8627
+ (result.refs ??= []).push(r.ref);
8628
+ }
8629
+ i = r.next;
8256
8630
  } else {
8257
- unwrapBlock(t[i++]);
8631
+ i = skipUnknownValue(t, i, cmd);
8258
8632
  }
8259
8633
  }
8260
8634
  return (ctx) => {
@@ -8392,7 +8766,10 @@ var dumpRequirement = function(r) {
8392
8766
  out += dumpSourceDiscrepancy(r.sourceDiscrepancy, " ") + "\n";
8393
8767
  }
8394
8768
  for (const src of r.sourceRefs ?? (r.source && (r.source.doc || r.source.clause) ? [r.source] : [])) {
8395
- out += ' source { doc "' + escapeString(src.doc) + '" clause "' + escapeString(src.clause) + '"' + (src.fragment ? ' fragment "' + escapeString(src.fragment) + '"' : "") + " }\n";
8769
+ out += dumpSourceRefAsRef(src, " ", escapeString);
8770
+ }
8771
+ for (const ref of r.refs ?? []) {
8772
+ out += " ref " + ref.predicate + ' "' + escapeString(ref.target) + '"' + (ref.note ? ' { note "' + escapeString(ref.note) + '" }' : "") + "\n";
8396
8773
  }
8397
8774
  out += "}\n";
8398
8775
  return out;
@@ -8430,7 +8807,7 @@ var parseRequirementClass = function(id, data) {
8430
8807
  } else if (cmd === "reference") {
8431
8808
  result.referenceIds = readIdList2(t[i++]);
8432
8809
  } else {
8433
- unwrapBlock(t[i++]);
8810
+ i = skipUnknownValue(t, i, cmd);
8434
8811
  }
8435
8812
  }
8436
8813
  return (ctx) => {
@@ -8571,6 +8948,12 @@ var parsePackage = function(data) {
8571
8948
  manifest.product = stripWrapping(t[i++]);
8572
8949
  } else if (cmd === "maps_to" || cmd === "mapsTo") {
8573
8950
  manifest.mapsTo = readList(t[i++]);
8951
+ } else if (cmd === "ref") {
8952
+ const r = parseRef(t, i, stripWrapping, unwrapBlock);
8953
+ if (!foldRefIntoLegacy(manifest, r.ref)) {
8954
+ (manifest.refs ??= []).push(r.ref);
8955
+ }
8956
+ i = r.next;
8574
8957
  } else if (cmd === "scheme_type" || cmd === "schemeType") {
8575
8958
  manifest.schemeType = stripWrapping(t[i++]);
8576
8959
  } else if (cmd === "provides") {
@@ -8636,7 +9019,7 @@ var parsePackage = function(data) {
8636
9019
  }
8637
9020
  manifest.source = src;
8638
9021
  } else {
8639
- unwrapBlock(t[i++]);
9022
+ i = skipUnknownValue(t, i, cmd);
8640
9023
  }
8641
9024
  }
8642
9025
  return (ctx) => {
@@ -8687,7 +9070,7 @@ var parseConformanceClass = function(id, data) {
8687
9070
  } else if (cmd === "reference") {
8688
9071
  result.referenceIds = tokenize(stripWrapping(t[i++])).map(stripWrapping);
8689
9072
  } else {
8690
- unwrapBlock(t[i++]);
9073
+ i = skipUnknownValue(t, i, cmd);
8691
9074
  }
8692
9075
  }
8693
9076
  return (ctx) => {
@@ -9113,7 +9496,7 @@ function dumpComposedOf(decl, indent) {
9113
9496
  }
9114
9497
 
9115
9498
  // src/ser-des/config/subject.ts
9116
- function dumpSource2(keyword, src, indent) {
9499
+ function dumpSource(keyword, src, indent) {
9117
9500
  if (!src || !src.doc && !src.clause) {
9118
9501
  return "";
9119
9502
  }
@@ -9149,7 +9532,11 @@ var parseInstrument = function(id, data) {
9149
9532
  referenceIds: [],
9150
9533
  measurand: null,
9151
9534
  components: [],
9152
- structure: []
9535
+ structure: [],
9536
+ // Initialized so the ref fold (docs/primmel/18 §18.4) mirrors the
9537
+ // first derives-from block here — the fold only mirrors slots the
9538
+ // object already carries.
9539
+ source: null
9153
9540
  };
9154
9541
  const t = tokenizePackage(data);
9155
9542
  let i = 0;
@@ -9177,7 +9564,11 @@ var parseInstrument = function(id, data) {
9177
9564
  } else if (cmd === "note") {
9178
9565
  result.note = stripWrapping(t[i++]);
9179
9566
  } else if (cmd === "source") {
9180
- result.source = readSource(unwrapBlock(t[i++]));
9567
+ const src = readSource(unwrapBlock(t[i++]));
9568
+ (result.sourceRefs ??= []).push(src);
9569
+ if (!result.source) {
9570
+ result.source = src;
9571
+ }
9181
9572
  } else if (cmd === "variant") {
9182
9573
  const variantId = stripWrapping(t[i++]);
9183
9574
  const vblock = i < t.length ? unwrapBlock(t[i++]) : "";
@@ -9227,6 +9618,15 @@ var parseInstrument = function(id, data) {
9227
9618
  result.familyNote = stripWrapping(ft[j++]);
9228
9619
  } else if (fc === "source") {
9229
9620
  result.familySource = readSource(unwrapBlock(ft[j++]));
9621
+ } else if (fc === "ref") {
9622
+ const rr = parseRef(ft, j, stripWrapping, unwrapBlock);
9623
+ j = rr.next;
9624
+ if (rr.ref.predicate === "derives-from") {
9625
+ const b = refTargetToSourceRef(rr.ref.target);
9626
+ if (b && !result.familySource) {
9627
+ result.familySource = b;
9628
+ }
9629
+ }
9230
9630
  } else {
9231
9631
  unwrapBlock(ft[j++]);
9232
9632
  }
@@ -9252,8 +9652,14 @@ var parseInstrument = function(id, data) {
9252
9652
  result.modelGroup = parseModelGroup(unwrapBlock(t[i++]));
9253
9653
  } else if (cmd === "reference") {
9254
9654
  result.referenceIds = readReference(t[i++]);
9655
+ } else if (cmd === "ref") {
9656
+ const rr = parseRef(t, i, stripWrapping, unwrapBlock);
9657
+ if (!foldRefIntoLegacy(result, rr.ref)) {
9658
+ (result.refs ??= []).push(rr.ref);
9659
+ }
9660
+ i = rr.next;
9255
9661
  } else {
9256
- unwrapBlock(t[i++]);
9662
+ i = skipUnknownValue(t, i, cmd);
9257
9663
  }
9258
9664
  }
9259
9665
  return (ctx) => {
@@ -9300,7 +9706,7 @@ function parseMeasurand(block) {
9300
9706
  } else if (cmd === "source") {
9301
9707
  m.source = readSource(unwrapBlock(t[i++]));
9302
9708
  } else {
9303
- unwrapBlock(t[i++]);
9709
+ i = skipUnknownValue(t, i, cmd);
9304
9710
  }
9305
9711
  }
9306
9712
  return m;
@@ -9326,7 +9732,7 @@ function parseComponent2(id, block) {
9326
9732
  } else if (cmd === "source") {
9327
9733
  c.source = readSource(unwrapBlock(t[i++]));
9328
9734
  } else {
9329
- unwrapBlock(t[i++]);
9735
+ i = skipUnknownValue(t, i, cmd);
9330
9736
  }
9331
9737
  }
9332
9738
  return c;
@@ -9370,7 +9776,7 @@ function parseStructure(id, block) {
9370
9776
  } else if (cmd === "source") {
9371
9777
  s.source = readSource(unwrapBlock(t[i++]));
9372
9778
  } else {
9373
- unwrapBlock(t[i++]);
9779
+ i = skipUnknownValue(t, i, cmd);
9374
9780
  }
9375
9781
  }
9376
9782
  return s;
@@ -9414,7 +9820,7 @@ function parseDimension(id, block) {
9414
9820
  } else if (cmd === "values") {
9415
9821
  dim.values = parseDimensionValues(unwrapBlock(t[i++]));
9416
9822
  } else {
9417
- unwrapBlock(t[i++]);
9823
+ i = skipUnknownValue(t, i, cmd);
9418
9824
  }
9419
9825
  }
9420
9826
  return dim;
@@ -9521,10 +9927,19 @@ function parseModelGroup(block) {
9521
9927
  mg.note = stripWrapping(t[i++]);
9522
9928
  } else if (cmd === "source") {
9523
9929
  mg.sources.push(readSource(unwrapBlock(t[i++])));
9930
+ } else if (cmd === "ref") {
9931
+ const rr = parseRef(t, i, stripWrapping, unwrapBlock);
9932
+ i = rr.next;
9933
+ if (rr.ref.predicate === "derives-from") {
9934
+ const b = refTargetToSourceRef(rr.ref.target);
9935
+ if (b) {
9936
+ mg.sources.push(b);
9937
+ }
9938
+ }
9524
9939
  } else if (cmd === "sample_selection") {
9525
9940
  mg.sampleSelection.push(readSource(unwrapBlock(t[i++])));
9526
9941
  } else {
9527
- unwrapBlock(t[i++]);
9942
+ i = skipUnknownValue(t, i, cmd);
9528
9943
  }
9529
9944
  }
9530
9945
  return mg;
@@ -9559,7 +9974,7 @@ var dumpInstrument = function(inst) {
9559
9974
  }
9560
9975
  out += " }\n";
9561
9976
  }
9562
- out += dumpSource2("source", m.source, " ");
9977
+ out += dumpSource("source", m.source, " ");
9563
9978
  out += " }\n";
9564
9979
  }
9565
9980
  for (const c of inst.components ?? []) {
@@ -9599,7 +10014,7 @@ var dumpInstrument = function(inst) {
9599
10014
  if (s.note) {
9600
10015
  out += ' note "' + escapeString(s.note) + '"\n';
9601
10016
  }
9602
- out += dumpSource2("source", s.source, " ");
10017
+ out += dumpSource("source", s.source, " ");
9603
10018
  out += " }\n";
9604
10019
  }
9605
10020
  if (inst.definition) {
@@ -9639,7 +10054,7 @@ var dumpInstrument = function(inst) {
9639
10054
  if (d.description) {
9640
10055
  out += ' description "' + escapeString(d.description) + '"\n';
9641
10056
  }
9642
- out += dumpSource2("reference", d.source, " ");
10057
+ out += dumpSource("reference", d.source, " ");
9643
10058
  if (d.values.length > 0) {
9644
10059
  out += " values {\n";
9645
10060
  for (const v of d.values) {
@@ -9693,7 +10108,9 @@ var dumpInstrument = function(inst) {
9693
10108
  if (inst.familyNote) {
9694
10109
  out += ' note "' + escapeString(inst.familyNote) + '"\n';
9695
10110
  }
9696
- out += dumpSource2("source", inst.familySource ?? null, " ");
10111
+ if (inst.familySource && (inst.familySource.doc || inst.familySource.clause)) {
10112
+ out += dumpSourceRefAsRef(inst.familySource, " ", escapeString);
10113
+ }
9697
10114
  out += " }\n";
9698
10115
  }
9699
10116
  if (inst.familyCriteria.length > 0) {
@@ -9731,14 +10148,18 @@ var dumpInstrument = function(inst) {
9731
10148
  " "
9732
10149
  );
9733
10150
  for (const s of inst.modelGroup.sources ?? []) {
9734
- out += dumpSource2("source", s, " ");
10151
+ out += dumpSourceRefAsRef(s, " ", escapeString);
9735
10152
  }
9736
10153
  for (const s of inst.modelGroup.sampleSelection ?? []) {
9737
- out += dumpSource2("sample_selection", s, " ");
10154
+ out += dumpSource("sample_selection", s, " ");
9738
10155
  }
9739
10156
  out += " }\n";
9740
10157
  }
9741
- out += dumpSource2("source", inst.source ?? null, " ");
10158
+ const instSources = inst.sourceRefs && inst.sourceRefs.length > 0 ? inst.sourceRefs : inst.source ? [inst.source] : [];
10159
+ for (const s of instSources) {
10160
+ out += dumpSourceRefAsRef(s, " ", escapeString);
10161
+ }
10162
+ out += dumpRefs(inst.refs, " ", escapeString);
9742
10163
  out += dumpIdList("reference", inst.referenceIds, " ");
9743
10164
  out += "}\n";
9744
10165
  return out;
@@ -9776,7 +10197,11 @@ var parseAttributeDefinition = function(id, data) {
9776
10197
  } else if (cmd === "definition") {
9777
10198
  result.definition = stripWrapping(t[i++]);
9778
10199
  } else if (cmd === "source" || cmd === "reference") {
9779
- result.source = readSource(unwrapBlock(t[i++]));
10200
+ const src = readSource(unwrapBlock(t[i++]));
10201
+ (result.sourceRefs ??= []).push(src);
10202
+ if (!result.source) {
10203
+ result.source = src;
10204
+ }
9780
10205
  } else if (cmd === "quantity_kind") {
9781
10206
  result.quantityKind = stripWrapping(t[i++]);
9782
10207
  } else if (cmd === "unit") {
@@ -9801,8 +10226,14 @@ var parseAttributeDefinition = function(id, data) {
9801
10226
  result.irdi = stripWrapping(t[i++]);
9802
10227
  } else if (cmd === "derived") {
9803
10228
  result.derived = stripWrapping(t[i++]);
10229
+ } else if (cmd === "ref") {
10230
+ const rr = parseRef(t, i, stripWrapping, unwrapBlock);
10231
+ if (!foldRefIntoLegacy(result, rr.ref)) {
10232
+ (result.refs ??= []).push(rr.ref);
10233
+ }
10234
+ i = rr.next;
9804
10235
  } else {
9805
- unwrapBlock(t[i++]);
10236
+ i = skipUnknownValue(t, i, cmd);
9806
10237
  }
9807
10238
  }
9808
10239
  return (ctx) => {
@@ -9821,7 +10252,11 @@ var dumpAttributeDefinition = function(a) {
9821
10252
  if (a.definition) {
9822
10253
  out += ' definition "' + escapeString(a.definition) + '"\n';
9823
10254
  }
9824
- out += dumpSource2("source", a.source, " ");
10255
+ const attrSources = a.sourceRefs && a.sourceRefs.length > 0 ? a.sourceRefs : a.source ? [a.source] : [];
10256
+ for (const s of attrSources) {
10257
+ out += dumpSourceRefAsRef(s, " ", escapeString);
10258
+ }
10259
+ out += dumpRefs(a.refs, " ", escapeString);
9825
10260
  if (a.quantityKind) {
9826
10261
  out += " quantity_kind " + a.quantityKind + "\n";
9827
10262
  }
@@ -9893,8 +10328,14 @@ var parseCapability = function(id, data) {
9893
10328
  result.verifiedByTests = readReference(t[i++]);
9894
10329
  } else if (cmd === "reference") {
9895
10330
  result.referenceIds = readReference(t[i++]);
10331
+ } else if (cmd === "ref") {
10332
+ const rr = parseRef(t, i, stripWrapping, unwrapBlock);
10333
+ if (!foldRefIntoLegacy(result, rr.ref)) {
10334
+ (result.refs ??= []).push(rr.ref);
10335
+ }
10336
+ i = rr.next;
9896
10337
  } else {
9897
- unwrapBlock(t[i++]);
10338
+ i = skipUnknownValue(t, i, cmd);
9898
10339
  }
9899
10340
  }
9900
10341
  return (ctx) => {
@@ -9919,6 +10360,7 @@ var dumpCapability = function(c) {
9919
10360
  out += dumpIdList("satisfies_requirements", c.satisfiesRequirements, " ");
9920
10361
  out += dumpIdList("verified_by_tests", c.verifiedByTests, " ");
9921
10362
  out += dumpIdList("reference", c.referenceIds, " ");
10363
+ out += dumpRefs(c.refs, " ", escapeString);
9922
10364
  out += "}\n";
9923
10365
  return out;
9924
10366
  };
@@ -9946,11 +10388,21 @@ var parseBehavior = function(id, data) {
9946
10388
  } else if (cmd === "response") {
9947
10389
  result.response = stripWrapping(t[i++]);
9948
10390
  } else if (cmd === "source" || cmd === "reference") {
9949
- result.source = readSource(unwrapBlock(t[i++]));
10391
+ const src = readSource(unwrapBlock(t[i++]));
10392
+ (result.sourceRefs ??= []).push(src);
10393
+ if (!result.source) {
10394
+ result.source = src;
10395
+ }
9950
10396
  } else if (cmd === "verified_by" || cmd === "verified_by_tests") {
9951
10397
  result.verifiedBy = readReference(t[i++]);
10398
+ } else if (cmd === "ref") {
10399
+ const rr = parseRef(t, i, stripWrapping, unwrapBlock);
10400
+ if (!foldRefIntoLegacy(result, rr.ref)) {
10401
+ (result.refs ??= []).push(rr.ref);
10402
+ }
10403
+ i = rr.next;
9952
10404
  } else {
9953
- unwrapBlock(t[i++]);
10405
+ i = skipUnknownValue(t, i, cmd);
9954
10406
  }
9955
10407
  }
9956
10408
  return (ctx) => {
@@ -9969,7 +10421,11 @@ var dumpBehavior = function(b) {
9969
10421
  if (b.response) {
9970
10422
  out += ' response "' + escapeString(b.response) + '"\n';
9971
10423
  }
9972
- out += dumpSource2("source", b.source, " ");
10424
+ const behaviorSources = b.sourceRefs && b.sourceRefs.length > 0 ? b.sourceRefs : b.source ? [b.source] : [];
10425
+ for (const s of behaviorSources) {
10426
+ out += dumpSourceRefAsRef(s, " ", escapeString);
10427
+ }
10428
+ out += dumpRefs(b.refs, " ", escapeString);
9973
10429
  out += dumpIdList("verified_by", b.verifiedBy, " ");
9974
10430
  out += "}\n";
9975
10431
  return out;
@@ -10004,10 +10460,28 @@ var parseConditionSet = function(id, data) {
10004
10460
  if (!result.source) {
10005
10461
  result.source = src;
10006
10462
  }
10463
+ } else if (cmd === "ref") {
10464
+ const rr = parseRef(t, i, stripWrapping, unwrapBlock);
10465
+ i = rr.next;
10466
+ if (rr.ref.predicate === "derives-from") {
10467
+ const b = refTargetToSourceRef(rr.ref.target);
10468
+ if (b) {
10469
+ result.sources.push(b);
10470
+ if (!result.source) {
10471
+ result.source = b;
10472
+ }
10473
+ } else {
10474
+ (result.refs ??= []).push(rr.ref);
10475
+ }
10476
+ } else if (rr.ref.predicate === "cites") {
10477
+ result.referenceIds.push(rr.ref.target);
10478
+ } else {
10479
+ (result.refs ??= []).push(rr.ref);
10480
+ }
10007
10481
  } else if (cmd === "reference") {
10008
10482
  result.referenceIds = readReference(t[i++]);
10009
10483
  } else {
10010
- unwrapBlock(t[i++]);
10484
+ i = skipUnknownValue(t, i, cmd);
10011
10485
  }
10012
10486
  }
10013
10487
  return (ctx) => {
@@ -10086,9 +10560,10 @@ var dumpConditionSet = function(cs) {
10086
10560
  }
10087
10561
  const sources = cs.sources && cs.sources.length > 0 ? cs.sources : cs.source ? [cs.source] : [];
10088
10562
  for (const s of sources) {
10089
- out += dumpSource2("source", s, " ");
10563
+ out += dumpSourceRefAsRef(s, " ", escapeString);
10090
10564
  }
10091
10565
  out += dumpIdList("reference", cs.referenceIds, " ");
10566
+ out += dumpRefs(cs.refs, " ", escapeString);
10092
10567
  out += "}\n";
10093
10568
  return out;
10094
10569
  };
@@ -10217,7 +10692,7 @@ function readCharacteristicBlock(block) {
10217
10692
  } else if (cmd === "source" || cmd === "reference") {
10218
10693
  c.source = readSource(unwrapBlock(t[i++]));
10219
10694
  } else {
10220
- unwrapBlock(t[i++]);
10695
+ i = skipUnknownValue(t, i, cmd);
10221
10696
  }
10222
10697
  }
10223
10698
  return c;
@@ -10481,7 +10956,7 @@ var parseSubject = function(id, data) {
10481
10956
  } else if (cmd === "reference") {
10482
10957
  result.referenceIds = readReference(t[i++]);
10483
10958
  } else {
10484
- unwrapBlock(t[i++]);
10959
+ i = skipUnknownValue(t, i, cmd);
10485
10960
  }
10486
10961
  }
10487
10962
  return (ctx) => {
@@ -10633,7 +11108,7 @@ function dumpSubjectPromises(promises) {
10633
11108
  out += ' statement "' + escapeString(p.statement) + '"\n';
10634
11109
  }
10635
11110
  out += dumpIdList("verified_by", p.verifiedBy, " ");
10636
- out += dumpSource2("source", p.source ?? null, " ");
11111
+ out += dumpSource("source", p.source ?? null, " ");
10637
11112
  out += " }\n";
10638
11113
  }
10639
11114
  out += " }\n";
@@ -10665,7 +11140,7 @@ function dumpSubjectCharacteristics(map) {
10665
11140
  if (c.unit) {
10666
11141
  out += ' unit "' + escapeString(c.unit) + '"\n';
10667
11142
  }
10668
- out += dumpSource2("source", c.source ?? null, " ");
11143
+ out += dumpSource("source", c.source ?? null, " ");
10669
11144
  out += " }\n";
10670
11145
  continue;
10671
11146
  }
@@ -10937,14 +11412,6 @@ var instanceConstruct = {
10937
11412
  };
10938
11413
 
10939
11414
  // src/ser-des/config/artifact.ts
10940
- function dumpSource3(keyword, src, indent) {
10941
- if (!src || !src.doc && !src.clause) {
10942
- return "";
10943
- }
10944
- const frag = src.fragment ? ` fragment "${escapeString(src.fragment)}"` : "";
10945
- return `${indent}${keyword} { doc "${escapeString(src.doc)}" clause "${escapeString(src.clause)}"${frag} }
10946
- `;
10947
- }
10948
11415
  function readIdList4(block) {
10949
11416
  return tokenize(stripWrapping(block)).map(stripColon).map(stripWrapping).filter((s) => s.length > 0);
10950
11417
  }
@@ -11038,7 +11505,7 @@ function parseContentContract(block) {
11038
11505
  } else if (cmd === "media") {
11039
11506
  contract.media = readContractMedia(unwrapBlock(t[i++]));
11040
11507
  } else {
11041
- unwrapBlock(t[i++]);
11508
+ i = skipUnknownValue(t, i, cmd);
11042
11509
  }
11043
11510
  }
11044
11511
  return contract;
@@ -11079,11 +11546,21 @@ var parseArtifactDefinition = function(id, data) {
11079
11546
  } else if (cmd === "retention") {
11080
11547
  result.retention = stripWrapping(t[i++]);
11081
11548
  } else if (cmd === "source") {
11082
- result.source = readSource(unwrapBlock(t[i++]));
11549
+ const src = readSource(unwrapBlock(t[i++]));
11550
+ (result.sourceRefs ??= []).push(src);
11551
+ if (!result.source) {
11552
+ result.source = src;
11553
+ }
11083
11554
  } else if (cmd === "reference") {
11084
11555
  result.referenceIds = readReference3(t[i++]);
11556
+ } else if (cmd === "ref") {
11557
+ const rr = parseRef(t, i, stripWrapping, unwrapBlock);
11558
+ if (!foldRefIntoLegacy(result, rr.ref)) {
11559
+ (result.refs ??= []).push(rr.ref);
11560
+ }
11561
+ i = rr.next;
11085
11562
  } else {
11086
- unwrapBlock(t[i++]);
11563
+ i = skipUnknownValue(t, i, cmd);
11087
11564
  }
11088
11565
  }
11089
11566
  return (ctx) => {
@@ -11144,7 +11621,11 @@ var dumpArtifactDefinition = function(d) {
11144
11621
  if (d.retention) {
11145
11622
  out += ' retention "' + escapeString(d.retention) + '"\n';
11146
11623
  }
11147
- out += dumpSource3("source", d.source, " ");
11624
+ const artifactSources = d.sourceRefs && d.sourceRefs.length > 0 ? d.sourceRefs : d.source ? [d.source] : [];
11625
+ for (const s of artifactSources) {
11626
+ out += dumpSourceRefAsRef(s, " ", escapeString);
11627
+ }
11628
+ out += dumpRefs(d.refs, " ", escapeString);
11148
11629
  out += dumpIdList2("reference", d.referenceIds, " ");
11149
11630
  out += "}\n";
11150
11631
  return out;
@@ -11179,7 +11660,7 @@ var parseArtifactInstance = function(id, data) {
11179
11660
  } else if (cmd === "reference") {
11180
11661
  result.referenceIds = readReference3(t[i++]);
11181
11662
  } else {
11182
- unwrapBlock(t[i++]);
11663
+ i = skipUnknownValue(t, i, cmd);
11183
11664
  }
11184
11665
  }
11185
11666
  return (ctx) => {
@@ -11730,6 +12211,12 @@ var parseTestSequence = function(id, data) {
11730
12211
  sequence.description = stripWrapping(t[i++]);
11731
12212
  } else if (command === "sample_applicability") {
11732
12213
  sequence.sampleApplicability = stripWrapping(t[i++]);
12214
+ } else if (command === "ref") {
12215
+ const rr = parseRef(t, i, stripWrapping, unwrapBlock);
12216
+ if (!foldRefIntoLegacy(sequence, rr.ref)) {
12217
+ sequence.refs = [...sequence.refs ?? [], rr.ref];
12218
+ }
12219
+ i = rr.next;
11733
12220
  } else if (command === "source") {
11734
12221
  sequence.sourceRefs.push(readSource(unwrapBlock(t[i++])));
11735
12222
  } else if (command === "step") {
@@ -11785,8 +12272,11 @@ var dumpTestSequence = function(seq) {
11785
12272
  if (seq.sampleApplicability !== "") {
11786
12273
  out += " sample_applicability " + dumpBareSafe(seq.sampleApplicability) + "\n";
11787
12274
  }
12275
+ for (const r of seq.refs ?? []) {
12276
+ out += " ref " + r.predicate + ' "' + escapeString(r.target) + '"' + (r.note ? ' { note "' + escapeString(r.note) + '" }' : "") + "\n";
12277
+ }
11788
12278
  for (const src of seq.sourceRefs) {
11789
- out += ' source { doc "' + escapeString(src.doc) + '" clause "' + escapeString(src.clause) + '"' + (src.fragment ? ' fragment "' + escapeString(src.fragment) + '"' : "") + " }\n";
12279
+ out += dumpSourceRefAsRef(src, " ", escapeString);
11790
12280
  }
11791
12281
  out += "}\n";
11792
12282
  return out;
@@ -11810,13 +12300,18 @@ var parseFormulasUsed = function(id, data) {
11810
12300
  };
11811
12301
  forEachEntry(
11812
12302
  data,
11813
- (command, value) => {
12303
+ (command, value, peek) => {
11814
12304
  if (command === "name") {
11815
12305
  trace.name = stripWrapping(value());
11816
12306
  } else if (command === "description") {
11817
12307
  trace.description = stripWrapping(value());
11818
12308
  } else if (command === "formulas") {
11819
12309
  trace.formulas.push(...readEntryTokens(value()));
12310
+ } else if (command === "ref") {
12311
+ const r = parseRefFromReaders(value, peek, stripWrapping, unwrapBlock);
12312
+ if (!foldRefIntoLegacy(trace, r)) {
12313
+ (trace.refs ??= []).push(r);
12314
+ }
11820
12315
  } else if (command === "source") {
11821
12316
  trace.sourceRefs.push(readSource(unwrapBlock(value())));
11822
12317
  } else {
@@ -11842,8 +12337,11 @@ var dumpFormulasUsed = function(fu) {
11842
12337
  if (fu.formulas.length > 0) {
11843
12338
  out += " formulas { " + fu.formulas.map(dumpBareSafe).join(" ") + " }\n";
11844
12339
  }
12340
+ for (const r of fu.refs ?? []) {
12341
+ out += " ref " + r.predicate + ' "' + escapeString(r.target) + '"' + (r.note ? ' { note "' + escapeString(r.note) + '" }' : "") + "\n";
12342
+ }
11845
12343
  for (const src of fu.sourceRefs) {
11846
- out += ' source { doc "' + escapeString(src.doc) + '" clause "' + escapeString(src.clause) + '"' + (src.fragment ? ' fragment "' + escapeString(src.fragment) + '"' : "") + " }\n";
12344
+ out += dumpSourceRefAsRef(src, " ", escapeString);
11847
12345
  }
11848
12346
  out += "}\n";
11849
12347
  return out;
@@ -12438,6 +12936,14 @@ var CONSTRUCTS = [
12438
12936
  parse: parseCompetenceKind,
12439
12937
  dump: dumpCompetenceKind
12440
12938
  }),
12939
+ // The relation registry (docs/primmel/18): declared ref predicates.
12940
+ defineConstruct({
12941
+ keyword: "predicate",
12942
+ field: "predicates",
12943
+ takesID: true,
12944
+ parse: parsePredicate,
12945
+ dump: dumpPredicate
12946
+ }),
12441
12947
  // Primmel v3 domain constraints (TODO.roadmap/51 — BUG.R60-SSOT gap 7)
12442
12948
  defineConstruct({
12443
12949
  keyword: "constraint",
@@ -15297,6 +15803,19 @@ var CHECK_RULES = [
15297
15803
  "error",
15298
15804
  "normal",
15299
15805
  "TODO.integration/14, the composed_of construct (TODO.v3/03 Phase 2)"
15806
+ ),
15807
+ // ── the relation registry (docs/primmel/18 §18.6) ──────────────────
15808
+ // C103: every ref predicate resolves against the composed registry —
15809
+ // a typo is an error, not a silent new predicate. The rule only fires
15810
+ // when the package set declares a registry: the predicate vocabulary
15811
+ // is data (the metamodel layer's predicates.prl), never grammar.
15812
+ R(
15813
+ "C103",
15814
+ "declared-predicate",
15815
+ "base",
15816
+ "error",
15817
+ "normal",
15818
+ "docs/primmel/18 \xA718.6 (the unified reference/relation construct)"
15300
15819
  )
15301
15820
  ];
15302
15821
  var byId = new Map(CHECK_RULES.map((r) => [r.id, r]));
@@ -16233,6 +16752,7 @@ function checkPackage(dir, options = {}) {
16233
16752
  }
16234
16753
  issues.push(...checkEditionLifecycle(dir, standard));
16235
16754
  issues.push(...checkSpellingCodes(standard));
16755
+ issues.push(...checkDeclaredPredicates(standard));
16236
16756
  const reqIds = new Set(
16237
16757
  (standard.requirements ?? []).map((r) => r.id)
16238
16758
  );
@@ -19692,6 +20212,81 @@ function checkSpellingCodes(standard) {
19692
20212
  }
19693
20213
  return issues;
19694
20214
  }
20215
+ function checkDeclaredPredicates(standard) {
20216
+ const issues = [];
20217
+ const registry = new Set((standard.predicates ?? []).map((p) => p.id));
20218
+ if (registry.size === 0) {
20219
+ return issues;
20220
+ }
20221
+ const visit = (owner, refs) => {
20222
+ for (const r of refs ?? []) {
20223
+ if (!registry.has(r.predicate)) {
20224
+ issues.push({
20225
+ check: "C103",
20226
+ severity: "error",
20227
+ message: `${owner}: ref predicate "${r.predicate}" is not declared in the composed predicate registry (declared-predicate)`
20228
+ });
20229
+ }
20230
+ }
20231
+ };
20232
+ const visitFields = (owner, fields) => {
20233
+ for (const f of fields) {
20234
+ const here = `${owner} field ${f.name}`;
20235
+ visit(here, f.refs);
20236
+ if (f.fields && f.fields.length > 0) {
20237
+ visitFields(here, f.fields);
20238
+ }
20239
+ }
20240
+ };
20241
+ const m = standard.packageManifest;
20242
+ if (m) {
20243
+ visit(`package "${m.id}"`, m.refs);
20244
+ }
20245
+ for (const r of standard.requirements ?? []) {
20246
+ visit(`requirement ${r.id}`, r.refs);
20247
+ }
20248
+ for (const t of standard.conformanceTests ?? []) {
20249
+ visit(`conformance_test ${t.id}`, t.refs);
20250
+ }
20251
+ for (const f of standard.forms ?? []) {
20252
+ visit(`form ${f.id}`, f.refs);
20253
+ visitFields(`form ${f.id}`, f.fields ?? []);
20254
+ }
20255
+ for (const s of standard.subforms ?? []) {
20256
+ visitFields(`subform ${s.id}`, s.fields ?? []);
20257
+ }
20258
+ for (const c of standard.calculations ?? []) {
20259
+ visit(`calculation ${c.id}`, c.refs);
20260
+ }
20261
+ for (const s of standard.symbols ?? []) {
20262
+ visit(`symbol ${s.id}`, s.refs);
20263
+ }
20264
+ for (const t of standard.terms ?? []) {
20265
+ visit(`term ${t.id}`, t.refs);
20266
+ }
20267
+ for (const t of standard.tables ?? []) {
20268
+ visit(`table ${t.id}`, t.refs);
20269
+ }
20270
+ for (const c of standard.constraints ?? []) {
20271
+ visit(`constraint ${c.id}`, c.refs);
20272
+ }
20273
+ for (const k of standard.competenceKinds ?? []) {
20274
+ visit(`competence_kind ${k.id}`, k.refs);
20275
+ }
20276
+ for (const f of standard.formulasUsed ?? []) {
20277
+ visit(`formulas_used ${f.id}`, f.refs);
20278
+ }
20279
+ for (const s of standard.testSequences ?? []) {
20280
+ visit(`test_sequence ${s.id}`, s.refs);
20281
+ }
20282
+ for (const c of standard.conditionSets ?? []) {
20283
+ visit(`condition_set ${c.id}`, c.refs);
20284
+ }
20285
+ for (const i of standard.instruments ?? []) {
20286
+ visit(`instrument ${i.id}`, i.refs);
20287
+ }
20288
+ return issues;
20289
+ }
19695
20290
  function checkEditionLifecycle(dir, standard) {
19696
20291
  const issues = [];
19697
20292
  const err = (check, message) => issues.push({ check, severity: "error", message });