@primmel/primmel 1.20.0 → 1.21.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 (136) hide show
  1. package/dist/index.d.ts +2 -1
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +7 -3
  4. package/dist/index.js.map +1 -1
  5. package/dist/src/check-rules.d.ts +1 -1
  6. package/dist/src/check-rules.d.ts.map +1 -1
  7. package/dist/src/check-rules.js +36 -15
  8. package/dist/src/check-rules.js.map +1 -1
  9. package/dist/src/check.d.ts +4 -0
  10. package/dist/src/check.d.ts.map +1 -1
  11. package/dist/src/check.js +428 -137
  12. package/dist/src/check.js.map +1 -1
  13. package/dist/src/export/cddal.d.ts +25 -0
  14. package/dist/src/export/cddal.d.ts.map +1 -0
  15. package/dist/src/export/cddal.js +213 -0
  16. package/dist/src/export/cddal.js.map +1 -0
  17. package/dist/src/export/retrieval.d.ts +147 -6
  18. package/dist/src/export/retrieval.d.ts.map +1 -1
  19. package/dist/src/export/retrieval.js +254 -25
  20. package/dist/src/export/retrieval.js.map +1 -1
  21. package/dist/src/export/unitsdb.d.ts +19 -0
  22. package/dist/src/export/unitsdb.d.ts.map +1 -0
  23. package/dist/src/export/unitsdb.js +82 -0
  24. package/dist/src/export/unitsdb.js.map +1 -0
  25. package/dist/src/export/yaml-lite.d.ts +13 -0
  26. package/dist/src/export/yaml-lite.d.ts.map +1 -0
  27. package/dist/src/export/yaml-lite.js +219 -0
  28. package/dist/src/export/yaml-lite.js.map +1 -0
  29. package/dist/src/instance-resolution.d.ts +19 -0
  30. package/dist/src/instance-resolution.d.ts.map +1 -1
  31. package/dist/src/instance-resolution.js +87 -1
  32. package/dist/src/instance-resolution.js.map +1 -1
  33. package/dist/src/model-diff.d.ts.map +1 -1
  34. package/dist/src/model-diff.js +0 -5
  35. package/dist/src/model-diff.js.map +1 -1
  36. package/dist/src/runtime.d.ts +143 -0
  37. package/dist/src/runtime.d.ts.map +1 -0
  38. package/dist/src/runtime.js +648 -0
  39. package/dist/src/runtime.js.map +1 -0
  40. package/dist/src/ser-des/config/artifact.d.ts.map +1 -1
  41. package/dist/src/ser-des/config/artifact.js +6 -0
  42. package/dist/src/ser-des/config/artifact.js.map +1 -1
  43. package/dist/src/ser-des/config/attestation.d.ts +5 -0
  44. package/dist/src/ser-des/config/attestation.d.ts.map +1 -0
  45. package/dist/src/ser-des/config/attestation.js +143 -0
  46. package/dist/src/ser-des/config/attestation.js.map +1 -0
  47. package/dist/src/ser-des/config/data.d.ts.map +1 -1
  48. package/dist/src/ser-des/config/data.js +98 -0
  49. package/dist/src/ser-des/config/data.js.map +1 -1
  50. package/dist/src/ser-des/config/documentModule.js +5 -5
  51. package/dist/src/ser-des/config/documentModule.js.map +1 -1
  52. package/dist/src/ser-des/config/index.d.ts +8 -0
  53. package/dist/src/ser-des/config/index.d.ts.map +1 -1
  54. package/dist/src/ser-des/config/index.js +22 -49
  55. package/dist/src/ser-des/config/index.js.map +1 -1
  56. package/dist/src/ser-des/config/instance.d.ts.map +1 -1
  57. package/dist/src/ser-des/config/instance.js +24 -0
  58. package/dist/src/ser-des/config/instance.js.map +1 -1
  59. package/dist/src/ser-des/config/process.d.ts.map +1 -1
  60. package/dist/src/ser-des/config/process.js +8 -0
  61. package/dist/src/ser-des/config/process.js.map +1 -1
  62. package/dist/src/ser-des/config/processSequence.d.ts +19 -0
  63. package/dist/src/ser-des/config/processSequence.d.ts.map +1 -0
  64. package/dist/src/ser-des/config/processSequence.js +77 -0
  65. package/dist/src/ser-des/config/processSequence.js.map +1 -0
  66. package/dist/src/ser-des/config/quantity.d.ts +4 -1
  67. package/dist/src/ser-des/config/quantity.d.ts.map +1 -1
  68. package/dist/src/ser-des/config/quantity.js +63 -1
  69. package/dist/src/ser-des/config/quantity.js.map +1 -1
  70. package/dist/src/ser-des/config/subject.d.ts.map +1 -1
  71. package/dist/src/ser-des/config/subject.js +14 -0
  72. package/dist/src/ser-des/config/subject.js.map +1 -1
  73. package/dist/src/ser-des/index.d.ts +4 -1
  74. package/dist/src/ser-des/index.d.ts.map +1 -1
  75. package/dist/src/ser-des/index.js +3 -1
  76. package/dist/src/ser-des/index.js.map +1 -1
  77. package/dist/src/ser-des/package.d.ts.map +1 -1
  78. package/dist/src/ser-des/package.js +9 -7
  79. package/dist/src/ser-des/package.js.map +1 -1
  80. package/dist/src/ser-des/parse.d.ts +24 -0
  81. package/dist/src/ser-des/parse.d.ts.map +1 -1
  82. package/dist/src/ser-des/parse.js +69 -33
  83. package/dist/src/ser-des/parse.js.map +1 -1
  84. package/dist/src/ser-des/shape-front-end.d.ts +8 -0
  85. package/dist/src/ser-des/shape-front-end.d.ts.map +1 -0
  86. package/dist/src/ser-des/shape-front-end.js +215 -0
  87. package/dist/src/ser-des/shape-front-end.js.map +1 -0
  88. package/dist/src/ser-des/types.d.ts +4 -10
  89. package/dist/src/ser-des/types.d.ts.map +1 -1
  90. package/dist/src/types/Artifact.d.ts +7 -0
  91. package/dist/src/types/Artifact.d.ts.map +1 -1
  92. package/dist/src/types/Attestation.d.ts +60 -0
  93. package/dist/src/types/Attestation.d.ts.map +1 -0
  94. package/dist/src/types/Attestation.js +20 -0
  95. package/dist/src/types/Attestation.js.map +1 -0
  96. package/dist/src/types/DocumentModule.d.ts +1 -1
  97. package/dist/src/types/DocumentModule.d.ts.map +1 -1
  98. package/dist/src/types/Instance.d.ts +6 -2
  99. package/dist/src/types/Instance.d.ts.map +1 -1
  100. package/dist/src/types/ProcessModel.d.ts +0 -11
  101. package/dist/src/types/ProcessModel.d.ts.map +1 -1
  102. package/dist/src/types/ProcessModel.js +2 -28
  103. package/dist/src/types/ProcessModel.js.map +1 -1
  104. package/dist/src/types/Quantity.d.ts +22 -0
  105. package/dist/src/types/Quantity.d.ts.map +1 -1
  106. package/dist/src/types/Standard.d.ts +2 -13
  107. package/dist/src/types/Standard.d.ts.map +1 -1
  108. package/dist/src/types/Subject.d.ts +14 -0
  109. package/dist/src/types/Subject.d.ts.map +1 -1
  110. package/dist/src/types/data.d.ts +13 -0
  111. package/dist/src/types/data.d.ts.map +1 -1
  112. package/dist/src/types/process.d.ts +8 -0
  113. package/dist/src/types/process.d.ts.map +1 -1
  114. package/dist-browser/index.mjs +1746 -1829
  115. package/dist-cli/primmel.mjs +1630 -845
  116. package/package.json +15 -3
  117. package/dist/src/ser-des/config/processModel.d.ts +0 -13
  118. package/dist/src/ser-des/config/processModel.d.ts.map +0 -1
  119. package/dist/src/ser-des/config/processModel.js +0 -163
  120. package/dist/src/ser-des/config/processModel.js.map +0 -1
  121. package/dist/src/ser-des/config/storyline.d.ts +0 -7
  122. package/dist/src/ser-des/config/storyline.d.ts.map +0 -1
  123. package/dist/src/ser-des/config/storyline.js +0 -264
  124. package/dist/src/ser-des/config/storyline.js.map +0 -1
  125. package/dist/src/ser-des/config/workflowConfig.d.ts +0 -5
  126. package/dist/src/ser-des/config/workflowConfig.d.ts.map +0 -1
  127. package/dist/src/ser-des/config/workflowConfig.js +0 -129
  128. package/dist/src/ser-des/config/workflowConfig.js.map +0 -1
  129. package/dist/src/ser-des/config/workflowStage.d.ts +0 -5
  130. package/dist/src/ser-des/config/workflowStage.d.ts.map +0 -1
  131. package/dist/src/ser-des/config/workflowStage.js +0 -96
  132. package/dist/src/ser-des/config/workflowStage.js.map +0 -1
  133. package/dist/src/types/Storyline.d.ts +0 -62
  134. package/dist/src/types/Storyline.d.ts.map +0 -1
  135. package/dist/src/types/Storyline.js +0 -51
  136. package/dist/src/types/Storyline.js.map +0 -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 readdirSync6, statSync as statSync4, writeFileSync } from "node:fs";
5
- import { join as join7 } from "node:path";
4
+ import { existsSync as existsSync8, readdirSync as readdirSync7, statSync as statSync4, writeFileSync } from "node:fs";
5
+ import { join as join9 } 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";
@@ -186,6 +186,52 @@ function createDuplicateIdChecker() {
186
186
  // src/ser-des/parse.ts
187
187
  function parse(mmelString, parsers, options = {}) {
188
188
  const tokens = tokenizeWithPositions(mmelString);
189
+ const declarations = [];
190
+ let i = 0;
191
+ while (i < tokens.length) {
192
+ const tok = tokens[i++];
193
+ const cfg = parsers[tok.value];
194
+ if (!cfg) {
195
+ if (options.strict) {
196
+ throw new Error(
197
+ `Unknown keyword "${tok.value}" at line ${tok.start.line} col ${tok.start.col}. Use lenient mode (default) to skip unknown keywords.`
198
+ );
199
+ }
200
+ continue;
201
+ }
202
+ if (cfg.takesID) {
203
+ if (i + 1 > tokens.length) {
204
+ throw new Error(
205
+ `Keyword "${tok.value}" at line ${tok.start.line} col ${tok.start.col} expects an ID and payload, but only ${tokens.length - i + 1} token(s) remain.`
206
+ );
207
+ }
208
+ const idTok = tokens[i++];
209
+ const payloadTok = tokens[i++];
210
+ declarations.push({
211
+ keyword: tok.value,
212
+ id: idTok.value,
213
+ payload: payloadTok.value,
214
+ start: tok.start,
215
+ end: payloadTok.end
216
+ });
217
+ } else {
218
+ if (i >= tokens.length) {
219
+ throw new Error(
220
+ `Keyword "${tok.value}" at line ${tok.start.line} col ${tok.start.col} expects a payload, but no tokens remain.`
221
+ );
222
+ }
223
+ const payloadTok = tokens[i++];
224
+ declarations.push({
225
+ keyword: tok.value,
226
+ payload: payloadTok.value,
227
+ start: tok.start,
228
+ end: payloadTok.end
229
+ });
230
+ }
231
+ }
232
+ return parseDeclarations(declarations, parsers, options);
233
+ }
234
+ function parseDeclarations(declarations, parsers, options = {}) {
189
235
  const dupChecker = createDuplicateIdChecker();
190
236
  const constructs = [];
191
237
  let ctx = {
@@ -196,7 +242,6 @@ function parse(mmelString, parsers, options = {}) {
196
242
  roles: {},
197
243
  processes: {},
198
244
  // The abstract-process models (smart TODO.roadmap/40 batch 2)
199
- processModels: {},
200
245
  pages: {},
201
246
  gateways: {},
202
247
  regs: {},
@@ -258,11 +303,10 @@ function parse(mmelString, parsers, options = {}) {
258
303
  evaluationDimensions: {},
259
304
  evaluationProfiles: {},
260
305
  // The certificate rendering contract (batch 3)
306
+ attestations: {},
261
307
  certificateTemplates: {},
262
308
  // The certification workflow step register (batch 3)
263
- workflowConfigs: {},
264
309
  // The named pipeline stages (batch 5)
265
- workflowStages: {},
266
310
  // The verification pathways (batch 3)
267
311
  verificationPathways: {},
268
312
  // The selection rules (batch 3)
@@ -298,8 +342,6 @@ function parse(mmelString, parsers, options = {}) {
298
342
  documentModules: {},
299
343
  informativeAnnexes: {},
300
344
  partAnnexes: {},
301
- demoWorlds: {},
302
- storylines: {},
303
345
  // Primmel v3 twin interface (TODO.roadmap/32)
304
346
  connectorProfiles: {},
305
347
  // Primmel v3 continuous compliance (TODO.roadmap/34)
@@ -322,11 +364,23 @@ function parse(mmelString, parsers, options = {}) {
322
364
  // Issue collection (duplicate IDs, etc.)
323
365
  issues: []
324
366
  };
325
- let i = 0;
326
- while (i < tokens.length) {
327
- const tok = tokens[i++];
328
- const keyword = tok.value;
367
+ for (const decl of declarations) {
368
+ const tok = { start: decl.start };
369
+ const keyword = decl.keyword;
329
370
  const cfg = parsers[keyword];
371
+ if (cfg?.deprecated) {
372
+ ctx.issues.push({
373
+ severity: "warning",
374
+ code: "construct-deprecated",
375
+ construct: keyword,
376
+ message: `construct "${keyword}" at line ${tok.start.line} col ${tok.start.col} is deprecated: ${cfg.deprecated} (construct-deprecated)`,
377
+ position: {
378
+ line: tok.start.line,
379
+ col: tok.start.col,
380
+ offset: tok.start.offset
381
+ }
382
+ });
383
+ }
330
384
  if (!cfg) {
331
385
  if (options.strict) {
332
386
  throw new Error(
@@ -337,13 +391,8 @@ function parse(mmelString, parsers, options = {}) {
337
391
  }
338
392
  let updateCtx;
339
393
  if (cfg.takesID) {
340
- if (i + 1 > tokens.length) {
341
- throw new Error(
342
- `Keyword "${keyword}" at line ${tok.start.line} col ${tok.start.col} expects an ID and payload, but only ${tokens.length - i + 1} token(s) remain.`
343
- );
344
- }
345
- const idTok = tokens[i++];
346
- const payloadTok = tokens[i++];
394
+ const idTok = { value: decl.id ?? "", start: decl.start };
395
+ const payloadTok = { value: decl.payload ?? "", end: decl.start };
347
396
  if (cfg.field) {
348
397
  const issue = dupChecker.check(
349
398
  cfg.field,
@@ -361,24 +410,19 @@ function parse(mmelString, parsers, options = {}) {
361
410
  id: idTok.value,
362
411
  keyword,
363
412
  start: tok.start,
364
- end: payloadTok.end
413
+ end: decl.end ?? payloadTok.end
365
414
  });
366
415
  }
367
416
  updateCtx = cfg.parse(idTok.value, payloadTok.value);
368
417
  } else {
369
- if (i >= tokens.length) {
370
- throw new Error(
371
- `Keyword "${keyword}" at line ${tok.start.line} col ${tok.start.col} expects a payload, but no tokens remain.`
372
- );
373
- }
374
- const payloadTok = tokens[i++];
418
+ const payloadTok = { value: decl.payload ?? "", end: decl.start };
375
419
  if (options.withProvenance) {
376
420
  constructs.push({
377
421
  field: cfg.field ?? keyword,
378
422
  id: "",
379
423
  keyword,
380
424
  start: tok.start,
381
- end: payloadTok.end
425
+ end: decl.end ?? payloadTok.end
382
426
  });
383
427
  }
384
428
  updateCtx = cfg.parse(payloadTok.value);
@@ -1867,10 +1911,21 @@ var parseDataClass = function(id, data) {
1867
1911
  result.helper = details.trim() === "true";
1868
1912
  return;
1869
1913
  }
1914
+ if (head === "overlay") {
1915
+ result.overlay = details.replace(/[{}\s]/g, "") === "true";
1916
+ return;
1917
+ }
1870
1918
  if (head === "extends") {
1871
1919
  result.extends = details.trim();
1872
1920
  return;
1873
1921
  }
1922
+ const lutaml = head.match(/^attribute\s+(\S+?)\s*,\s*(\S+)\s*$/);
1923
+ if (lutaml) {
1924
+ result.attributes.push(
1925
+ parseLutamlAttribute(lutaml[1], lutaml[2], details)
1926
+ );
1927
+ return;
1928
+ }
1874
1929
  result.attributes.push(parseDataAttribute(head, details));
1875
1930
  },
1876
1931
  { construct: "class", id }
@@ -1880,6 +1935,52 @@ var parseDataClass = function(id, data) {
1880
1935
  return ctx;
1881
1936
  };
1882
1937
  };
1938
+ var parseLutamlAttribute = (name, type, details) => {
1939
+ const result = {
1940
+ id: name,
1941
+ type,
1942
+ modality: "",
1943
+ cardinality: "",
1944
+ definition: "",
1945
+ ref: [],
1946
+ satisfy: [],
1947
+ _relations: { ref: [] },
1948
+ surface: "lutaml"
1949
+ };
1950
+ const wrapped = details.startsWith("{") ? details : `{ ${details} }`;
1951
+ forEachEntry(
1952
+ wrapped,
1953
+ (keyword, value, peek) => {
1954
+ if (keyword === "definition") {
1955
+ result.definition = unwrapped(value);
1956
+ } else if (keyword === "cardinality") {
1957
+ result.cardinality = value().trim();
1958
+ } else if (keyword === "modality") {
1959
+ result.modality = value();
1960
+ } else if (keyword === "values") {
1961
+ const facets = /* @__PURE__ */ new Set([
1962
+ "definition",
1963
+ "cardinality",
1964
+ "values",
1965
+ "modality",
1966
+ "reference"
1967
+ ]);
1968
+ const vals = [value()];
1969
+ while (peek() !== void 0 && !facets.has(peek())) {
1970
+ vals.push(value());
1971
+ }
1972
+ result.enumValues = vals;
1973
+ } else if (keyword === "reference") {
1974
+ result._relations.ref = tokenizePackage(value());
1975
+ } else {
1976
+ value();
1977
+ }
1978
+ return true;
1979
+ },
1980
+ { construct: "class", id: name }
1981
+ );
1982
+ return result;
1983
+ };
1883
1984
  var parseDataAttribute = (basic, details) => {
1884
1985
  const result = {
1885
1986
  id: "",
@@ -1953,6 +2054,7 @@ var resolveDataClass = function(ctx, unresolved) {
1953
2054
  ...unresolved.store !== void 0 ? { store: unresolved.store } : {},
1954
2055
  ...unresolved.indexes !== void 0 ? { indexes: unresolved.indexes } : {},
1955
2056
  ...unresolved.helper !== void 0 ? { helper: unresolved.helper } : {},
2057
+ ...unresolved.overlay !== void 0 ? { overlay: unresolved.overlay } : {},
1956
2058
  ...unresolved.extends !== void 0 ? { extends: unresolved.extends } : {},
1957
2059
  ...unresolved.description !== void 0 ? { description: unresolved.description } : {},
1958
2060
  ...unresolved.ref !== void 0 ? { ref: unresolved.ref } : {}
@@ -1987,6 +2089,9 @@ var dumpDataClass = function(dataclass) {
1987
2089
  if (dataclass.helper !== void 0) {
1988
2090
  out += " helper { " + dataclass.helper + " }\n";
1989
2091
  }
2092
+ if (dataclass.overlay) {
2093
+ out += " overlay { true }\n";
2094
+ }
1990
2095
  if (dataclass.extends) {
1991
2096
  out += " extends { " + dataclass.extends + " }\n";
1992
2097
  }
@@ -2006,6 +2111,26 @@ var dumpDataClass = function(dataclass) {
2006
2111
  return out;
2007
2112
  };
2008
2113
  var toDataAttributeModel = (attribute) => {
2114
+ if (attribute.surface === "lutaml") {
2115
+ const lutaml = " attribute " + attribute.id + ", " + attribute.type + " {";
2116
+ const facets = [];
2117
+ if (attribute.definition !== "") {
2118
+ facets.push('definition "' + escapeString(attribute.definition) + '"');
2119
+ }
2120
+ if (attribute.cardinality !== "") {
2121
+ facets.push("cardinality " + attribute.cardinality);
2122
+ }
2123
+ if (attribute.enumValues && attribute.enumValues.length > 0) {
2124
+ facets.push("values " + attribute.enumValues.join(" "));
2125
+ }
2126
+ if (attribute.modality !== "") {
2127
+ facets.push("modality " + attribute.modality);
2128
+ }
2129
+ if (facets.length === 0) {
2130
+ return lutaml + " }\n";
2131
+ }
2132
+ return lutaml + " " + facets.join(" ") + " }\n";
2133
+ }
2009
2134
  let out = " " + attribute.id;
2010
2135
  if (attribute.type !== "") {
2011
2136
  out += ": " + attribute.type;
@@ -2398,6 +2523,8 @@ function readQuantityBlock(content) {
2398
2523
  out.uncertainty = coerceValueToken(t[i++]);
2399
2524
  } else if (cmd === "tolerance") {
2400
2525
  out.tolerance = coerceValueToken(t[i++]);
2526
+ } else if (cmd === "provenance") {
2527
+ out.provenance = readProvenanceBlock(unwrapBlock(t[i++]));
2401
2528
  } else {
2402
2529
  unwrapBlock(t[i++]);
2403
2530
  }
@@ -2405,7 +2532,53 @@ function readQuantityBlock(content) {
2405
2532
  return out;
2406
2533
  }
2407
2534
  function needsQuantityBlock(v) {
2408
- return v.quantityKind !== void 0 || v.uncertainty !== void 0 || v.tolerance !== void 0;
2535
+ return v.quantityKind !== void 0 || v.uncertainty !== void 0 || v.tolerance !== void 0 || v.provenance !== void 0;
2536
+ }
2537
+ function readProvenanceBlock(content) {
2538
+ const out = { source: "" };
2539
+ const t = tokenize(content);
2540
+ let i = 0;
2541
+ while (i < t.length) {
2542
+ const cmd = t[i++];
2543
+ if (i >= t.length) {
2544
+ break;
2545
+ }
2546
+ if (cmd === "source") {
2547
+ out.source = stripWrapping(t[i++]);
2548
+ } else if (cmd === "page") {
2549
+ out.page = String(coerceValueToken(t[i++]));
2550
+ } else if (cmd === "entry_wording") {
2551
+ out.entryWording = stripWrapping(t[i++]);
2552
+ } else if (cmd === "read_at") {
2553
+ out.readAt = stripColon(stripWrapping(t[i++]));
2554
+ } else if (cmd === "declaration") {
2555
+ out.declaration = stripColon(stripWrapping(t[i++]));
2556
+ } else if (cmd === "verdict") {
2557
+ out.verdict = stripColon(stripWrapping(t[i++]));
2558
+ } else {
2559
+ unwrapBlock(t[i++]);
2560
+ }
2561
+ }
2562
+ return out;
2563
+ }
2564
+ function dumpProvenanceBlock(p) {
2565
+ const parts = ['source "' + escapeString(p.source) + '"'];
2566
+ if (p.page !== void 0) {
2567
+ parts.push("page " + dumpScalarToken(p.page));
2568
+ }
2569
+ if (p.entryWording !== void 0) {
2570
+ parts.push('entry_wording "' + escapeString(p.entryWording) + '"');
2571
+ }
2572
+ if (p.readAt !== void 0) {
2573
+ parts.push("read_at " + dumpScalarToken(p.readAt));
2574
+ }
2575
+ if (p.declaration !== void 0) {
2576
+ parts.push("declaration " + dumpScalarToken(p.declaration));
2577
+ }
2578
+ if (p.verdict !== void 0) {
2579
+ parts.push("verdict " + dumpScalarToken(p.verdict));
2580
+ }
2581
+ return "{ " + parts.join(" ") + " }";
2409
2582
  }
2410
2583
  function dumpScalarToken(v) {
2411
2584
  if (typeof v === "number") {
@@ -2440,6 +2613,9 @@ function dumpQuantityBlock(v) {
2440
2613
  if (v.tolerance !== void 0) {
2441
2614
  parts.push("tolerance " + dumpScalarToken(v.tolerance));
2442
2615
  }
2616
+ if (v.provenance !== void 0) {
2617
+ parts.push("provenance " + dumpProvenanceBlock(v.provenance));
2618
+ }
2443
2619
  return "{ " + parts.join(" ") + " }";
2444
2620
  }
2445
2621
 
@@ -3074,6 +3250,8 @@ var parseProcess = function(id, data) {
3074
3250
  result.machineSteps = tokenize(stripWrapping(value())).map(stripColon).map(stripWrapping).filter((s) => s.length > 0);
3075
3251
  } else if (keyword === "name") {
3076
3252
  result.name = unwrapped(value);
3253
+ } else if (keyword === "overlay") {
3254
+ result.overlay = value() === "true";
3077
3255
  } else if (keyword === "actor") {
3078
3256
  result._relations.actor = value();
3079
3257
  } else if (keyword === "parent") {
@@ -3329,6 +3507,9 @@ function dumpDoes(flow) {
3329
3507
  var dumpProcess = function(process2, ctx) {
3330
3508
  let out = "process " + process2.id + " {\n";
3331
3509
  out += ' name "' + escapeString(process2.name) + '"\n';
3510
+ if (process2.overlay) {
3511
+ out += " overlay true\n";
3512
+ }
3332
3513
  if (process2.summary) {
3333
3514
  out += ' summary "' + escapeString(process2.summary) + '"\n';
3334
3515
  }
@@ -3568,348 +3749,52 @@ var dumpProcess = function(process2, ctx) {
3568
3749
  return out;
3569
3750
  };
3570
3751
 
3571
- // src/ser-des/config/processModel.ts
3572
- function parseProcessSequence(block) {
3573
- return tokenizePackage(block).map(stripColon).map(stripWrapping).filter((s) => s.length > 0);
3574
- }
3575
- function parseProcessRegister(id, block) {
3576
- const register = {
3577
- id,
3578
- label: "",
3579
- clause: "",
3580
- maintainer: "",
3581
- published: "",
3582
- entries: ""
3583
- };
3584
- forEachEntry(
3585
- block,
3586
- (keyword, value) => {
3587
- if (keyword === "label") {
3588
- register.label = stripWrapping(value());
3589
- } else if (keyword === "clause") {
3590
- register.clause = stripWrapping(value());
3591
- } else if (keyword === "maintainer") {
3592
- register.maintainer = stripWrapping(value());
3593
- } else if (keyword === "published") {
3594
- register.published = stripWrapping(value());
3595
- } else if (keyword === "entries") {
3596
- register.entries = stripWrapping(value());
3597
- } else {
3598
- return false;
3599
- }
3600
- return true;
3601
- },
3602
- { construct: "process_model register", id }
3603
- );
3604
- return register;
3752
+ // src/ser-des/config/verificationPathway.ts
3753
+ var VERIFICATION_KINDS = [
3754
+ "initial",
3755
+ "subsequent",
3756
+ "periodic",
3757
+ "in-service"
3758
+ ];
3759
+ var TRIGGER_KINDS = ["timer", "signal"];
3760
+ var LIMITS_MODES = ["same-as-type-evaluation", "override"];
3761
+ function readIdList(block) {
3762
+ return tokenize(stripWrapping(block)).map(stripColon).map(stripWrapping).filter((s) => s.length > 0);
3605
3763
  }
3606
- var parseProcessModel = (id, data) => {
3607
- const model = {
3608
- id,
3609
- sequence: [],
3610
- registers: [],
3611
- source: { doc: "", clause: "" }
3612
- };
3613
- forEachEntry(
3614
- data,
3615
- (keyword, value, peek) => {
3616
- if (keyword === "sequence") {
3617
- model.sequence = parseProcessSequence(unwrapBlock(value()));
3618
- } else if (keyword === "register") {
3619
- const regId = stripWrapping(value());
3620
- const head = peek();
3621
- if (head === void 0 || !head.startsWith("{")) {
3622
- throw new Error(
3623
- `Parsing error: process_model. ID ${id}: register ${regId} is missing its block`
3624
- );
3625
- }
3626
- model.registers.push(parseProcessRegister(regId, unwrapBlock(value())));
3627
- } else if (keyword === "source") {
3628
- model.source = readSource(unwrapBlock(value()));
3629
- } else {
3630
- return false;
3631
- }
3632
- return true;
3633
- },
3634
- { construct: "process_model", id }
3635
- );
3636
- return (ctx) => {
3637
- ctx.processModels[id] = model;
3638
- return ctx;
3639
- };
3640
- };
3641
- function dumpProcessSequence(sequence) {
3642
- if (sequence.length === 0) {
3643
- return "";
3764
+ function readWindow(block) {
3765
+ const window = { years: 0, months: 0 };
3766
+ const t = tokenize(unwrapBlock(block));
3767
+ for (let i = 0; i + 1 < t.length; i += 2) {
3768
+ if (t[i] === "years") {
3769
+ window.years = parseInt(stripWrapping(t[i + 1]), 10) || 0;
3770
+ } else if (t[i] === "months") {
3771
+ window.months = parseInt(stripWrapping(t[i + 1]), 10) || 0;
3772
+ }
3644
3773
  }
3645
- return "sequence { " + sequence.map(dumpBareSafe).join(" ") + " }";
3774
+ return window;
3646
3775
  }
3647
- function dumpProcessRegister(r, indent) {
3648
- let out = indent + "register " + dumpBareSafe(r.id) + " {\n";
3649
- if (r.label) {
3650
- out += indent + ' label "' + escapeString(r.label) + '"\n';
3651
- }
3652
- if (r.clause) {
3653
- out += indent + ' clause "' + escapeString(r.clause) + '"\n';
3654
- }
3655
- if (r.maintainer) {
3656
- out += indent + " maintainer " + dumpBareSafe(r.maintainer) + "\n";
3657
- }
3658
- if (r.published) {
3659
- out += indent + ' published "' + escapeString(r.published) + '"\n';
3776
+ function dumpWindow(w, indent) {
3777
+ let out = indent + "window {";
3778
+ if (w.years > 0) {
3779
+ out += " years " + w.years;
3660
3780
  }
3661
- if (r.entries) {
3662
- out += indent + ' entries "' + escapeString(r.entries) + '"\n';
3781
+ if (w.months > 0) {
3782
+ out += " months " + w.months;
3663
3783
  }
3664
- out += indent + "}\n";
3665
- return out;
3784
+ return out + " }\n";
3666
3785
  }
3667
- var dumpProcessModel = function(m) {
3668
- let out = "process_model " + m.id + " {\n";
3669
- const seq = dumpProcessSequence(m.sequence);
3670
- if (seq) {
3671
- out += " " + seq + "\n";
3672
- }
3673
- for (const r of m.registers) {
3674
- out += dumpProcessRegister(r, " ");
3786
+ function dumpSourceLines(src, indent) {
3787
+ if (!src.doc && !src.clause) {
3788
+ return "";
3675
3789
  }
3676
- if (m.source.doc || m.source.clause) {
3677
- out += " source {\n";
3678
- if (m.source.doc) {
3679
- out += ' doc "' + escapeString(m.source.doc) + '"\n';
3680
- }
3681
- if (m.source.clause) {
3682
- out += ' clause "' + escapeString(m.source.clause) + '"\n';
3683
- }
3684
- out += " }\n";
3790
+ let out = indent + "source {\n";
3791
+ if (src.doc) {
3792
+ out += indent + ' doc "' + escapeString(src.doc) + '"\n';
3685
3793
  }
3686
- out += "}\n";
3687
- return out;
3688
- };
3689
-
3690
- // src/ser-des/config/workflowConfig.ts
3691
- var WORKFLOW_PHASES = [
3692
- "intake",
3693
- "dispatch",
3694
- "testing",
3695
- "evaluation",
3696
- "issuance"
3697
- ];
3698
- function readTokenList(block) {
3699
- return tokenize(stripWrapping(block)).map(stripColon).map(stripWrapping).filter((s) => s.length > 0);
3700
- }
3701
- function dumpTokenList(keyword, ids, indent) {
3702
- if (ids.length === 0) {
3703
- return "";
3794
+ if (src.clause) {
3795
+ out += indent + ' clause "' + escapeString(src.clause) + '"\n';
3704
3796
  }
3705
- return indent + keyword + " { " + ids.map(dumpBareSafe).join(" ") + " }\n";
3706
- }
3707
- var parseWorkflowConfig = (id, data) => {
3708
- const config = { id, overlay: false, steps: [] };
3709
- forEachEntry(
3710
- data,
3711
- (keyword, value) => {
3712
- if (keyword === "overlay") {
3713
- config.overlay = value() === "true";
3714
- } else if (keyword === "step") {
3715
- const step = {
3716
- id: stripWrapping(stripColon(value())),
3717
- phase: null,
3718
- actor: null,
3719
- label: null,
3720
- description: null,
3721
- inputs: [],
3722
- outputs: [],
3723
- gates: []
3724
- };
3725
- forEachEntry(
3726
- unwrapBlock(value()),
3727
- (k2, v2) => {
3728
- if (k2 === "phase") {
3729
- const p = stripWrapping(v2());
3730
- if (!WORKFLOW_PHASES.includes(p)) {
3731
- throw new Error(
3732
- `Parsing error: workflow_config. ID ${id}: Unknown phase "${p}" (valid: ${WORKFLOW_PHASES.join(", ")})`
3733
- );
3734
- }
3735
- step.phase = p;
3736
- } else if (k2 === "actor") {
3737
- step.actor = stripWrapping(v2());
3738
- } else if (k2 === "label") {
3739
- step.label = stripWrapping(v2());
3740
- } else if (k2 === "description") {
3741
- step.description = stripWrapping(v2());
3742
- } else if (k2 === "inputs") {
3743
- step.inputs = readTokenList(v2());
3744
- } else if (k2 === "outputs") {
3745
- step.outputs = readTokenList(v2());
3746
- } else if (k2 === "gates") {
3747
- step.gates = readTokenList(v2());
3748
- } else {
3749
- return false;
3750
- }
3751
- return true;
3752
- },
3753
- { construct: "workflow_config", id }
3754
- );
3755
- config.steps.push(step);
3756
- } else {
3757
- return false;
3758
- }
3759
- return true;
3760
- },
3761
- { construct: "workflow_config", id }
3762
- );
3763
- return (ctx) => {
3764
- ctx.workflowConfigs[id] = config;
3765
- return ctx;
3766
- };
3767
- };
3768
- var dumpWorkflowConfig = function(c) {
3769
- let out = "workflow_config " + dumpBareSafe(c.id) + " {\n";
3770
- if (c.overlay) {
3771
- out += " overlay true\n";
3772
- }
3773
- for (const s of c.steps) {
3774
- out += " step " + dumpBareSafe(s.id) + " {\n";
3775
- if (s.phase) {
3776
- out += " phase " + s.phase + "\n";
3777
- }
3778
- if (s.actor) {
3779
- out += " actor " + dumpBareSafe(s.actor) + "\n";
3780
- }
3781
- if (s.label) {
3782
- out += ' label "' + escapeString(s.label) + '"\n';
3783
- }
3784
- if (s.description) {
3785
- out += ' description "' + escapeString(s.description) + '"\n';
3786
- }
3787
- out += dumpTokenList("inputs", s.inputs, " ");
3788
- out += dumpTokenList("outputs", s.outputs, " ");
3789
- if (s.gates.length > 0) {
3790
- out += " gates { " + s.gates.map((g) => '"' + escapeString(g) + '"').join(" ") + " }\n";
3791
- }
3792
- out += " }\n";
3793
- }
3794
- out += "}\n";
3795
- return out;
3796
- };
3797
-
3798
- // src/ser-des/config/workflowStage.ts
3799
- function readTokenList2(block) {
3800
- return tokenize(stripWrapping(block)).map(stripColon).map(stripWrapping).filter((s) => s.length > 0);
3801
- }
3802
- function dumpTokenList2(keyword, ids) {
3803
- if (ids.length === 0) {
3804
- return "";
3805
- }
3806
- return " " + keyword + " { " + ids.map(dumpBareSafe).join(" ") + " }\n";
3807
- }
3808
- var parseWorkflowStage = (id, data) => {
3809
- const stage = {
3810
- id,
3811
- label: "",
3812
- description: "",
3813
- elements: [],
3814
- startEvent: "",
3815
- endEvents: [],
3816
- approvals: [],
3817
- gateways: []
3818
- };
3819
- forEachEntry(
3820
- data,
3821
- (keyword, value) => {
3822
- if (keyword === "label") {
3823
- stage.label = stripWrapping(value());
3824
- } else if (keyword === "description") {
3825
- stage.description = stripWrapping(value());
3826
- } else if (keyword === "elements") {
3827
- stage.elements = readTokenList2(value());
3828
- } else if (keyword === "start_event") {
3829
- stage.startEvent = stripWrapping(value());
3830
- } else if (keyword === "end_events") {
3831
- stage.endEvents = readTokenList2(value());
3832
- } else if (keyword === "approvals") {
3833
- stage.approvals = readTokenList2(value());
3834
- } else if (keyword === "gateways") {
3835
- stage.gateways = readTokenList2(value());
3836
- } else {
3837
- return false;
3838
- }
3839
- return true;
3840
- },
3841
- { construct: "workflow_stage", id }
3842
- );
3843
- return (ctx) => {
3844
- ctx.workflowStages[id] = stage;
3845
- return ctx;
3846
- };
3847
- };
3848
- var dumpWorkflowStage = function(s) {
3849
- let out = "workflow_stage " + dumpBareSafe(s.id) + " {\n";
3850
- if (s.label) {
3851
- out += ' label "' + escapeString(s.label) + '"\n';
3852
- }
3853
- if (s.description) {
3854
- out += ' description "' + escapeString(s.description) + '"\n';
3855
- }
3856
- out += dumpTokenList2("elements", s.elements);
3857
- if (s.startEvent) {
3858
- out += " start_event " + dumpBareSafe(s.startEvent) + "\n";
3859
- }
3860
- out += dumpTokenList2("end_events", s.endEvents);
3861
- out += dumpTokenList2("approvals", s.approvals);
3862
- out += dumpTokenList2("gateways", s.gateways);
3863
- out += "}\n";
3864
- return out;
3865
- };
3866
-
3867
- // src/ser-des/config/verificationPathway.ts
3868
- var VERIFICATION_KINDS = [
3869
- "initial",
3870
- "subsequent",
3871
- "periodic",
3872
- "in-service"
3873
- ];
3874
- var TRIGGER_KINDS = ["timer", "signal"];
3875
- var LIMITS_MODES = ["same-as-type-evaluation", "override"];
3876
- function readIdList(block) {
3877
- return tokenize(stripWrapping(block)).map(stripColon).map(stripWrapping).filter((s) => s.length > 0);
3878
- }
3879
- function readWindow(block) {
3880
- const window = { years: 0, months: 0 };
3881
- const t = tokenize(unwrapBlock(block));
3882
- for (let i = 0; i + 1 < t.length; i += 2) {
3883
- if (t[i] === "years") {
3884
- window.years = parseInt(stripWrapping(t[i + 1]), 10) || 0;
3885
- } else if (t[i] === "months") {
3886
- window.months = parseInt(stripWrapping(t[i + 1]), 10) || 0;
3887
- }
3888
- }
3889
- return window;
3890
- }
3891
- function dumpWindow(w, indent) {
3892
- let out = indent + "window {";
3893
- if (w.years > 0) {
3894
- out += " years " + w.years;
3895
- }
3896
- if (w.months > 0) {
3897
- out += " months " + w.months;
3898
- }
3899
- return out + " }\n";
3900
- }
3901
- function dumpSourceLines(src, indent) {
3902
- if (!src.doc && !src.clause) {
3903
- return "";
3904
- }
3905
- let out = indent + "source {\n";
3906
- if (src.doc) {
3907
- out += indent + ' doc "' + escapeString(src.doc) + '"\n';
3908
- }
3909
- if (src.clause) {
3910
- out += indent + ' clause "' + escapeString(src.clause) + '"\n';
3911
- }
3912
- return out + indent + "}\n";
3797
+ return out + indent + "}\n";
3913
3798
  }
3914
3799
  var parseVerificationPathway = (id, data) => {
3915
3800
  const pathway = {
@@ -11226,7 +11111,7 @@ function readLimit(block) {
11226
11111
  } else if (cmd === "notes") {
11227
11112
  limit.notes = stripWrapping(t[i++]);
11228
11113
  } else if (cmd === "quantity") {
11229
- const quantity = { kind: "", unit: "" };
11114
+ const quantity2 = { kind: "", unit: "" };
11230
11115
  const qt = tokenize(unwrapBlock(t[i++]));
11231
11116
  let k = 0;
11232
11117
  while (k < qt.length) {
@@ -11235,14 +11120,14 @@ function readLimit(block) {
11235
11120
  break;
11236
11121
  }
11237
11122
  if (qc === "kind") {
11238
- quantity.kind = stripWrapping(qt[k++]);
11123
+ quantity2.kind = stripWrapping(qt[k++]);
11239
11124
  } else if (qc === "unit") {
11240
- quantity.unit = stripWrapping(qt[k++]);
11125
+ quantity2.unit = stripWrapping(qt[k++]);
11241
11126
  } else {
11242
11127
  unwrapBlock(qt[k++]);
11243
11128
  }
11244
11129
  }
11245
- limit.quantity = quantity;
11130
+ limit.quantity = quantity2;
11246
11131
  } else if (cmd === "accepts") {
11247
11132
  limit.accepts = readAccepts(unwrapBlock(t[i++]));
11248
11133
  } else if (cmd === "acceptance") {
@@ -12683,6 +12568,8 @@ function parseDimension(id, block) {
12683
12568
  dim.source = readSource(unwrapBlock(t[i++]));
12684
12569
  } else if (cmd === "values") {
12685
12570
  dim.values = parseDimensionValues(unwrapBlock(t[i++]));
12571
+ } else if (cmd === "payload_class") {
12572
+ dim.payloadClass = stripColon(stripWrapping(t[i++]));
12686
12573
  } else if (cmd === "values_of") {
12687
12574
  dim.valuesOf = stripWrapping(t[i++]);
12688
12575
  } else if (cmd === "ref") {
@@ -12791,6 +12678,9 @@ function dumpDimension(d, indent) {
12791
12678
  if (d.description) {
12792
12679
  out += inner + 'description "' + escapeString(d.description) + '"\n';
12793
12680
  }
12681
+ if (d.payloadClass) {
12682
+ out += inner + "payload_class " + d.payloadClass + "\n";
12683
+ }
12794
12684
  out += dumpSource2("reference", d.source, inner);
12795
12685
  if (d.valuesOf) {
12796
12686
  out += inner + "values_of " + d.valuesOf + "\n";
@@ -13188,6 +13078,8 @@ var parseAttributeDefinition = function(id, data) {
13188
13078
  result.note = stripWrapping(t[i++]);
13189
13079
  } else if (cmd === "irdi") {
13190
13080
  result.irdi = stripWrapping(t[i++]);
13081
+ } else if (cmd === "class") {
13082
+ result.classRef = stripColon(stripWrapping(t[i++]));
13191
13083
  } else if (cmd === "derived") {
13192
13084
  result.derived = stripWrapping(t[i++]);
13193
13085
  } else if (cmd === "ref") {
@@ -13267,6 +13159,9 @@ var dumpAttributeDefinition = function(a) {
13267
13159
  if (a.irdi) {
13268
13160
  out += ' irdi "' + escapeString(a.irdi) + '"\n';
13269
13161
  }
13162
+ if (a.classRef) {
13163
+ out += " class " + a.classRef + "\n";
13164
+ }
13270
13165
  if (a.derived) {
13271
13166
  out += ' derived "' + escapeString(a.derived) + '"\n';
13272
13167
  }
@@ -14410,6 +14305,16 @@ function parseInstanceHas(block, result) {
14410
14305
  }
14411
14306
  }
14412
14307
  }
14308
+ function readQuantity2(tokens) {
14309
+ if (tokens.length === 0) {
14310
+ return { value: "" };
14311
+ }
14312
+ const first = stripWrapping(tokens[0]);
14313
+ if (tokens.length === 1) {
14314
+ return { value: first };
14315
+ }
14316
+ return { value: first, unit: tokens.slice(1).map(stripWrapping).join(" ") };
14317
+ }
14413
14318
  var parseInstance = function(id, data) {
14414
14319
  const result = {
14415
14320
  id,
@@ -14431,6 +14336,13 @@ var parseInstance = function(id, data) {
14431
14336
  }
14432
14337
  if (cmd === "of") {
14433
14338
  result.of = stripWrapping(t[i++]);
14339
+ } else if (t[i] === "=" && i + 1 < t.length) {
14340
+ i++;
14341
+ const valueTokens = [];
14342
+ while (i < t.length && t[i] !== "}" && !(i + 1 < t.length && t[i + 1] === "=")) {
14343
+ valueTokens.push(t[i++]);
14344
+ }
14345
+ result.has.attributes[cmd] = readQuantity2(valueTokens);
14434
14346
  } else if (cmd === "level") {
14435
14347
  result.level = stripWrapping(t[i++]);
14436
14348
  } else if (cmd === "model") {
@@ -15048,6 +14960,127 @@ var dumpEvaluationProfile = function(p) {
15048
14960
  return out;
15049
14961
  };
15050
14962
 
14963
+ // src/ser-des/config/attestation.ts
14964
+ var parseAttestation = (id, data) => {
14965
+ const a = {
14966
+ id,
14967
+ subject: "",
14968
+ promises: "",
14969
+ basis: [],
14970
+ authority: { role: "", name: "" },
14971
+ statement: "",
14972
+ limits: [],
14973
+ claims: [],
14974
+ referenceIds: []
14975
+ };
14976
+ forEachEntry(
14977
+ data,
14978
+ (keyword, value) => {
14979
+ if (keyword === "subject") {
14980
+ a.subject = stripWrapping(stripColon(value()));
14981
+ } else if (keyword === "promises") {
14982
+ a.promises = stripWrapping(stripColon(value()));
14983
+ } else if (keyword === "basis") {
14984
+ const kind = stripWrapping(stripColon(value()));
14985
+ const eid = stripWrapping(value());
14986
+ a.basis.push({ kind, id: eid });
14987
+ } else if (keyword === "authority") {
14988
+ const role = stripWrapping(stripColon(value()));
14989
+ const name = stripWrapping(value());
14990
+ a.authority = { role, name };
14991
+ } else if (keyword === "statement") {
14992
+ a.statement = stripWrapping(value());
14993
+ } else if (keyword === "limits") {
14994
+ forEachEntry(
14995
+ unwrapBlock(value()),
14996
+ (label, text) => {
14997
+ const limit = {
14998
+ label: stripColon(label),
14999
+ text: stripWrapping(text())
15000
+ };
15001
+ a.limits.push(limit);
15002
+ return true;
15003
+ },
15004
+ { construct: "attestation", id }
15005
+ );
15006
+ } else if (keyword === "claims") {
15007
+ forEachEntry(
15008
+ unwrapBlock(value()),
15009
+ (promise, claimValue) => {
15010
+ const claim = {
15011
+ promise: stripColon(promise),
15012
+ declared: "",
15013
+ validatedBy: ""
15014
+ };
15015
+ forEachEntry(
15016
+ unwrapBlock(claimValue()),
15017
+ (k2, v2) => {
15018
+ if (k2 === "declared") {
15019
+ claim.declared = stripWrapping(stripColon(v2()));
15020
+ } else if (k2 === "validated_by") {
15021
+ claim.validatedBy = stripWrapping(stripColon(v2()));
15022
+ } else {
15023
+ return false;
15024
+ }
15025
+ return true;
15026
+ },
15027
+ { construct: "attestation", id }
15028
+ );
15029
+ a.claims.push(claim);
15030
+ return true;
15031
+ },
15032
+ { construct: "attestation", id }
15033
+ );
15034
+ } else {
15035
+ return false;
15036
+ }
15037
+ return true;
15038
+ },
15039
+ { construct: "attestation", id }
15040
+ );
15041
+ return (ctx) => {
15042
+ ctx.attestations[id] = a;
15043
+ return ctx;
15044
+ };
15045
+ };
15046
+ var dumpAttestation = function(a) {
15047
+ let out = "attestation " + dumpBareSafe(a.id) + " {\n";
15048
+ if (a.subject) {
15049
+ out += " subject " + dumpBareSafe(a.subject) + "\n";
15050
+ }
15051
+ if (a.promises) {
15052
+ out += " promises " + dumpBareSafe(a.promises) + "\n";
15053
+ }
15054
+ for (const b of a.basis) {
15055
+ out += " basis " + dumpBareSafe(b.kind) + ' "' + b.id.replace(/"/g, '\\"') + '"\n';
15056
+ }
15057
+ if (a.authority.role || a.authority.name) {
15058
+ out += " authority " + dumpBareSafe(a.authority.role) + ' "' + a.authority.name.replace(/"/g, '\\"') + '"\n';
15059
+ }
15060
+ if (a.statement) {
15061
+ out += ' statement "' + a.statement.replace(/"/g, '\\"') + '"\n';
15062
+ }
15063
+ if (a.limits.length > 0) {
15064
+ out += " limits {\n";
15065
+ for (const l of a.limits) {
15066
+ out += " " + dumpBareSafe(l.label) + ' "' + l.text.replace(/"/g, '\\"') + '"\n';
15067
+ }
15068
+ out += " }\n";
15069
+ }
15070
+ if (a.claims.length > 0) {
15071
+ out += " claims {\n";
15072
+ for (const c of a.claims) {
15073
+ out += " " + dumpBareSafe(c.promise) + " {\n";
15074
+ out += " declared " + dumpBareSafe(c.declared) + "\n";
15075
+ out += " validated_by " + dumpBareSafe(c.validatedBy) + "\n";
15076
+ out += " }\n";
15077
+ }
15078
+ out += " }\n";
15079
+ }
15080
+ out += "}\n";
15081
+ return out;
15082
+ };
15083
+
15051
15084
  // src/ser-des/config/certificateTemplate.ts
15052
15085
  var CERTIFICATE_OBLIGATIONS = ["mandatory", "optional"];
15053
15086
  function readIdList6(block) {
@@ -15345,6 +15378,8 @@ var parseArtifactDefinition = function(id, data) {
15345
15378
  result.description = stripWrapping(t[i++]);
15346
15379
  } else if (cmd === "content_contract") {
15347
15380
  result.contentContract = parseContentContract(unwrapBlock(t[i++]));
15381
+ } else if (cmd === "contract_from") {
15382
+ result.contractFrom = stripColon(stripWrapping(t[i++]));
15348
15383
  } else if (cmd === "produced_when") {
15349
15384
  const kind = stripWrapping(t[i++] ?? "");
15350
15385
  if (kind === "per_interval") {
@@ -15400,6 +15435,9 @@ var dumpArtifactDefinition = function(d) {
15400
15435
  if (d.description) {
15401
15436
  out += ' description "' + escapeString(d.description) + '"\n';
15402
15437
  }
15438
+ if (d.contractFrom) {
15439
+ out += " contract_from " + d.contractFrom + "\n";
15440
+ }
15403
15441
  const c = d.contentContract;
15404
15442
  const hasContract = c.fields.length > 0 || c.structure || c.media.length > 0;
15405
15443
  if (hasContract) {
@@ -18403,6 +18441,68 @@ var dumpDecisionRule = function(r) {
18403
18441
  return out;
18404
18442
  };
18405
18443
 
18444
+ // src/ser-des/config/processSequence.ts
18445
+ function parseProcessSequence(block) {
18446
+ return tokenizePackage(block).map(stripColon).map(stripWrapping).filter((s) => s.length > 0);
18447
+ }
18448
+ function parseProcessRegister(id, block) {
18449
+ const register = {
18450
+ id,
18451
+ label: "",
18452
+ clause: "",
18453
+ maintainer: "",
18454
+ published: "",
18455
+ entries: ""
18456
+ };
18457
+ forEachEntry(
18458
+ block,
18459
+ (keyword, value) => {
18460
+ if (keyword === "label") {
18461
+ register.label = stripWrapping(value());
18462
+ } else if (keyword === "clause") {
18463
+ register.clause = stripWrapping(value());
18464
+ } else if (keyword === "maintainer") {
18465
+ register.maintainer = stripWrapping(value());
18466
+ } else if (keyword === "published") {
18467
+ register.published = stripWrapping(value());
18468
+ } else if (keyword === "entries") {
18469
+ register.entries = stripWrapping(value());
18470
+ } else {
18471
+ return false;
18472
+ }
18473
+ return true;
18474
+ },
18475
+ { construct: "process_model register", id }
18476
+ );
18477
+ return register;
18478
+ }
18479
+ function dumpProcessSequence(sequence) {
18480
+ if (sequence.length === 0) {
18481
+ return "";
18482
+ }
18483
+ return "sequence { " + sequence.map(dumpBareSafe).join(" ") + " }";
18484
+ }
18485
+ function dumpProcessRegister(r, indent) {
18486
+ let out = indent + "register " + dumpBareSafe(r.id) + " {\n";
18487
+ if (r.label) {
18488
+ out += indent + ' label "' + escapeString(r.label) + '"\n';
18489
+ }
18490
+ if (r.clause) {
18491
+ out += indent + ' clause "' + escapeString(r.clause) + '"\n';
18492
+ }
18493
+ if (r.maintainer) {
18494
+ out += indent + " maintainer " + dumpBareSafe(r.maintainer) + "\n";
18495
+ }
18496
+ if (r.published) {
18497
+ out += indent + ' published "' + escapeString(r.published) + '"\n';
18498
+ }
18499
+ if (r.entries) {
18500
+ out += indent + ' entries "' + escapeString(r.entries) + '"\n';
18501
+ }
18502
+ out += indent + "}\n";
18503
+ return out;
18504
+ }
18505
+
18406
18506
  // src/ser-des/config/documentModule.ts
18407
18507
  var parseDocumentModule = (id, data) => {
18408
18508
  const module = {
@@ -18737,237 +18837,9 @@ var dumpPartAnnex = function(a) {
18737
18837
  return out;
18738
18838
  };
18739
18839
 
18740
- // src/ser-des/config/storyline.ts
18741
- function readRecordValue(token) {
18742
- if (token.startsWith("{")) {
18743
- return tokenize(unwrapBlock(token)).filter((s) => s.length > 0).map(coerceValueToken);
18744
- }
18745
- return coerceValueToken(token);
18746
- }
18747
- function readRecordFields(block) {
18748
- const fields = {};
18749
- const t = tokenize(block);
18750
- let i = 0;
18751
- while (i < t.length) {
18752
- const key = t[i++];
18753
- if (i >= t.length) {
18754
- break;
18755
- }
18756
- fields[stripColon(key)] = readRecordValue(t[i++]);
18757
- }
18758
- return fields;
18759
- }
18760
- function dumpRecordFields(fields, indent) {
18761
- let out = "";
18762
- for (const [key, value] of Object.entries(fields)) {
18763
- if (Array.isArray(value)) {
18764
- out += indent + key + " { " + value.map(dumpScalarToken).join(" ") + " }\n";
18765
- } else {
18766
- out += indent + key + " " + dumpScalarToken(value) + "\n";
18767
- }
18768
- }
18769
- return out;
18770
- }
18771
- function parseParticipants(block) {
18772
- const sections = [];
18773
- const t = tokenize(block);
18774
- let i = 0;
18775
- while (i < t.length) {
18776
- const sid = stripWrapping(t[i++]);
18777
- if (i >= t.length || !t[i].startsWith("{")) {
18778
- break;
18779
- }
18780
- const section = { id: sid, entries: [] };
18781
- const st = tokenize(unwrapBlock(t[i++]));
18782
- let j = 0;
18783
- while (j < st.length) {
18784
- const eid = stripWrapping(st[j++]);
18785
- if (j >= st.length || !st[j].startsWith("{")) {
18786
- break;
18787
- }
18788
- section.entries.push({
18789
- id: eid,
18790
- fields: readRecordFields(unwrapBlock(st[j++]))
18791
- });
18792
- }
18793
- sections.push(section);
18794
- }
18795
- return sections;
18796
- }
18797
- var parseDemoWorld = (id, data) => {
18798
- const world = {
18799
- id,
18800
- standard: "",
18801
- description: "",
18802
- participants: []
18803
- };
18804
- forEachEntry(
18805
- data,
18806
- (keyword, value) => {
18807
- if (keyword === "standard") {
18808
- world.standard = stripWrapping(value());
18809
- } else if (keyword === "description") {
18810
- world.description = stripWrapping(value());
18811
- } else if (keyword === "participants") {
18812
- world.participants = parseParticipants(unwrapBlock(value()));
18813
- } else {
18814
- return false;
18815
- }
18816
- return true;
18817
- },
18818
- { construct: "demo_world", id }
18819
- );
18820
- return (ctx) => {
18821
- ctx.demoWorlds[id] = world;
18822
- return ctx;
18823
- };
18824
- };
18825
- var dumpDemoWorld = function(w) {
18826
- let out = "demo_world " + w.id + " {\n";
18827
- if (w.standard) {
18828
- out += " standard " + dumpBareSafe(w.standard) + "\n";
18829
- }
18830
- if (w.description) {
18831
- out += ' description "' + escapeString(w.description) + '"\n';
18832
- }
18833
- if (w.participants.length > 0) {
18834
- out += " participants {\n";
18835
- for (const s of w.participants) {
18836
- out += " " + dumpBareSafe(s.id) + " {\n";
18837
- for (const e of s.entries) {
18838
- out += " " + dumpBareSafe(e.id) + " {\n";
18839
- out += dumpRecordFields(e.fields, " ");
18840
- out += " }\n";
18841
- }
18842
- out += " }\n";
18843
- }
18844
- out += " }\n";
18845
- }
18846
- out += "}\n";
18847
- return out;
18848
- };
18849
- function parseSubjectEntries(block) {
18850
- const entries = [];
18851
- const t = tokenize(block);
18852
- let i = 0;
18853
- while (i < t.length) {
18854
- const kind = stripWrapping(t[i++]);
18855
- if (i >= t.length) {
18856
- break;
18857
- }
18858
- const eid = stripWrapping(t[i++]);
18859
- const entry = { kind, id: eid, fields: {} };
18860
- if (i < t.length && t[i].startsWith("{")) {
18861
- entry.fields = readRecordFields(unwrapBlock(t[i++]));
18862
- }
18863
- entries.push(entry);
18864
- }
18865
- return entries;
18866
- }
18867
- var parseStoryline = (id, data) => {
18868
- const storyline = {
18869
- id,
18870
- name: "",
18871
- idPrefix: "",
18872
- party: { laboratory: "", authority: "" },
18873
- subject: [],
18874
- records: [],
18875
- notes: []
18876
- };
18877
- forEachEntry(
18878
- data,
18879
- (keyword, value, peek) => {
18880
- if (keyword === "name") {
18881
- storyline.name = stripWrapping(value());
18882
- } else if (keyword === "id_prefix") {
18883
- storyline.idPrefix = stripWrapping(value());
18884
- } else if (keyword === "party") {
18885
- const pt = tokenize(unwrapBlock(value()));
18886
- for (let j = 0; j + 1 < pt.length; j += 2) {
18887
- if (pt[j] === "laboratory") {
18888
- storyline.party.laboratory = stripWrapping(pt[j + 1]);
18889
- } else if (pt[j] === "authority") {
18890
- storyline.party.authority = stripWrapping(pt[j + 1]);
18891
- }
18892
- }
18893
- } else if (keyword === "subject") {
18894
- storyline.subject = parseSubjectEntries(unwrapBlock(value()));
18895
- } else if (keyword === "record") {
18896
- const store = stripWrapping(value());
18897
- const idHead = peek();
18898
- if (idHead === void 0 || idHead.startsWith("{")) {
18899
- throw new Error(
18900
- `Parsing error: storyline. ID ${id}: record ${store} is missing its id and block`
18901
- );
18902
- }
18903
- const rid = stripWrapping(value());
18904
- const blockHead = peek();
18905
- if (blockHead === void 0 || !blockHead.startsWith("{")) {
18906
- throw new Error(
18907
- `Parsing error: storyline. ID ${id}: record ${store} ${rid} is missing its block`
18908
- );
18909
- }
18910
- storyline.records.push({
18911
- store,
18912
- id: rid,
18913
- fields: readRecordFields(unwrapBlock(value()))
18914
- });
18915
- } else if (keyword === "note") {
18916
- storyline.notes.push(stripWrapping(value()));
18917
- } else {
18918
- return false;
18919
- }
18920
- return true;
18921
- },
18922
- { construct: "storyline", id }
18923
- );
18924
- return (ctx) => {
18925
- ctx.storylines[id] = storyline;
18926
- return ctx;
18927
- };
18928
- };
18929
- var dumpStoryline = function(s) {
18930
- let out = "storyline " + s.id + " {\n";
18931
- if (s.name) {
18932
- out += ' name "' + escapeString(s.name) + '"\n';
18933
- }
18934
- if (s.idPrefix) {
18935
- out += " id_prefix " + dumpBareSafe(s.idPrefix) + "\n";
18936
- }
18937
- if (s.party.laboratory || s.party.authority) {
18938
- out += " party {";
18939
- if (s.party.laboratory) {
18940
- out += " laboratory " + dumpBareSafe(s.party.laboratory);
18941
- }
18942
- if (s.party.authority) {
18943
- out += " authority " + dumpBareSafe(s.party.authority);
18944
- }
18945
- out += " }\n";
18946
- }
18947
- if (s.subject.length > 0) {
18948
- out += " subject {\n";
18949
- for (const e of s.subject) {
18950
- out += " " + dumpBareSafe(e.kind) + " " + dumpBareSafe(e.id) + " {\n";
18951
- out += dumpRecordFields(e.fields, " ");
18952
- out += " }\n";
18953
- }
18954
- out += " }\n";
18955
- }
18956
- for (const r of s.records) {
18957
- out += " record " + dumpBareSafe(r.store) + " " + dumpBareSafe(r.id) + " {\n";
18958
- out += dumpRecordFields(r.fields, " ");
18959
- out += " }\n";
18960
- }
18961
- for (const n of s.notes) {
18962
- out += ' note "' + escapeString(n) + '"\n';
18963
- }
18964
- out += "}\n";
18965
- return out;
18966
- };
18967
-
18968
- // src/ser-des/config/index.ts
18969
- function defineConstruct(def) {
18970
- return def;
18840
+ // src/ser-des/config/index.ts
18841
+ function defineConstruct(def) {
18842
+ return def;
18971
18843
  }
18972
18844
  var CONSTRUCTS = [
18973
18845
  defineConstruct({
@@ -18995,33 +18867,12 @@ var CONSTRUCTS = [
18995
18867
  }),
18996
18868
  // The abstract-process model's file-level home (smart TODO.roadmap/40
18997
18869
  // batch 2): the pipeline sequence + the participant/expert registers.
18998
- defineConstruct({
18999
- keyword: "process_model",
19000
- field: "processModels",
19001
- takesID: true,
19002
- parse: parseProcessModel,
19003
- dump: dumpProcessModel
19004
- }),
19005
18870
  // The certification workflow step register (smart TODO.roadmap/40
19006
18871
  // batch 3) — process-adjacent but NOT the abstract-process machinery;
19007
18872
  // the rec-overlay deep merge (OVERLAY_DEEP_MERGE_FIELDS) lands here.
19008
- defineConstruct({
19009
- keyword: "workflow_config",
19010
- field: "workflowConfigs",
19011
- takesID: true,
19012
- parse: parseWorkflowConfig,
19013
- dump: dumpWorkflowConfig
19014
- }),
19015
18873
  // The named pipeline stage (smart TODO.roadmap/40 batch 5) — groups
19016
18874
  // the workflow constructs per stage; the members-resolve discipline
19017
18875
  // is C142's.
19018
- defineConstruct({
19019
- keyword: "workflow_stage",
19020
- field: "workflowStages",
19021
- takesID: true,
19022
- parse: parseWorkflowStage,
19023
- dump: dumpWorkflowStage
19024
- }),
19025
18876
  defineConstruct({
19026
18877
  keyword: "approval",
19027
18878
  field: "approvals",
@@ -19197,6 +19048,16 @@ var CONSTRUCTS = [
19197
19048
  // The certificate rendering contract (smart TODO.roadmap/40 batch 3)
19198
19049
  // — form-adjacent (the certificate is the issuing-side document);
19199
19050
  // singleton per package.
19051
+ // The attestation (the typed kernel; clause 19) — the claim that a
19052
+ // third party has verified a subject against a declared promise set,
19053
+ // carrying the lineage of the claims (C150/C151 check the references).
19054
+ defineConstruct({
19055
+ keyword: "attestation",
19056
+ field: "attestations",
19057
+ takesID: true,
19058
+ parse: parseAttestation,
19059
+ dump: dumpAttestation
19060
+ }),
19200
19061
  defineConstruct({
19201
19062
  keyword: "certificate_template",
19202
19063
  field: "certificateTemplates",
@@ -19586,24 +19447,6 @@ var CONSTRUCTS = [
19586
19447
  parse: parsePartAnnex,
19587
19448
  dump: dumpPartAnnex
19588
19449
  }),
19589
- // The demo seeds (smart TODO.roadmap/40 batch 4) — one demo_world per
19590
- // package (file-level metadata + the OPEN participants registry) and
19591
- // one storyline per flow; the record-value sub-grammar follows the
19592
- // quantity.ts dumpScalarToken conventions.
19593
- defineConstruct({
19594
- keyword: "demo_world",
19595
- field: "demoWorlds",
19596
- takesID: true,
19597
- parse: parseDemoWorld,
19598
- dump: dumpDemoWorld
19599
- }),
19600
- defineConstruct({
19601
- keyword: "storyline",
19602
- field: "storylines",
19603
- takesID: true,
19604
- parse: parseStoryline,
19605
- dump: dumpStoryline
19606
- }),
19607
19450
  // Primmel v3 twin interface (TODO.roadmap/32 — doctrine ch. 14 §14.4):
19608
19451
  // the connector-profile registry. Endpoints and serve bindings are NOT
19609
19452
  // top-level constructs — they are subject anatomy slots (is.endpoints /
@@ -19665,7 +19508,12 @@ function buildParserConfig(constructs) {
19665
19508
  if (!c.field) {
19666
19509
  continue;
19667
19510
  }
19668
- const entry = { takesID: c.takesID, parse: c.parse, field: c.field };
19511
+ const entry = {
19512
+ takesID: c.takesID,
19513
+ parse: c.parse,
19514
+ field: c.field,
19515
+ ...c.deprecated ? { deprecated: c.deprecated } : {}
19516
+ };
19669
19517
  out[c.keyword] = entry;
19670
19518
  for (const alias of c.aliases ?? []) {
19671
19519
  out[alias] = entry;
@@ -19948,7 +19796,6 @@ var MERGE_FIELDS = [
19948
19796
  "processes",
19949
19797
  // The abstract-process models (smart TODO.roadmap/40 batch 2) compose
19950
19798
  // like the processes they sequence, with uses-no-redefine semantics.
19951
- "processModels",
19952
19799
  "pages",
19953
19800
  "gateways",
19954
19801
  "regs",
@@ -20002,6 +19849,7 @@ var MERGE_FIELDS = [
20002
19849
  // like the subject anatomy they extend, with uses-no-redefine
20003
19850
  // semantics.
20004
19851
  "promiseSets",
19852
+ "attestations",
20005
19853
  // The applicant-facing documentation register (smart TODO.roadmap/40
20006
19854
  // batch 3) composes with uses-no-redefine semantics.
20007
19855
  "applicationDeclarations",
@@ -20015,10 +19863,8 @@ var MERGE_FIELDS = [
20015
19863
  "certificateTemplates",
20016
19864
  // The certification workflow step register (smart TODO.roadmap/40
20017
19865
  // batch 3) — the rec-overlay deep merge (OVERLAY_DEEP_MERGE_FIELDS).
20018
- "workflowConfigs",
20019
19866
  // The named pipeline stages (smart TODO.roadmap/40 batch 5) compose
20020
19867
  // with uses-no-redefine semantics.
20021
- "workflowStages",
20022
19868
  // The verification pathways (smart TODO.roadmap/40 batch 3) compose
20023
19869
  // with uses-no-redefine semantics.
20024
19870
  "verificationPathways",
@@ -20070,8 +19916,6 @@ var MERGE_FIELDS = [
20070
19916
  "documentModules",
20071
19917
  "informativeAnnexes",
20072
19918
  "partAnnexes",
20073
- "demoWorlds",
20074
- "storylines",
20075
19919
  // The pre-existing drift closed (the packages-as-SSOT epic): these
20076
19920
  // collections existed as constructs but were never merged, so `uses`
20077
19921
  // composition silently dropped them — comments, predicates, the
@@ -20094,13 +19938,17 @@ var OVERLAY_DEEP_MERGE_FIELDS = /* @__PURE__ */ new Set([
20094
19938
  // The workflow step register (B3.7): a rec package's overlay-marked
20095
19939
  // workflow_config merges field-wise into the core skeleton (steps
20096
19940
  // union by id in first-seen order, gates append as a union).
20097
- "workflowConfigs",
20098
19941
  // The OIML-CS test-report checklist (B3.10): a rec package's
20099
19942
  // overlay-marked test_report_checklist merges field-wise into the
20100
19943
  // oiml-cs base — entry scalars land IN PLACE (the base order
20101
19944
  // survives; append-at-end would reorder the composition-point
20102
19945
  // entries to the tail).
20103
- "testReportChecklists"
19946
+ "testReportChecklists",
19947
+ // The entity classes (the smart core's #data plane): a rec
19948
+ // package's overlay-marked class merges field-wise into the core's
19949
+ // — attributes union by id in first-seen order (the rec's added
19950
+ // fields land beside the core's), scalars override.
19951
+ "dataclasses"
20104
19952
  ]);
20105
19953
  function isPlainRecord(v) {
20106
19954
  return typeof v === "object" && v !== null && !Array.isArray(v);
@@ -20262,7 +20110,7 @@ function composePackage(rootDir, options, rootManifest, withProvenance = false)
20262
20110
  )) {
20263
20111
  const prior = pm.get(key);
20264
20112
  if (prior !== void 0) {
20265
- const isOverlay = typeof value === "object" && value !== null && value.overlay === true && (field === "terms" || OVERLAY_DEEP_MERGE_FIELDS.has(field));
20113
+ const isOverlay = typeof value === "object" && value !== null && value.overlay === true && (field === "terms" || field === "processes" || OVERLAY_DEEP_MERGE_FIELDS.has(field));
20266
20114
  if (!isOverlay) {
20267
20115
  throw new CompositionError(
20268
20116
  "uses-no-redefine",
@@ -21027,10 +20875,8 @@ var TIER_BY_FIELD = {
21027
20875
  certificateTemplates: "secondary",
21028
20876
  // The certification workflow step register (smart TODO.roadmap/40
21029
20877
  // batch 3) — operational wiring, tertiary.
21030
- workflowConfigs: "tertiary",
21031
20878
  // The named pipeline stages (smart TODO.roadmap/40 batch 5) —
21032
20879
  // operational wiring, tertiary.
21033
- workflowStages: "tertiary",
21034
20880
  // The verification pathways (smart TODO.roadmap/40 batch 3) —
21035
20881
  // operational wiring, tertiary.
21036
20882
  verificationPathways: "tertiary",
@@ -21070,7 +20916,6 @@ var TIER_BY_FIELD = {
21070
20916
  // Process models (smart TODO.roadmap/40 batch 2) are tertiary beside
21071
20917
  // processes: the pipeline sequence/registers are the abstract-process
21072
20918
  // model's file-level furniture.
21073
- processModels: "tertiary",
21074
20919
  // Document modules (smart TODO.roadmap/40 batch 2) are tertiary beside
21075
20920
  // processes: the module is the pipeline's document-level furniture.
21076
20921
  documentModules: "tertiary",
@@ -21096,8 +20941,6 @@ var TIER_BY_FIELD = {
21096
20941
  // the model.
21097
20942
  informativeAnnexes: "cross-cutting",
21098
20943
  partAnnexes: "cross-cutting",
21099
- demoWorlds: "tertiary",
21100
- storylines: "tertiary",
21101
20944
  // Invariants (smart gap-close E9) are cross-cutting beside notes: the
21102
20945
  // typed replacement for the note-family encoding — doctrine about the
21103
20946
  // model, not machinery inside it (the enforcement claims point at the
@@ -22075,6 +21918,29 @@ var CHECK_RULES = [
22075
21918
  "normal",
22076
21919
  "TODO.roadmap/03"
22077
21920
  ),
21921
+ // ── the power-type discipline (the reconfiguration phase 8; the CDD
21922
+ // family's central modelling relationship, and the CDDAL interop
21923
+ // requirement): every instance can serve as the definition of further
21924
+ // instantiation. C155 keeps the of-chain coherent — an instance that
21925
+ // instantiates another instance carries no upward subject-chain link,
21926
+ // and the of-graph is acyclic. C156 reaches the definition side: a
21927
+ // class's extends names a class or an instance.
21928
+ R(
21929
+ "C155",
21930
+ "power-type-chain",
21931
+ "instantiation",
21932
+ "error",
21933
+ "normal",
21934
+ "the reconfiguration phase 8 (TODO.reconfigure/09-subjects-twins-attestation.md, the power-type clause)"
21935
+ ),
21936
+ R(
21937
+ "C156",
21938
+ "class-extends-resolves",
21939
+ "instantiation",
21940
+ "warning",
21941
+ "normal",
21942
+ "the reconfiguration phase 8 (TODO.reconfigure/09-subjects-twins-attestation.md, the power-type clause)"
21943
+ ),
22078
21944
  // ── mapping (TODO.roadmap/04) ─────────────────────────────────────
22079
21945
  R(
22080
21946
  "C21",
@@ -22301,28 +22167,6 @@ var CHECK_RULES = [
22301
22167
  "normal",
22302
22168
  "smart TODO.roadmap/40 batch 4 (the packages-as-SSOT epic)"
22303
22169
  ),
22304
- // C129 (smart TODO.roadmap/40 batch 4; the packages-as-SSOT epic): the
22305
- // demo-seed shapes — the storyline's id_prefix pattern (register-free),
22306
- // the party laboratory/authority → the demo_world participant seeds
22307
- // (gated on that register), the record stores → the entity-class stores
22308
- // (gated), and the in-construct record cross-references (a record field
22309
- // keyed by a sibling record's store names a sibling of that store —
22310
- // ungated). Field-level discipline stays app-side.
22311
- R(
22312
- "C129",
22313
- "storyline-shape",
22314
- "composition",
22315
- "error",
22316
- "normal",
22317
- "smart TODO.roadmap/40 batch 4 (the packages-as-SSOT epic)"
22318
- ),
22319
- // C130 (smart TODO.roadmap/40 batch 3; the packages-as-SSOT epic): the
22320
- // identity_slot / aspect registers — the ≥1-presentation shape leg, the
22321
- // aspect reference legs (term_ref → term, component → instrument
22322
- // component, attribute → attribute_definition, contains → identity path
22323
- // OR bare attribute/dimension id), and the R28 bind-path consumer leg
22324
- // (model.identity.<slot> / model.aspects.<id> in requirement/test
22325
- // binds_to), each leg gated on its target register (the C58 doctrine).
22326
22170
  R(
22327
22171
  "C130",
22328
22172
  "identity-and-aspect-references",
@@ -23109,6 +22953,75 @@ var CHECK_RULES = [
23109
22953
  "normal",
23110
22954
  "smart TODO.twin-demo/03 (the model-drive bindings)"
23111
22955
  ),
22956
+ // ── the deprecation report (phase 2 of the reconfiguration): a
22957
+ // construct whose definition carries a migration note warns on every
22958
+ // use; the retirement phase removes the constructs and the rule
22959
+ // burns down to empty.
22960
+ R(
22961
+ "C154",
22962
+ "construct-deprecated",
22963
+ "base",
22964
+ "warning",
22965
+ "normal",
22966
+ "the reconfiguration phase 2 (TODO.reconfigure/09-migration-plan.md)"
22967
+ ),
22968
+ // ── the attestation (the typed kernel, clause 19): the claim that a
22969
+ // third party has verified a subject against a declared promise set.
22970
+ // C150 resolves its subject, promise set, basis, authority, and claim
22971
+ // references; C151 requires the claim lineage — a mandatory
22972
+ // characteristic is carried by lineage, never restated.
22973
+ // ── the typed kernel R3 (the reconfiguration): the closed-derivation
22974
+ // rule. A derivation expression names only declared definitions —
22975
+ // calculations, tables, symbols, measurements, and attributes — and
22976
+ // the checker rejects anything else, naming the missing declaration.
22977
+ R(
22978
+ "C149",
22979
+ "closed-derivation-references-declared",
22980
+ "quantities",
22981
+ "error",
22982
+ "normal",
22983
+ "the typed kernel R3 (TODO.reconfigure/03-typed-kernel.md)"
22984
+ ),
22985
+ R(
22986
+ "C150",
22987
+ "attestation-references-resolve",
22988
+ "attestation",
22989
+ "error",
22990
+ "normal",
22991
+ "the typed kernel clause 19 (TODO.reconfigure/07-subjects-twins-attestation.md)"
22992
+ ),
22993
+ R(
22994
+ "C151",
22995
+ "attestation-claim-lineage",
22996
+ "attestation",
22997
+ "error",
22998
+ "normal",
22999
+ "the typed kernel clause 19 (TODO.reconfigure/07-subjects-twins-attestation.md)"
23000
+ ),
23001
+ // ── the typed payload rule (the typed kernel R2, clause 10): a
23002
+ // dimension that declares payload_class types every value's
23003
+ // definition — the class resolves, the payload fields are fields of
23004
+ // that class, and every value carries its definition.
23005
+ R(
23006
+ "C152",
23007
+ "payload-typed-by-class",
23008
+ "quantities",
23009
+ "error",
23010
+ "normal",
23011
+ "the typed kernel R2 (TODO.reconfigure/03-typed-kernel.md)"
23012
+ ),
23013
+ // ── the contract-derivation facet (the typed kernel, clause 10): an
23014
+ // artifact definition whose content is the projection of declared
23015
+ // claims derives its contract; the reference resolves and never
23016
+ // combines with inline fields.
23017
+ R(
23018
+ "C153",
23019
+ "artifact-contract-derivation",
23020
+ "artifacts",
23021
+ "error",
23022
+ "normal",
23023
+ "the typed kernel clause 10 (TODO.reconfigure/07-subjects-twins-attestation.md)"
23024
+ ),
23112
23025
  // ── the per-test evaluation-formula traces (smart gap-close E11,
23113
23026
  // analysis/architecture-gaps-2026-07.md; the smart contract
23114
23027
  // data/schemas/formulas-used.yaml) ──
@@ -23456,6 +23369,50 @@ function activeRuleIds(level) {
23456
23369
  );
23457
23370
  }
23458
23371
 
23372
+ // src/instance-resolution.ts
23373
+ function classPrototype(standard, classId) {
23374
+ const classes = new Map((standard.dataclasses ?? []).map((c) => [c.id, c]));
23375
+ const instances = new Map((standard.instances ?? []).map((i) => [i.id, i]));
23376
+ const seen = /* @__PURE__ */ new Set([classId]);
23377
+ let cur = classes.get(classId);
23378
+ while (cur && cur.extends) {
23379
+ const target = cur.extends;
23380
+ if (seen.has(target)) {
23381
+ return null;
23382
+ }
23383
+ seen.add(target);
23384
+ const inst = instances.get(target);
23385
+ if (inst) {
23386
+ return inst;
23387
+ }
23388
+ cur = classes.get(target);
23389
+ }
23390
+ return null;
23391
+ }
23392
+ function delegationSuccessors(standard) {
23393
+ const out = /* @__PURE__ */ new Map();
23394
+ for (const inst of standard.instances ?? []) {
23395
+ const upward = inst.model || inst.group || inst.family;
23396
+ if (upward) {
23397
+ out.set(inst.id, upward);
23398
+ continue;
23399
+ }
23400
+ if (!inst.of) {
23401
+ continue;
23402
+ }
23403
+ const direct = (standard.instances ?? []).find((i) => i.id === inst.of);
23404
+ if (direct) {
23405
+ out.set(inst.id, direct.id);
23406
+ continue;
23407
+ }
23408
+ const prototype = classPrototype(standard, inst.of);
23409
+ if (prototype) {
23410
+ out.set(inst.id, prototype.id);
23411
+ }
23412
+ }
23413
+ return out;
23414
+ }
23415
+
23459
23416
  // src/check-allowlist.ts
23460
23417
  import { existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
23461
23418
  import { join as join2 } from "path";
@@ -24356,7 +24313,9 @@ function checkPackage(dir, options = {}) {
24356
24313
  });
24357
24314
  standard = loaded.standard;
24358
24315
  for (const i of loaded.issues) {
24359
- if (i.code === "provides-unconsumed") {
24316
+ if (i.code === "construct-deprecated") {
24317
+ warn("C154", i.message);
24318
+ } else if (i.code === "provides-unconsumed") {
24360
24319
  warn("C30", i.message);
24361
24320
  } else if (i.code === "extends-deprecated") {
24362
24321
  warn("C27", i.message);
@@ -24386,6 +24345,10 @@ function checkPackage(dir, options = {}) {
24386
24345
  issues.push(...checkDimensions(standard));
24387
24346
  issues.push(...checkReferences(standard));
24388
24347
  issues.push(...checkVerdictChains(standard));
24348
+ issues.push(...checkClosedDerivations(standard));
24349
+ issues.push(...checkAttestations(standard));
24350
+ issues.push(...checkTypedPayloads(standard));
24351
+ issues.push(...checkArtifactContracts(standard));
24389
24352
  const reqIds = new Set(
24390
24353
  (standard.requirements ?? []).map((r) => r.id)
24391
24354
  );
@@ -24395,12 +24358,11 @@ function checkPackage(dir, options = {}) {
24395
24358
  const attrIds = new Set(
24396
24359
  (standard.attributeDefinitions ?? []).map((a) => a.id)
24397
24360
  );
24361
+ const roleIds = new Set((standard.roles ?? []).map((r) => r.id));
24398
24362
  const behaviorIds = new Set(
24399
24363
  (standard.behaviors ?? []).map((b) => b.id)
24400
24364
  );
24401
- const subjectIds = new Set(
24402
- (standard.subjects ?? []).map((s) => s.id)
24403
- );
24365
+ const subjectIds = new Set((standard.subjects ?? []).map((s) => s.id));
24404
24366
  const symbolIds = new Set((standard.symbols ?? []).map((s) => s.id));
24405
24367
  const dimIds = /* @__PURE__ */ new Map();
24406
24368
  const dimCardinality = /* @__PURE__ */ new Map();
@@ -24958,7 +24920,7 @@ function checkPackage(dir, options = {}) {
24958
24920
  );
24959
24921
  for (const d of standard.artifactDefinitions ?? []) {
24960
24922
  const c = d.contentContract;
24961
- if (c.fields.length === 0) {
24923
+ if (!d.contractFrom && c.fields.length === 0) {
24962
24924
  err(
24963
24925
  "C45",
24964
24926
  `artifact definition ${d.id}: content contract declares no fields \u2014 a definition must contract SOME content (artifact-def-contract)`
@@ -25544,15 +25506,6 @@ function checkPackage(dir, options = {}) {
25544
25506
  }
25545
25507
  }
25546
25508
  }
25547
- for (const m of standard.processModels ?? []) {
25548
- const where = `process_model ${m.id}`;
25549
- for (const s of m.sequence ?? []) {
25550
- resolveProcessRef(where, "sequence", s);
25551
- }
25552
- for (const r of m.registers ?? []) {
25553
- resolveOrganAp(`${where} register ${r.id}`, "maintainer", r.maintainer);
25554
- }
25555
- }
25556
25509
  }
25557
25510
  {
25558
25511
  const OCL_CHECK = /^ocl\{[\s\S]*\}$/;
@@ -25865,7 +25818,6 @@ function checkPackage(dir, options = {}) {
25865
25818
  }
25866
25819
  }
25867
25820
  {
25868
- const roleIds = new Set((standard.roles ?? []).map((r) => r.id));
25869
25821
  const KNOWN_OUTCOMES = new Set(MONITOR_OUTCOMES);
25870
25822
  const KNOWN_ACTIONS = new Set(MONITOR_ESCALATION_ACTIONS);
25871
25823
  const KNOWN_STREAMS = new Set(MONITOR_STREAMS);
@@ -26217,6 +26169,7 @@ function checkPackage(dir, options = {}) {
26217
26169
  };
26218
26170
  const instrumentIds = new Set((standard.instruments ?? []).map((i) => i.id));
26219
26171
  const instanceIds = new Set((standard.instances ?? []).map((i) => i.id));
26172
+ const dataclassIds = new Set((standard.dataclasses ?? []).map((c) => c.id));
26220
26173
  const attrScopes = new Map(
26221
26174
  (standard.attributeDefinitions ?? []).map((a) => [a.id, a.scope])
26222
26175
  );
@@ -26321,10 +26274,43 @@ function checkPackage(dir, options = {}) {
26321
26274
  );
26322
26275
  }
26323
26276
  }
26324
- if (!subjectIds.has(inst.of) && !instrumentIds.has(inst.of)) {
26277
+ if (!subjectIds.has(inst.of) && !instrumentIds.has(inst.of) && !instanceIds.has(inst.of) && !dataclassIds.has(inst.of)) {
26325
26278
  err(
26326
26279
  "C20",
26327
- `instance ${inst.id}: of "${inst.of}" is not a declared subject or instrument (instance-of-resolves)`
26280
+ `instance ${inst.id}: of "${inst.of}" is not a declared subject, instrument, class, or instance (instance-of-resolves)`
26281
+ );
26282
+ }
26283
+ if (instanceIds.has(inst.of)) {
26284
+ const links = ["model", "group", "family"].filter(
26285
+ (k) => inst[k]
26286
+ );
26287
+ if (links.length > 0) {
26288
+ err(
26289
+ "C155",
26290
+ `instance ${inst.id}: of "${inst.of}" names an instance and the instance carries an upward ${links.join("/")} link \u2014 the power-type chain and the subject-chain profile do not mix (power-type-chain)`
26291
+ );
26292
+ }
26293
+ }
26294
+ }
26295
+ const delegation = delegationSuccessors(standard);
26296
+ const ofAdj = /* @__PURE__ */ new Map();
26297
+ for (const [from, to] of delegation) {
26298
+ if (instanceIds.has(to)) {
26299
+ ofAdj.set(from, [to]);
26300
+ }
26301
+ }
26302
+ const ofCycle = findCycle(ofAdj);
26303
+ if (ofCycle) {
26304
+ err(
26305
+ "C155",
26306
+ `the power-type of-chain is cyclic: ${ofCycle.join(" \u2192 ")} (power-type-chain)`
26307
+ );
26308
+ }
26309
+ for (const c of standard.dataclasses ?? []) {
26310
+ if (c.extends && !dataclassIds.has(c.extends) && !instanceIds.has(c.extends)) {
26311
+ warn(
26312
+ "C156",
26313
+ `class ${c.id}: extends "${c.extends}" is not a declared class or instance (class-extends-resolves)`
26328
26314
  );
26329
26315
  }
26330
26316
  }
@@ -27574,67 +27560,6 @@ function checkPackage(dir, options = {}) {
27574
27560
  }
27575
27561
  }
27576
27562
  }
27577
- {
27578
- const participantSeeds = /* @__PURE__ */ new Set();
27579
- for (const w of standard.demoWorlds ?? []) {
27580
- for (const section of w.participants ?? []) {
27581
- for (const e of section.entries ?? []) {
27582
- participantSeeds.add(e.id);
27583
- }
27584
- }
27585
- }
27586
- const entityStores = new Set(
27587
- (standard.dataclasses ?? []).map((c) => c.store).filter((s) => !!s)
27588
- );
27589
- for (const s of standard.storylines ?? []) {
27590
- const where = `storyline ${s.id}`;
27591
- if (s.idPrefix && !/^[a-z0-9-]+$/.test(s.idPrefix)) {
27592
- err(
27593
- "C129",
27594
- `${where}: id_prefix "${s.idPrefix}" does not match ^[a-z0-9-]+$ \u2014 the id-minting prefix is a lowercase slug (storyline-shape)`
27595
- );
27596
- }
27597
- if (participantSeeds.size > 0) {
27598
- for (const [slot, ref] of [
27599
- ["laboratory", s.party.laboratory],
27600
- ["authority", s.party.authority]
27601
- ]) {
27602
- if (ref && !participantSeeds.has(ref)) {
27603
- err(
27604
- "C129",
27605
- `${where}: party ${slot} "${ref}" is not a declared participant seed (storyline-shape)`
27606
- );
27607
- }
27608
- }
27609
- }
27610
- const siblingStores = /* @__PURE__ */ new Map();
27611
- for (const r of s.records ?? []) {
27612
- if (entityStores.size > 0 && !entityStores.has(r.store)) {
27613
- err(
27614
- "C129",
27615
- `${where}: record store "${r.store}" is not a declared entity-class store (storyline-shape)`
27616
- );
27617
- }
27618
- let ids = siblingStores.get(r.store);
27619
- if (!ids) {
27620
- ids = /* @__PURE__ */ new Set();
27621
- siblingStores.set(r.store, ids);
27622
- }
27623
- ids.add(r.id);
27624
- }
27625
- for (const r of s.records ?? []) {
27626
- for (const [key, value] of Object.entries(r.fields)) {
27627
- const targets = siblingStores.get(key);
27628
- if (targets !== void 0 && !Array.isArray(value) && !targets.has(String(value))) {
27629
- err(
27630
- "C129",
27631
- `${where}: record ${r.store} ${r.id}: ${key} "${String(value)}" is not a sibling ${key} record of this storyline (storyline-shape)`
27632
- );
27633
- }
27634
- }
27635
- }
27636
- }
27637
- }
27638
27563
  {
27639
27564
  const slotIds = new Set((standard.identitySlots ?? []).map((s) => s.id));
27640
27565
  const aspectIds = new Set((standard.aspects ?? []).map((a) => a.id));
@@ -28005,40 +27930,11 @@ function checkPackage(dir, options = {}) {
28005
27930
  }
28006
27931
  }
28007
27932
  {
28008
- const roleIds = new Set((standard.roles ?? []).map((r) => r.id));
28009
- const dataclassIds = /* @__PURE__ */ new Set();
27933
+ const dataclassIds2 = /* @__PURE__ */ new Set();
28010
27934
  for (const c of standard.dataclasses ?? []) {
28011
- dataclassIds.add(c.id);
27935
+ dataclassIds2.add(c.id);
28012
27936
  if (c.id.includes("#")) {
28013
- dataclassIds.add(c.id.slice(0, c.id.indexOf("#")));
28014
- }
28015
- }
28016
- const CLEAN_TOKEN = /^[A-Za-z_][A-Za-z0-9_]*$/;
28017
- for (const w of standard.workflowConfigs ?? []) {
28018
- for (const s of w.steps ?? []) {
28019
- const where = `workflow_config ${w.id}: step ${s.id}`;
28020
- if (s.actor && roleIds.size > 0 && !roleIds.has(s.actor)) {
28021
- err(
28022
- "C137",
28023
- `${where}: actor "${s.actor}" is not a declared role (workflow-config-references)`
28024
- );
28025
- }
28026
- for (const [facet, list] of [
28027
- ["inputs", s.inputs],
28028
- ["outputs", s.outputs]
28029
- ]) {
28030
- for (const entry of list) {
28031
- if (!CLEAN_TOKEN.test(entry)) {
28032
- continue;
28033
- }
28034
- if (dataclassIds.size > 0 && !dataclassIds.has(entry)) {
28035
- err(
28036
- "C137",
28037
- `${where}: ${facet} entry "${entry}" is not a declared data class (workflow-config-references)`
28038
- );
28039
- }
28040
- }
28041
- }
27937
+ dataclassIds2.add(c.id.slice(0, c.id.indexOf("#")));
28042
27938
  }
28043
27939
  }
28044
27940
  }
@@ -28275,35 +28171,6 @@ function checkPackage(dir, options = {}) {
28275
28171
  }
28276
28172
  }
28277
28173
  }
28278
- const stageApprovalIds = new Set((standard.approvals ?? []).map((a) => a.id));
28279
- const stageGatewayIds = new Set((standard.gateways ?? []).map((g) => g.id));
28280
- for (const s of standard.workflowStages ?? []) {
28281
- const where = `workflow_stage ${s.id}`;
28282
- for (const el of s.elements ?? []) {
28283
- if (gwProcessIds.size > 0 && !gwProcessIds.has(el)) {
28284
- err(
28285
- "C142",
28286
- `${where}: element "${el}" is not a declared process (gateway-edges-resolve)`
28287
- );
28288
- }
28289
- }
28290
- for (const a of s.approvals ?? []) {
28291
- if (stageApprovalIds.size > 0 && !stageApprovalIds.has(a)) {
28292
- err(
28293
- "C142",
28294
- `${where}: approval "${a}" is not a declared approval (gateway-edges-resolve)`
28295
- );
28296
- }
28297
- }
28298
- for (const g of s.gateways ?? []) {
28299
- if (stageGatewayIds.size > 0 && !stageGatewayIds.has(g)) {
28300
- err(
28301
- "C142",
28302
- `${where}: gateway "${g}" is not a declared gateway (gateway-edges-resolve)`
28303
- );
28304
- }
28305
- }
28306
- }
28307
28174
  }
28308
28175
  {
28309
28176
  const approvalRoleIds = new Set((standard.roles ?? []).map((r) => r.id));
@@ -29447,6 +29314,368 @@ function textAddressKey(item, segment) {
29447
29314
  }
29448
29315
  return false;
29449
29316
  }
29317
+ function checkArtifactContracts(standard) {
29318
+ const issues = [];
29319
+ const err = (check, message) => issues.push({ check, severity: "error", message });
29320
+ const setIds = /* @__PURE__ */ new Set();
29321
+ for (const ps of standard.promiseSets ?? []) {
29322
+ setIds.add(ps.id);
29323
+ setIds.add(`${ps.id}.promise_set`);
29324
+ }
29325
+ for (const s of standard.subjects ?? []) {
29326
+ if ((s.is?.promises ?? []).length > 0) {
29327
+ setIds.add(s.id);
29328
+ setIds.add(`${s.id}.promise_set`);
29329
+ }
29330
+ }
29331
+ for (const d of standard.artifactDefinitions ?? []) {
29332
+ if (!d.contractFrom) {
29333
+ continue;
29334
+ }
29335
+ if (!setIds.has(d.contractFrom)) {
29336
+ err(
29337
+ "C153",
29338
+ `artifact_definition ${d.id}: contract_from "${d.contractFrom}" does not resolve to a declared promise set (artifact-contract-derivation)`
29339
+ );
29340
+ }
29341
+ const c = d.contentContract;
29342
+ if (c.fields.length > 0 || c.structure || c.media.length > 0) {
29343
+ err(
29344
+ "C153",
29345
+ `artifact_definition ${d.id}: declares both contract_from and inline contract fields \u2014 the derived contract is the referenced set's projection, never a restatement (artifact-contract-derivation)`
29346
+ );
29347
+ }
29348
+ }
29349
+ return issues;
29350
+ }
29351
+ function checkTypedPayloads(standard) {
29352
+ const issues = [];
29353
+ const err = (check, message) => issues.push({ check, severity: "error", message });
29354
+ const classFields = /* @__PURE__ */ new Map();
29355
+ for (const c of standard.dataclasses ?? []) {
29356
+ classFields.set(c.id, new Set(c.attributes.map((a) => a.id)));
29357
+ }
29358
+ const instanceShape = (id) => {
29359
+ const inst = (standard.instances ?? []).find((i) => i.id === id);
29360
+ if (!inst) {
29361
+ return void 0;
29362
+ }
29363
+ let cur = inst;
29364
+ const seen = /* @__PURE__ */ new Set([cur.id]);
29365
+ while (cur.of) {
29366
+ const next = (standard.instances ?? []).find((i) => i.id === cur.of);
29367
+ if (!next || seen.has(next.id)) {
29368
+ break;
29369
+ }
29370
+ seen.add(next.id);
29371
+ cur = next;
29372
+ }
29373
+ return cur.of !== "" ? classFields.get(cur.of) : void 0;
29374
+ };
29375
+ const typedFields = (id) => classFields.get(id) ?? instanceShape(id);
29376
+ const checkDim = (owner, d) => {
29377
+ if (!d.payloadClass) {
29378
+ return;
29379
+ }
29380
+ const fields = typedFields(d.payloadClass);
29381
+ if (!fields) {
29382
+ err(
29383
+ "C152",
29384
+ `${owner} dimension ${d.id}: payload_class "${d.payloadClass}" is not a declared class (payload-typed-by-class)`
29385
+ );
29386
+ return;
29387
+ }
29388
+ for (const v of d.values) {
29389
+ const keys = Object.keys(v.payload ?? {});
29390
+ if (keys.length === 0) {
29391
+ err(
29392
+ "C152",
29393
+ `${owner} dimension ${d.id}: value ${v.id} carries no payload \u2014 a value of a payload_class dimension IS its definition (payload-typed-by-class)`
29394
+ );
29395
+ continue;
29396
+ }
29397
+ for (const key of keys) {
29398
+ if (!fields.has(key)) {
29399
+ err(
29400
+ "C152",
29401
+ `${owner} dimension ${d.id}: value ${v.id} payload field "${key}" is not a field of class "${d.payloadClass}" (payload-typed-by-class)`
29402
+ );
29403
+ }
29404
+ }
29405
+ }
29406
+ };
29407
+ for (const inst of standard.instruments ?? []) {
29408
+ for (const d of inst.dimensions ?? []) {
29409
+ checkDim(`instrument ${inst.id}`, d);
29410
+ }
29411
+ }
29412
+ for (const d of standard.dimensions ?? []) {
29413
+ checkDim("top-level", d);
29414
+ }
29415
+ for (const a of standard.attributeDefinitions ?? []) {
29416
+ if (a.classRef && !typedFields(a.classRef)) {
29417
+ err(
29418
+ "C152",
29419
+ `attribute_definition ${a.id}: class "${a.classRef}" is not a declared class (payload-typed-by-class)`
29420
+ );
29421
+ }
29422
+ }
29423
+ return issues;
29424
+ }
29425
+ function checkAttestations(standard) {
29426
+ const issues = [];
29427
+ const err = (check, message) => issues.push({ check, severity: "error", message });
29428
+ const roleIds = new Set((standard.roles ?? []).map((r) => r.id));
29429
+ const instanceIds = new Set((standard.instances ?? []).map((i) => i.id));
29430
+ const verdictIds = new Set((standard.verdicts ?? []).map((v) => v.id));
29431
+ const setViews = /* @__PURE__ */ new Map();
29432
+ for (const ps of standard.promiseSets ?? []) {
29433
+ setViews.set(ps.id, { promises: ps.promises });
29434
+ setViews.set(`${ps.id}.promise_set`, { promises: ps.promises });
29435
+ }
29436
+ for (const s of standard.subjects ?? []) {
29437
+ if ((s.is?.promises ?? []).length > 0) {
29438
+ setViews.set(s.id, { promises: s.is.promises });
29439
+ }
29440
+ }
29441
+ const resolveSet = (ref) => setViews.get(ref) ?? setViews.get(ref.split(".").slice(1).join(".")) ?? null;
29442
+ const mandatoryOf = (view) => {
29443
+ const out = /* @__PURE__ */ new Set();
29444
+ for (const p of view.promises) {
29445
+ if (p.certificate?.obligation === "mandatory") {
29446
+ out.add(p.id);
29447
+ }
29448
+ }
29449
+ return out;
29450
+ };
29451
+ for (const a of standard.attestations ?? []) {
29452
+ if (!a.subject) {
29453
+ err(
29454
+ "C150",
29455
+ `attestation ${a.id}: no subject facet (attestation-references-resolve)`
29456
+ );
29457
+ } else if (!instanceIds.has(a.subject)) {
29458
+ err(
29459
+ "C150",
29460
+ `attestation ${a.id}: subject "${a.subject}" is not a declared instance (attestation-references-resolve)`
29461
+ );
29462
+ }
29463
+ if (!a.promises) {
29464
+ err(
29465
+ "C150",
29466
+ `attestation ${a.id}: no promises facet (attestation-references-resolve)`
29467
+ );
29468
+ }
29469
+ const set = a.promises ? resolveSet(a.promises) : null;
29470
+ if (a.promises && !set) {
29471
+ err(
29472
+ "C150",
29473
+ `attestation ${a.id}: promises "${a.promises}" does not resolve to a declared promise set (attestation-references-resolve)`
29474
+ );
29475
+ }
29476
+ for (const b of a.basis) {
29477
+ if (!b.kind || !b.id) {
29478
+ err(
29479
+ "C150",
29480
+ `attestation ${a.id}: a basis entry needs an evidence kind and an id (attestation-references-resolve)`
29481
+ );
29482
+ }
29483
+ }
29484
+ if (a.authority.role && roleIds.size > 0 && !roleIds.has(a.authority.role)) {
29485
+ err(
29486
+ "C150",
29487
+ `attestation ${a.id}: authority role "${a.authority.role}" is not a declared role (attestation-references-resolve)`
29488
+ );
29489
+ }
29490
+ const carried = new Set(a.claims.map((c) => c.promise));
29491
+ for (const c of a.claims) {
29492
+ if (set && !set.promises.some((p) => p.id === c.promise)) {
29493
+ err(
29494
+ "C150",
29495
+ `attestation ${a.id}: claim "${c.promise}" is not a promise of "${a.promises}" (attestation-references-resolve)`
29496
+ );
29497
+ }
29498
+ if (!c.declared) {
29499
+ err(
29500
+ "C151",
29501
+ `attestation ${a.id}: claim "${c.promise}" carries no declaration reference (attestation-claim-lineage)`
29502
+ );
29503
+ }
29504
+ if (!c.validatedBy) {
29505
+ err(
29506
+ "C151",
29507
+ `attestation ${a.id}: claim "${c.promise}" carries no verdict reference (attestation-claim-lineage)`
29508
+ );
29509
+ } else if (verdictIds.size > 0 && !c.validatedBy.startsWith("/") && !verdictIds.has(c.validatedBy)) {
29510
+ err(
29511
+ "C150",
29512
+ `attestation ${a.id}: claim "${c.promise}" names verdict "${c.validatedBy}", which is not declared (attestation-references-resolve)`
29513
+ );
29514
+ }
29515
+ }
29516
+ if (set) {
29517
+ for (const pid of mandatoryOf(set)) {
29518
+ if (!carried.has(pid)) {
29519
+ err(
29520
+ "C151",
29521
+ `attestation ${a.id}: the mandatory promise "${pid}" of "${a.promises}" is carried by no claim \u2014 a mandatory characteristic is carried by lineage, never restated (attestation-claim-lineage)`
29522
+ );
29523
+ }
29524
+ }
29525
+ }
29526
+ }
29527
+ return issues;
29528
+ }
29529
+ var CLOSED_DERIVATION_STOP = /* @__PURE__ */ new Set([
29530
+ "self",
29531
+ "p",
29532
+ "ocl",
29533
+ "true",
29534
+ "false",
29535
+ "null",
29536
+ "undefined",
29537
+ // OCL navigation and collection operators
29538
+ "and",
29539
+ "or",
29540
+ "not",
29541
+ "implies",
29542
+ "if",
29543
+ "then",
29544
+ "else",
29545
+ "endif",
29546
+ "xor",
29547
+ "let",
29548
+ "in",
29549
+ "exists",
29550
+ "forAll",
29551
+ "select",
29552
+ "reject",
29553
+ "collect",
29554
+ "isEmpty",
29555
+ "size",
29556
+ "sum",
29557
+ "min",
29558
+ "max",
29559
+ "abs",
29560
+ "round",
29561
+ "floor",
29562
+ "sqrt",
29563
+ "includes",
29564
+ "excludes",
29565
+ "includesAll",
29566
+ "excludesAll",
29567
+ "count",
29568
+ "first",
29569
+ "last",
29570
+ "asSet",
29571
+ "asOrderedSet",
29572
+ "asSequence",
29573
+ "asBag",
29574
+ "sortedBy",
29575
+ "iterate",
29576
+ "oclIsUndefined",
29577
+ "oclIsKindOf",
29578
+ "oclIsTypeOf",
29579
+ "allInstances",
29580
+ // table-lookup engine vocabulary (the lookup facet names these)
29581
+ "lookup",
29582
+ "profile",
29583
+ // OCL collection statistics and arithmetic
29584
+ "average",
29585
+ "mean",
29586
+ "size",
29587
+ "div",
29588
+ "mod",
29589
+ "collect"
29590
+ ]);
29591
+ var CLOSED_DERIVATION_PATH_RE = /\b[A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)+/g;
29592
+ var CLOSED_DERIVATION_IDENT_RE = /[A-Za-z_][A-Za-z0-9_]*/g;
29593
+ function checkClosedDerivations(standard) {
29594
+ const issues = [];
29595
+ const err = (check, message) => issues.push({ check, severity: "error", message });
29596
+ const declared = /* @__PURE__ */ new Set();
29597
+ for (const c of standard.calculations ?? []) {
29598
+ declared.add(c.id);
29599
+ declared.add(c.name);
29600
+ }
29601
+ for (const tb of standard.tables ?? []) {
29602
+ declared.add(tb.id);
29603
+ }
29604
+ for (const s of standard.symbols ?? []) {
29605
+ declared.add(s.id);
29606
+ }
29607
+ for (const v of standard.variables ?? []) {
29608
+ declared.add(v.id);
29609
+ }
29610
+ for (const a of standard.attributeDefinitions ?? []) {
29611
+ declared.add(a.id);
29612
+ }
29613
+ for (const e of standard.enums ?? []) {
29614
+ declared.add(e.id);
29615
+ }
29616
+ for (const d of standard.dataclasses ?? []) {
29617
+ declared.add(d.id);
29618
+ }
29619
+ for (const inst of standard.instruments ?? []) {
29620
+ for (const d of inst.dimensions ?? []) {
29621
+ declared.add(d.id);
29622
+ }
29623
+ }
29624
+ for (const d of standard.dimensions ?? []) {
29625
+ declared.add(d.id);
29626
+ }
29627
+ for (const c of standard.calculations ?? []) {
29628
+ if (c.output?.name) {
29629
+ declared.add(c.output.name);
29630
+ }
29631
+ for (const i of c.inputs ?? []) {
29632
+ declared.add(i.name);
29633
+ }
29634
+ }
29635
+ const localsOf = (extra) => /* @__PURE__ */ new Set([...declared, ...extra]);
29636
+ const checkExpression = (expr, locals, where) => {
29637
+ if (!expr) {
29638
+ return;
29639
+ }
29640
+ const noLiterals = expr.replace(/'[^']*'/g, " ");
29641
+ const noLambdas = noLiterals.replace(
29642
+ /\b([A-Za-z_][A-Za-z0-9_]*)\s*\|/g,
29643
+ " "
29644
+ );
29645
+ const stripped = noLambdas.replace(CLOSED_DERIVATION_PATH_RE, " ");
29646
+ const seen = /* @__PURE__ */ new Set();
29647
+ for (const raw of stripped.match(CLOSED_DERIVATION_IDENT_RE) ?? []) {
29648
+ if (CLOSED_DERIVATION_STOP.has(raw) || locals.has(raw) || seen.has(raw) || /^[a-z][0-9]?$/.test(raw)) {
29649
+ continue;
29650
+ }
29651
+ seen.add(raw);
29652
+ err(
29653
+ "C149",
29654
+ `${where}: expression references "${raw}", which no declared calculation, table, symbol, measurement, or attribute defines (closed-derivation-references-declared)`
29655
+ );
29656
+ }
29657
+ };
29658
+ for (const a of standard.attributeDefinitions ?? []) {
29659
+ checkExpression(a.derived, localsOf([]), `attribute_definition ${a.id}`);
29660
+ }
29661
+ for (const c of standard.calculations ?? []) {
29662
+ const inputs = (c.inputs ?? []).map((i) => i.name);
29663
+ checkExpression(c.expression, localsOf(inputs), `calculation ${c.id}`);
29664
+ }
29665
+ for (const s of standard.symbols ?? []) {
29666
+ if (s.formula?.expression) {
29667
+ checkExpression(
29668
+ s.formula.expression,
29669
+ localsOf(s.formula.inputs ?? []),
29670
+ `symbol ${s.id}`
29671
+ );
29672
+ }
29673
+ }
29674
+ for (const v of standard.verdicts ?? []) {
29675
+ checkExpression(v.derive, localsOf(v.inputs ?? []), `verdict ${v.id}`);
29676
+ }
29677
+ return issues;
29678
+ }
29450
29679
  function checkSpellingCodes(standard) {
29451
29680
  const issues = [];
29452
29681
  const err = (check, message) => issues.push({ check, severity: "error", message });
@@ -31431,9 +31660,229 @@ function renderJsonLd(prefixes, triples) {
31431
31660
 
31432
31661
  // src/export/retrieval.ts
31433
31662
  import { createHash } from "node:crypto";
31434
- import { readdirSync as readdirSync4, readFileSync as readFileSync6, statSync as statSync3 } from "node:fs";
31435
- import { join as join5, relative } from "node:path";
31436
- var RETRIEVAL_PROJECTION = "primmel-retrieval/1";
31663
+ import { readdirSync as readdirSync4, readFileSync as readFileSync7, statSync as statSync3 } from "node:fs";
31664
+ import { join as join6, relative } from "node:path";
31665
+
31666
+ // src/export/unitsdb.ts
31667
+ import { existsSync as existsSync6, readFileSync as readFileSync6 } from "node:fs";
31668
+ import { join as join5 } from "node:path";
31669
+ function loadUnitsDb(dir) {
31670
+ if (!dir) {
31671
+ return null;
31672
+ }
31673
+ try {
31674
+ const entries = [];
31675
+ const jsonPath = join5(dir, "units.json");
31676
+ if (!existsSync6(jsonPath)) {
31677
+ return null;
31678
+ }
31679
+ const parsed = JSON.parse(readFileSync6(jsonPath, "utf8")).units;
31680
+ if (!Array.isArray(parsed)) {
31681
+ return null;
31682
+ }
31683
+ for (const u of parsed) {
31684
+ const identifiers = u.identifiers ?? [];
31685
+ const unitsml = identifiers.find((i) => i.type === "unitsml")?.id;
31686
+ if (!unitsml) {
31687
+ continue;
31688
+ }
31689
+ const nist = identifiers.find((i) => i.type === "nist")?.id;
31690
+ const scale = u.scale_reference?.id;
31691
+ const symbols = (u.symbols ?? []).map((s) => String(s.ascii ?? s.id)).filter(Boolean);
31692
+ const entry = {
31693
+ unitsml,
31694
+ ...nist ? { nist } : {},
31695
+ ...scale ? { scale } : {},
31696
+ symbols
31697
+ };
31698
+ entries.push(entry);
31699
+ }
31700
+ const bySymbol = /* @__PURE__ */ new Map();
31701
+ const byUnitsml = /* @__PURE__ */ new Map();
31702
+ const spellings = (s) => [
31703
+ s,
31704
+ s.replace(/\*([a-zA-ZμΩ°]+)\^-1\b/g, "/$1")
31705
+ ];
31706
+ for (const e of entries) {
31707
+ byUnitsml.set(e.unitsml, e);
31708
+ for (const s of e.symbols) {
31709
+ for (const sp of spellings(s)) {
31710
+ bySymbol.set(sp, e);
31711
+ }
31712
+ }
31713
+ }
31714
+ return { bySymbol, byUnitsml };
31715
+ } catch {
31716
+ return null;
31717
+ }
31718
+ }
31719
+ function unitsDbEntryFor(db, unit) {
31720
+ return db?.bySymbol.get(unit) ?? null;
31721
+ }
31722
+
31723
+ // src/export/yaml-lite.ts
31724
+ var NUMERIC2 = /^[-+]?(\d+\.?\d*|\.\d+)([eE][-+]?\d+)?$/;
31725
+ function parseScalar(raw) {
31726
+ const s = raw.trim();
31727
+ if (s === "" || s === "~" || s === "null" || s === "Null" || s === "NULL") {
31728
+ return null;
31729
+ }
31730
+ if (s === "true" || s === "True" || s === "TRUE") {
31731
+ return true;
31732
+ }
31733
+ if (s === "false" || s === "False" || s === "FALSE") {
31734
+ return false;
31735
+ }
31736
+ if (NUMERIC2.test(s)) {
31737
+ return Number(s);
31738
+ }
31739
+ if (s[0] === '"' || s[0] === "'") {
31740
+ return unquote(s, s[0]);
31741
+ }
31742
+ return s;
31743
+ }
31744
+ function unquote(s, q) {
31745
+ if (s.length < 2 || s[s.length - 1] !== q) {
31746
+ return s;
31747
+ }
31748
+ const body = s.slice(1, -1);
31749
+ if (q === "'") {
31750
+ return body.replace(/''/g, "'");
31751
+ }
31752
+ let out = "";
31753
+ for (let i = 0; i < body.length; i++) {
31754
+ const c = body[i];
31755
+ if (c !== "\\" || i === body.length - 1) {
31756
+ out += c;
31757
+ continue;
31758
+ }
31759
+ const e = body[++i];
31760
+ if (e === "n") {
31761
+ out += "\n";
31762
+ } else if (e === "t") {
31763
+ out += " ";
31764
+ } else if (e === "r") {
31765
+ out += "\r";
31766
+ } else if (e === "0") {
31767
+ out += "\0";
31768
+ } else if (e === "\\" || e === '"') {
31769
+ out += e;
31770
+ } else {
31771
+ out += "\\" + e;
31772
+ }
31773
+ }
31774
+ return out;
31775
+ }
31776
+ function splitKey(text) {
31777
+ const colon = text.indexOf(":");
31778
+ if (colon <= 0) {
31779
+ return null;
31780
+ }
31781
+ const key = text.slice(0, colon);
31782
+ if (/[\s"']/.test(key)) {
31783
+ return null;
31784
+ }
31785
+ return [key, text.slice(colon + 1)];
31786
+ }
31787
+ function parseValue(lines, i, indent) {
31788
+ if (i >= lines.length) {
31789
+ return [i, null];
31790
+ }
31791
+ const t = lines[i].text;
31792
+ if (t === "-" || t.startsWith("- ")) {
31793
+ return parseSequence(lines, i, indent);
31794
+ }
31795
+ return parseMapping(lines, i, indent);
31796
+ }
31797
+ function parseSequence(lines, i, indent) {
31798
+ const out = [];
31799
+ while (i < lines.length && lines[i].indent === indent && (lines[i].text === "-" || lines[i].text.startsWith("- "))) {
31800
+ const content = lines[i].text === "-" ? "" : lines[i].text.slice(2).trim();
31801
+ if (content === "") {
31802
+ i++;
31803
+ const next = i < lines.length ? lines[i].indent : -1;
31804
+ if (next > indent) {
31805
+ const [end, value] = parseValue(lines, i, next);
31806
+ out.push(value);
31807
+ i = end;
31808
+ } else {
31809
+ out.push(null);
31810
+ }
31811
+ continue;
31812
+ }
31813
+ const nested = content === "-" || content.startsWith("- ");
31814
+ if (nested || splitKey(content) !== null) {
31815
+ lines[i] = { indent: indent + 2, text: content };
31816
+ const [end, value] = nested ? parseSequence(lines, i, indent + 2) : parseMapping(lines, i, indent + 2);
31817
+ out.push(value);
31818
+ i = end;
31819
+ } else {
31820
+ out.push(parseScalar(content));
31821
+ i++;
31822
+ }
31823
+ }
31824
+ return [i, out];
31825
+ }
31826
+ function parseMapping(lines, i, indent) {
31827
+ const map = {};
31828
+ while (i < lines.length) {
31829
+ const line = lines[i];
31830
+ if (line.indent !== indent || line.text === "-" || line.text.startsWith("- ")) {
31831
+ break;
31832
+ }
31833
+ const kv = splitKey(line.text);
31834
+ if (!kv) {
31835
+ break;
31836
+ }
31837
+ const [key, rest] = kv;
31838
+ i++;
31839
+ if (rest.trim() === "") {
31840
+ const next = i < lines.length ? lines[i].indent : -1;
31841
+ if (next > indent) {
31842
+ const [end, value] = parseValue(lines, i, next);
31843
+ map[key] = value;
31844
+ i = end;
31845
+ } else {
31846
+ map[key] = null;
31847
+ }
31848
+ } else {
31849
+ map[key] = parseScalar(rest);
31850
+ }
31851
+ }
31852
+ return [i, map];
31853
+ }
31854
+ function parseYamlBlock(text) {
31855
+ const scanned = [];
31856
+ for (const raw of text.split("\n")) {
31857
+ if (raw.trim() === "") {
31858
+ continue;
31859
+ }
31860
+ scanned.push({
31861
+ indent: raw.length - raw.trimStart().length,
31862
+ text: raw.trim()
31863
+ });
31864
+ }
31865
+ if (scanned.length === 0 || splitKey(scanned[0].text) === null) {
31866
+ return void 0;
31867
+ }
31868
+ const bases = /* @__PURE__ */ new Set([
31869
+ scanned[0].indent,
31870
+ scanned[1]?.indent ?? scanned[0].indent
31871
+ ]);
31872
+ for (const base of bases) {
31873
+ const lines = scanned.map(
31874
+ (l) => l === scanned[0] && l.indent < base ? { indent: base, text: l.text } : l
31875
+ );
31876
+ const [end, map] = parseMapping(lines, 0, base);
31877
+ if (end === lines.length && Object.keys(map).length > 0) {
31878
+ return map;
31879
+ }
31880
+ }
31881
+ return void 0;
31882
+ }
31883
+
31884
+ // src/export/retrieval.ts
31885
+ var RETRIEVAL_PROJECTION = "primmel-retrieval/2";
31437
31886
  var RETRIEVAL_FACET_VERSION = "retrieval-facet/1";
31438
31887
  function sortDeep(v) {
31439
31888
  if (Array.isArray(v)) {
@@ -31462,7 +31911,7 @@ function* walkPackage(dir) {
31462
31911
  if (entry === ".DS_Store") {
31463
31912
  continue;
31464
31913
  }
31465
- const p = join5(dir, entry);
31914
+ const p = join6(dir, entry);
31466
31915
  if (statSync3(p).isDirectory()) {
31467
31916
  yield* walkPackage(p);
31468
31917
  } else {
@@ -31475,7 +31924,7 @@ function packageSourceHash(dir) {
31475
31924
  for (const file of walkPackage(dir)) {
31476
31925
  h.update(relative(dir, file));
31477
31926
  h.update("\0");
31478
- h.update(createHash("sha256").update(readFileSync6(file)).digest());
31927
+ h.update(createHash("sha256").update(readFileSync7(file)).digest());
31479
31928
  h.update("\n");
31480
31929
  }
31481
31930
  return h.digest("hex");
@@ -31590,11 +32039,94 @@ function passportOf(unit) {
31590
32039
  expression: unit.expression ?? "",
31591
32040
  units: unit.units ?? [],
31592
32041
  applicability: applicabilitySummary(unit.applicability),
31593
- acceptance: unit.acceptance ?? "",
32042
+ acceptance: acceptanceSummary(unit),
31594
32043
  provenance: (unit.clauses ?? []).map((c) => c.urn),
31595
32044
  content_hash: unit.content_hash
31596
32045
  };
31597
32046
  }
32047
+ function acceptanceDecisionOf(a) {
32048
+ if (!a) {
32049
+ return void 0;
32050
+ }
32051
+ const out = {
32052
+ ...present(a.rule) ? { rule: a.rule } : {}
32053
+ };
32054
+ if (a.guardBand) {
32055
+ out.guard_band = { kind: a.guardBand.kind, value: a.guardBand.value };
32056
+ }
32057
+ if (a.uncertainty) {
32058
+ out.uncertainty = { max_ratio_to_mpe: a.uncertainty.maxRatioToMpe };
32059
+ }
32060
+ if (present(a.criterion)) {
32061
+ out.criterion = a.criterion;
32062
+ }
32063
+ if (a.statistics) {
32064
+ out.statistics = {
32065
+ method: a.statistics.method,
32066
+ on_basis_of: a.statistics.onBasisOf,
32067
+ permits: a.statistics.permits
32068
+ };
32069
+ }
32070
+ return Object.keys(out).length > 0 ? out : void 0;
32071
+ }
32072
+ function criteriaItemOf(c) {
32073
+ const item = { name: c.item };
32074
+ if (present(c.requirementId)) {
32075
+ item.target = c.requirementId;
32076
+ }
32077
+ if (present(c.criterion)) {
32078
+ item.criterion = c.criterion;
32079
+ }
32080
+ if (present(c.passIf)) {
32081
+ item.pass_if = c.passIf;
32082
+ }
32083
+ if (c.accepts) {
32084
+ item.accepts = {
32085
+ verdict: c.accepts.verdict,
32086
+ op: c.accepts.op,
32087
+ limit: c.accepts.limit
32088
+ };
32089
+ }
32090
+ if (c.optional) {
32091
+ item.optional = true;
32092
+ }
32093
+ if (present(c.description)) {
32094
+ item.description = c.description;
32095
+ }
32096
+ if (present(c.reference)) {
32097
+ item.reference = c.reference;
32098
+ }
32099
+ return item;
32100
+ }
32101
+ function testAcceptanceCriteriaOf(t) {
32102
+ const out = {
32103
+ ...present(t.acceptanceCriteriaType) ? { type: t.acceptanceCriteriaType } : {},
32104
+ ...present(t.acceptanceCriteriaDescription) ? { description: t.acceptanceCriteriaDescription } : {},
32105
+ ...present(t.acceptancePassIf) ? { pass_if: t.acceptancePassIf } : {},
32106
+ ...presentList(t.acceptanceCriteria) ? { items: t.acceptanceCriteria.map(criteriaItemOf) } : {}
32107
+ };
32108
+ return Object.keys(out).length > 0 ? out : void 0;
32109
+ }
32110
+ function acceptanceSummary(unit) {
32111
+ if (unit.accepts) {
32112
+ return `${unit.accepts.verdict} ${unit.accepts.op} ${unit.accepts.limit}`;
32113
+ }
32114
+ const criteria = unit.acceptance_criteria;
32115
+ if (criteria && typeof criteria === "object") {
32116
+ const passIf = criteria["pass_if"];
32117
+ if (present(passIf)) {
32118
+ return passIf;
32119
+ }
32120
+ const description = criteria["description"];
32121
+ if (present(description)) {
32122
+ return description;
32123
+ }
32124
+ }
32125
+ if (unit.acceptance?.rule) {
32126
+ return unit.acceptance.rule;
32127
+ }
32128
+ return "";
32129
+ }
31598
32130
  var BASE_URN_PARTS = /^urn:oiml:pub:([rdbge]):(\d[\d-]*)(?::(\d{4}))?$/i;
31599
32131
  function retrievalDocParts(baseUrn) {
31600
32132
  const m = BASE_URN_PARTS.exec(baseUrn);
@@ -31753,6 +32285,8 @@ function scopeOf(id) {
31753
32285
  var present = (s) => typeof s === "string" && s.length > 0;
31754
32286
  var presentList = (xs) => xs && xs.length > 0 ? xs : void 0;
31755
32287
  function requirementUnit(r) {
32288
+ const decision = acceptanceDecisionOf(r.limit?.acceptance);
32289
+ const criteria = present(r.acceptanceCriteria) ? parseYamlBlock(r.acceptanceCriteria) ?? r.acceptanceCriteria : void 0;
31756
32290
  return assemble(
31757
32291
  {
31758
32292
  id: r.id,
@@ -31770,9 +32304,14 @@ function requirementUnit(r) {
31770
32304
  ...presentList(r.applicability) ? { applicability: r.applicability } : {},
31771
32305
  ...presentList(r.bindsTo) ? { binds_to: r.bindsTo } : {},
31772
32306
  ...r.limit?.accepts ? {
31773
- acceptance: `${r.limit.accepts.verdict} ${r.limit.accepts.op} ${r.limit.accepts.limit}`
32307
+ accepts: {
32308
+ verdict: r.limit.accepts.verdict,
32309
+ op: r.limit.accepts.op,
32310
+ limit: r.limit.accepts.limit
32311
+ }
31774
32312
  } : {},
31775
- ...present(r.acceptanceCriteria) ? { acceptance_criteria: r.acceptanceCriteria } : {},
32313
+ ...decision ? { acceptance: decision } : {},
32314
+ ...criteria !== void 0 ? { acceptance_criteria: criteria } : {},
31776
32315
  ...present(r.verificationMethod) ? {
31777
32316
  verification: {
31778
32317
  method: r.verificationMethod,
@@ -31788,16 +32327,10 @@ function requirementUnit(r) {
31788
32327
  function conformanceTestUnit(t) {
31789
32328
  const payload = {
31790
32329
  ...present(t.kind) ? { test_kind: t.kind } : {},
31791
- ...present(t.methodRef) ? { method_ref: t.methodRef } : {},
31792
- ...presentList(t.preconditions) ? {
31793
- preconditions: t.preconditions.map((p) => ({
31794
- id: p.id,
31795
- check: p.check,
31796
- description: p.description,
31797
- on_violation: p.onViolation
31798
- }))
31799
- } : {}
32330
+ ...present(t.methodRef) ? { method_ref: t.methodRef } : {}
31800
32331
  };
32332
+ const decision = acceptanceDecisionOf(t.acceptance);
32333
+ const criteria = testAcceptanceCriteriaOf(t);
31801
32334
  return assemble(
31802
32335
  {
31803
32336
  id: t.id,
@@ -31811,7 +32344,17 @@ function conformanceTestUnit(t) {
31811
32344
  ...presentList(t.applicability) ? { applicability: t.applicability } : {},
31812
32345
  ...presentList(t.targets) ? { targets: t.targets } : {},
31813
32346
  ...presentList(t.bindsTo) ? { binds_to: t.bindsTo } : {},
31814
- ...present(t.acceptancePassIf) ? { acceptance: t.acceptancePassIf } : present(t.acceptanceCriteriaDescription) ? { acceptance: t.acceptanceCriteriaDescription } : {},
32347
+ ...decision ? { acceptance: decision } : {},
32348
+ ...criteria ? { acceptance_criteria: criteria } : {},
32349
+ ...presentList(t.preconditions) ? {
32350
+ preconditions: t.preconditions.map((p) => ({
32351
+ id: p.id,
32352
+ check: p.check,
32353
+ ...present(p.description) ? { description: p.description } : {},
32354
+ ...present(p.onViolation) ? { on_violation: p.onViolation } : {},
32355
+ ...present(p.onUnresolvable) ? { on_unresolvable: p.onUnresolvable } : {}
32356
+ }))
32357
+ } : {},
31815
32358
  ...presentList(t.dependencies) ? { dependencies: t.dependencies } : {},
31816
32359
  ...Object.keys(payload).length > 0 ? { payload } : {}
31817
32360
  },
@@ -31970,9 +32513,15 @@ function constraintUnit(c) {
31970
32513
  ...present(c.name) ? { name: c.name } : {},
31971
32514
  ...present(c.violationMeaning) ? { statement: c.violationMeaning } : {},
31972
32515
  ...present(c.check) ? { expression: c.check } : {},
32516
+ // The violation semantics first-class (ask 8) — the construct's
32517
+ // own keyword vocabulary, out of the payload grab bag. `statement`
32518
+ // and `expression` stay: the generic prose/expression slots the
32519
+ // passport and the consumer's grounding text read.
32520
+ ...present(c.check) ? { check: c.check } : {},
32521
+ ...present(c.violationMeaning) ? { violation_meaning: c.violationMeaning } : {},
32522
+ ...present(c.onViolation) ? { on_violation: c.onViolation } : {},
31973
32523
  payload: {
31974
- ...present(c.stereotype) ? { stereotype: c.stereotype } : {},
31975
- ...present(c.onViolation) ? { on_violation: c.onViolation } : {}
32524
+ ...present(c.stereotype) ? { stereotype: c.stereotype } : {}
31976
32525
  }
31977
32526
  },
31978
32527
  collectClauses(c)
@@ -31995,7 +32544,7 @@ function characteristicUnit(v) {
31995
32544
  ...presentList(v.inputs) ? { expression_inputs: v.inputs } : {}
31996
32545
  } : {},
31997
32546
  ...units ? { units } : {},
31998
- ...v.acceptance && present(v.acceptance.rule) ? { acceptance: v.acceptance.rule } : {},
32547
+ ...acceptanceDecisionOf(v.acceptance) ? { acceptance: acceptanceDecisionOf(v.acceptance) } : {},
31999
32548
  ...Object.keys(payload).length > 0 ? { payload } : {}
32000
32549
  },
32001
32550
  collectClauses(v)
@@ -32052,6 +32601,76 @@ function sequenceUnit(s) {
32052
32601
  collectClauses({ sourceRefs: s.sourceRefs, refs: s.refs })
32053
32602
  );
32054
32603
  }
32604
+ function conditionSetUnit(cs, registers, db = null) {
32605
+ const unitsBySymbol = /* @__PURE__ */ new Map();
32606
+ for (const reg of registers ?? []) {
32607
+ const siUnitByKind = new Map(reg.kinds.map((k) => [k.id, k.siUnit]));
32608
+ for (const u of reg.units ?? []) {
32609
+ const siUnit = siUnitByKind.get(u.kind);
32610
+ if (siUnit) {
32611
+ unitsBySymbol.set(u.symbol, {
32612
+ kind: u.kind,
32613
+ factorToSI: u.factorToSI,
32614
+ offsetToSI: u.offsetToSI,
32615
+ siUnit
32616
+ });
32617
+ }
32618
+ }
32619
+ }
32620
+ const siOf = (value, unit) => {
32621
+ const def = unitsBySymbol.get(unit);
32622
+ if (!def) {
32623
+ return void 0;
32624
+ }
32625
+ const n = Number(String(value).replace(",", "."));
32626
+ if (!Number.isFinite(n)) {
32627
+ return void 0;
32628
+ }
32629
+ return { value: n * def.factorToSI + def.offsetToSI, unit: def.siUnit };
32630
+ };
32631
+ const payload = {
32632
+ role: cs.role,
32633
+ ...cs.subject ? { subject: cs.subject } : {},
32634
+ entries: cs.entries.map((e) => {
32635
+ const si = siOf(e.value, e.unit);
32636
+ const ud = unitsDbEntryFor(db, e.unit);
32637
+ return {
32638
+ quantity_kind: e.quantityKind,
32639
+ value: e.value,
32640
+ unit: e.unit,
32641
+ tolerance: e.tolerance,
32642
+ ...si ? { si } : {},
32643
+ ...ud ? {
32644
+ unitsdb: {
32645
+ unitsml: ud.unitsml,
32646
+ ...ud.scale ? { scale: ud.scale } : {}
32647
+ }
32648
+ } : {},
32649
+ ...e.note ? { note: e.note } : {}
32650
+ };
32651
+ })
32652
+ };
32653
+ return assemble(
32654
+ {
32655
+ id: `/condition/${cs.id}`,
32656
+ kind: "condition_set",
32657
+ name: cs.id,
32658
+ statement: [
32659
+ `${cs.role} condition set`,
32660
+ ...cs.description ? [cs.description] : [],
32661
+ ...cs.entries.map(
32662
+ (e) => `${e.quantityKind.replace(/_/g, " ")}: ${e.value} ${e.unit} \xB1${e.tolerance}`
32663
+ )
32664
+ ].join(" \u2014 "),
32665
+ payload
32666
+ },
32667
+ collectClauses({
32668
+ sourceRefs: cs.sources,
32669
+ refs: cs.refs,
32670
+ source: cs.source
32671
+ })
32672
+ );
32673
+ }
32055
32674
  function noteUnit(n) {
32056
32675
  return assemble(
32057
32676
  {
@@ -32092,11 +32711,16 @@ function dimensionUnit(d) {
32092
32711
  const payload = {
32093
32712
  ...present(d.scope) ? { scope: d.scope } : {},
32094
32713
  ...present(d.cardinality) ? { cardinality: d.cardinality } : {},
32714
+ // The typed payload (the typed kernel R2): a value IS its
32715
+ // definition — the class's fields ride the value, and the class
32716
+ // reference rides the dimension.
32717
+ ...present(d.payloadClass) ? { payload_class: d.payloadClass } : {},
32095
32718
  values: d.values.map((v) => ({
32096
32719
  id: v.id,
32097
32720
  ...present(v.label) ? { label: v.label } : {},
32098
32721
  ...presentList(v.implies) ? { implies: v.implies } : {},
32099
- ...present(v.termRef) ? { term_ref: v.termRef } : {}
32722
+ ...present(v.termRef) ? { term_ref: v.termRef } : {},
32723
+ ...Object.keys(v.payload ?? {}).length > 0 ? { payload: v.payload } : {}
32100
32724
  }))
32101
32725
  };
32102
32726
  return assemble(
@@ -32151,6 +32775,7 @@ function packageBlock(standard) {
32151
32775
  };
32152
32776
  }
32153
32777
  function exportStandardRetrieval(standard, options = {}) {
32778
+ const unitsDb = loadUnitsDb(process.env.UNITSDB_DIR);
32154
32779
  const pkg = packageBlock(standard);
32155
32780
  const built = [];
32156
32781
  const push = (content, elementId) => {
@@ -32189,6 +32814,9 @@ function exportStandardRetrieval(standard, options = {}) {
32189
32814
  for (const s of standard.testSequences ?? []) {
32190
32815
  push(sequenceUnit(s), s.id);
32191
32816
  }
32817
+ for (const cs of standard.conditionSets ?? []) {
32818
+ push(conditionSetUnit(cs, standard.quantityRegisters, unitsDb), cs.id);
32819
+ }
32192
32820
  for (const n of standard.notes ?? []) {
32193
32821
  push(noteUnit(n), n.id);
32194
32822
  }
@@ -32468,18 +33096,171 @@ function exportPackageImpact(dir) {
32468
33096
  };
32469
33097
  }
32470
33098
 
33099
+ // src/export/cddal.ts
33100
+ import { readFileSync as readFileSync8, readdirSync as readdirSync5 } from "node:fs";
33101
+ import { basename, join as join7, resolve as resolve5 } from "node:path";
33102
+ var CDDAL_PROJECTION_VERSION = "primmel-cddal/1";
33103
+ function escapeCddalString(s) {
33104
+ return s.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
33105
+ }
33106
+ function quote(s) {
33107
+ return `"${escapeCddalString(s)}"`;
33108
+ }
33109
+ function safeSymbol(id) {
33110
+ const s = id.replace(/[^A-Za-z0-9_]+/g, "_");
33111
+ return /^[0-9]/.test(s) ? `N${s}` : s;
33112
+ }
33113
+ function isSafeIdentifier(id) {
33114
+ return /^[A-Za-z_][A-Za-z0-9_]*$/.test(id);
33115
+ }
33116
+ function codeAssignment(id) {
33117
+ return isSafeIdentifier(id) ? id : quote(id);
33118
+ }
33119
+ function quantity(v) {
33120
+ return quote(
33121
+ v.unit !== void 0 && v.unit !== "" ? `${v.value} ${v.unit}` : String(v.value)
33122
+ );
33123
+ }
33124
+ function readL10n(files, read) {
33125
+ const out = /* @__PURE__ */ new Map();
33126
+ const block = /text\s+([\w./#-]+)\s*\{([\s\S]*?)\}/g;
33127
+ const spell = /spell\s+([\w-]+)\s+"((?:[^"\\]|\\.)*)"/g;
33128
+ for (const f of files.filter((f2) => /(^|\/)l10n\.[^/]+\.prl$/.test(f2))) {
33129
+ const src = read(f);
33130
+ for (const m of src.matchAll(block)) {
33131
+ const addr = m[1];
33132
+ const tail = addr.split("/").pop() ?? addr;
33133
+ for (const sp of (m[2] ?? "").matchAll(spell)) {
33134
+ const list = out.get(tail) ?? [];
33135
+ list.push({ tag: sp[1], value: sp[2] });
33136
+ out.set(tail, list);
33137
+ }
33138
+ }
33139
+ }
33140
+ return out;
33141
+ }
33142
+ function l10nDefinitions(l10n, id, field) {
33143
+ return l10n.get(`${id}.${field}`) ?? [];
33144
+ }
33145
+ function projectCddal(model, packageId, l10n = /* @__PURE__ */ new Map()) {
33146
+ const lines = [
33147
+ `# ${CDDAL_PROJECTION_VERSION} \u2014 the dictionary subset of ${packageId}`,
33148
+ "# (generated by primmel export cddal \u2014 never authored, never re-imported)",
33149
+ ""
33150
+ ];
33151
+ const stats = {
33152
+ classes: 0,
33153
+ instances: 0,
33154
+ assignments: 0,
33155
+ properties: 0,
33156
+ valueLists: 0
33157
+ };
33158
+ const attrDefs = new Map(
33159
+ (model.attributeDefinitions ?? []).map((a) => [a.id, a])
33160
+ );
33161
+ for (const c of model.dataclasses) {
33162
+ stats.classes++;
33163
+ lines.push(`instance ${safeSymbol(c.id)} < MDC_C002 {`);
33164
+ lines.push(` code: ${codeAssignment(c.id)}`);
33165
+ if (c.description) {
33166
+ lines.push(` definition.en: ${quote(c.description)}`);
33167
+ for (const alt of l10nDefinitions(l10n, c.id, "description")) {
33168
+ lines.push(` definition.${alt.tag}: ${quote(alt.value)}`);
33169
+ }
33170
+ }
33171
+ lines.push(
33172
+ ` superclass: ${c.extends !== void 0 ? safeSymbol(c.extends) : "UNIVERSE"}`
33173
+ );
33174
+ if (c.attributes.length > 0) {
33175
+ lines.push(
33176
+ ` applicable_properties: { ${c.attributes.map((a) => safeSymbol(a.id)).join(", ")} }`
33177
+ );
33178
+ }
33179
+ lines.push("}");
33180
+ lines.push("");
33181
+ for (const a of c.attributes) {
33182
+ const def = attrDefs.get(a.id);
33183
+ if (!def) {
33184
+ continue;
33185
+ }
33186
+ const irdi = def.irdi || def.correspondences?.find((x) => x.scheme === "iec-cdd")?.concept;
33187
+ stats.properties++;
33188
+ lines.push(`instance ${safeSymbol(a.id)} < MDC_C003 {`);
33189
+ lines.push(
33190
+ ` code: ${codeAssignment(irdi !== void 0 && irdi !== "" ? irdi : a.id)}`
33191
+ );
33192
+ if (def.definition) {
33193
+ lines.push(` definition.en: ${quote(def.definition)}`);
33194
+ for (const alt of l10nDefinitions(l10n, a.id, "definition")) {
33195
+ lines.push(` definition.${alt.tag}: ${quote(alt.value)}`);
33196
+ }
33197
+ }
33198
+ lines.push("}");
33199
+ lines.push("");
33200
+ }
33201
+ }
33202
+ for (const e of model.enums ?? []) {
33203
+ stats.valueLists++;
33204
+ lines.push(`instance ${safeSymbol(e.id)} < MDC_C005 {`);
33205
+ lines.push(` code: ${codeAssignment(e.id)}`);
33206
+ if (e.values.length > 0) {
33207
+ lines.push(
33208
+ ` MDC_P043: ( ${e.values.map((v) => safeSymbol(v.id)).join(", ")} )`
33209
+ );
33210
+ }
33211
+ lines.push("}");
33212
+ lines.push("");
33213
+ for (const v of e.values) {
33214
+ lines.push(`instance ${safeSymbol(v.id)} < MDC_C010 {`);
33215
+ lines.push(` code: ${codeAssignment(v.id)}`);
33216
+ lines.push("}");
33217
+ lines.push("");
33218
+ }
33219
+ }
33220
+ for (const inst of model.instances) {
33221
+ stats.instances++;
33222
+ lines.push(`instance ${safeSymbol(inst.id)} < MDC_C002 {`);
33223
+ lines.push(` code: ${codeAssignment(inst.id)}`);
33224
+ if (inst.of) {
33225
+ lines.push(` superclass: ${safeSymbol(inst.of)}`);
33226
+ }
33227
+ for (const [id, v] of Object.entries(inst.has?.attributes ?? {})) {
33228
+ stats.assignments++;
33229
+ lines.push(` ${safeSymbol(id)}: ${quantity(v)}`);
33230
+ }
33231
+ lines.push("}");
33232
+ lines.push("");
33233
+ }
33234
+ if (stats.classes === 0 && stats.instances === 0 && stats.valueLists === 0) {
33235
+ throw new Error(
33236
+ "no dictionary content: the CDDAL projection carries classes and instances"
33237
+ );
33238
+ }
33239
+ return {
33240
+ version: CDDAL_PROJECTION_VERSION,
33241
+ cddal: lines.join("\n"),
33242
+ stats
33243
+ };
33244
+ }
33245
+ function exportPackageCddal(dir) {
33246
+ const model = loadPackage(dir);
33247
+ const l10nFiles = readdirSync5(dir).filter((e) => /^l10n\.[^/]+\.prl$/.test(e)).map((e) => join7(dir, e));
33248
+ const l10n = readL10n(l10nFiles, (p) => readFileSync8(p, "utf8"));
33249
+ return projectCddal(model, basename(resolve5(dir)), l10n);
33250
+ }
33251
+
32471
33252
  // src/package-diff.ts
32472
- import { existsSync as existsSync6, readdirSync as readdirSync5, readFileSync as readFileSync7 } from "fs";
32473
- import { join as join6 } from "path";
33253
+ import { existsSync as existsSync7, readdirSync as readdirSync6, readFileSync as readFileSync9 } from "fs";
33254
+ import { join as join8 } from "path";
32474
33255
  function packageMappings(dir, standard) {
32475
33256
  const profiles = [...standard.mapProfiles ?? []];
32476
- if (existsSync6(dir)) {
32477
- for (const entry of readdirSync5(dir).sort()) {
33257
+ if (existsSync7(dir)) {
33258
+ for (const entry of readdirSync6(dir).sort()) {
32478
33259
  if (!entry.endsWith(".prm")) {
32479
33260
  continue;
32480
33261
  }
32481
33262
  profiles.push(
32482
- ...prmToMapProfiles(loadPrm(readFileSync7(join6(dir, entry), "utf8")))
33263
+ ...prmToMapProfiles(loadPrm(readFileSync9(join8(dir, entry), "utf8")))
32483
33264
  );
32484
33265
  }
32485
33266
  }
@@ -32488,17 +33269,17 @@ function packageMappings(dir, standard) {
32488
33269
  }
32489
33270
  function packageClauseTexts(dir) {
32490
33271
  const out = /* @__PURE__ */ new Map();
32491
- const prdDir = join6(dir, "sources-prd");
32492
- if (!existsSync6(prdDir)) {
33272
+ const prdDir = join8(dir, "sources-prd");
33273
+ if (!existsSync7(prdDir)) {
32493
33274
  return out;
32494
33275
  }
32495
- for (const entry of readdirSync5(prdDir).sort()) {
33276
+ for (const entry of readdirSync6(prdDir).sort()) {
32496
33277
  if (!entry.endsWith(".sentences.json")) {
32497
33278
  continue;
32498
33279
  }
32499
33280
  let payload;
32500
33281
  try {
32501
- payload = JSON.parse(readFileSync7(join6(prdDir, entry), "utf8"));
33282
+ payload = JSON.parse(readFileSync9(join8(prdDir, entry), "utf8"));
32502
33283
  } catch {
32503
33284
  continue;
32504
33285
  }
@@ -32548,18 +33329,18 @@ function diffPackageDirs(dirA, dirB, options = {}) {
32548
33329
  // scripts/check.mts
32549
33330
  var CHECK_USAGE = "Usage: primmel check [--strict] [--audit] [--coverage] [--rules] [--with <pkg-id>=<dir>]\u2026 <package-dir>";
32550
33331
  var DIFF_USAGE = "Usage: primmel diff [--json] [--exit-code] [--compare-texts] [--with <pkg-id>=<dir>]\u2026 <a> <b>";
32551
- var EXPORT_USAGE = "Usage: primmel export reqif|rdf|retrieval|impact <package-dir> [--out <file>] [--format turtle|jsonld]";
33332
+ var EXPORT_USAGE = "Usage: primmel export reqif|rdf|retrieval|impact|cddal <package-dir> [--out <file>] [--format turtle|jsonld]";
32552
33333
  function readablePackageDirProblem(target, needsManifest) {
32553
33334
  try {
32554
33335
  if (!statSync4(target).isDirectory()) {
32555
33336
  return "not a directory";
32556
33337
  }
32557
- readdirSync6(target);
33338
+ readdirSync7(target);
32558
33339
  } catch (e) {
32559
33340
  const err = e;
32560
33341
  return err.code === "ENOENT" ? "no such directory" : err.message;
32561
33342
  }
32562
- if (needsManifest && !existsSync7(join7(target, "package.primmel"))) {
33343
+ if (needsManifest && !existsSync8(join9(target, "package.primmel"))) {
32563
33344
  return "no package.primmel found";
32564
33345
  }
32565
33346
  return null;
@@ -32718,7 +33499,7 @@ function diffCli(args2) {
32718
33499
  }
32719
33500
  function exportCli(args2) {
32720
33501
  const surface = args2[0];
32721
- if (surface !== "reqif" && surface !== "rdf" && surface !== "retrieval" && surface !== "impact") {
33502
+ if (surface !== "reqif" && surface !== "rdf" && surface !== "retrieval" && surface !== "impact" && surface !== "cddal") {
32722
33503
  console.error(EXPORT_USAGE);
32723
33504
  process.exit(2);
32724
33505
  }
@@ -32753,7 +33534,11 @@ function exportCli(args2) {
32753
33534
  let document;
32754
33535
  let summary;
32755
33536
  try {
32756
- if (surface === "impact") {
33537
+ if (surface === "cddal") {
33538
+ const result = exportPackageCddal(dir);
33539
+ document = result.cddal;
33540
+ summary = `${n(result.stats.classes, "class", "classes")}, ${n(result.stats.instances, "instance", "instances")}, ${n(result.stats.assignments, "assignment", "assignments")}`;
33541
+ } else if (surface === "impact") {
32757
33542
  const result = exportPackageImpact(dir);
32758
33543
  document = result.json;
32759
33544
  const s = result.stats;