@astrale-os/kernel-dsl 0.2.0-beta.8 → 1.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (321) hide show
  1. package/dist/v1/addressing/class-key.js +5 -4
  2. package/dist/v1/addressing/method-key.js +3 -2
  3. package/dist/v1/addressing/patterns.d.ts +0 -5
  4. package/dist/v1/addressing/patterns.js +5 -5
  5. package/dist/v1/builder/callable/authoring.d.ts +87 -41
  6. package/dist/v1/builder/callable/authoring.js +29 -14
  7. package/dist/v1/builder/class/authoring.d.ts +311 -36
  8. package/dist/v1/builder/class/authoring.js +3 -4
  9. package/dist/v1/builder/class/property.d.ts +16 -8
  10. package/dist/v1/builder/class/property.js +21 -5
  11. package/dist/v1/builder/core/authoring.d.ts +28 -13
  12. package/dist/v1/builder/core/authoring.js +22 -2
  13. package/dist/v1/builder/index.d.ts +9 -8
  14. package/dist/v1/builder/index.js +2 -2
  15. package/dist/v1/builder/lowering/callable.d.ts +3 -1
  16. package/dist/v1/builder/lowering/callable.js +43 -51
  17. package/dist/v1/builder/lowering/class.d.ts +7 -0
  18. package/dist/v1/builder/lowering/class.js +79 -29
  19. package/dist/v1/builder/lowering/core.d.ts +3 -2
  20. package/dist/v1/builder/lowering/core.js +9 -6
  21. package/dist/v1/builder/lowering/policy.d.ts +8 -1
  22. package/dist/v1/builder/lowering/policy.js +35 -0
  23. package/dist/v1/builder/lowering/schema/capture.js +9 -4
  24. package/dist/v1/builder/lowering/schema/compile.d.ts +2 -2
  25. package/dist/v1/builder/lowering/schema/compile.js +15 -2
  26. package/dist/v1/builder/lowering/schema/context.d.ts +11 -8
  27. package/dist/v1/builder/lowering/schema/context.js +59 -29
  28. package/dist/v1/builder/lowering/schema/ownership.d.ts +3 -3
  29. package/dist/v1/builder/lowering/schema/ownership.js +2 -1
  30. package/dist/v1/builder/lowering/value/compile.js +14 -4
  31. package/dist/v1/builder/lowering/value/zod.d.ts +7 -6
  32. package/dist/v1/builder/lowering/value/zod.js +16 -7
  33. package/dist/v1/builder/lowering/view.d.ts +4 -3
  34. package/dist/v1/builder/lowering/view.js +2 -14
  35. package/dist/v1/builder/policy/authoring.d.ts +23 -6
  36. package/dist/v1/builder/policy/authoring.js +35 -8
  37. package/dist/v1/builder/schema/define.d.ts +8 -5
  38. package/dist/v1/builder/schema/diagnostic.d.ts +1 -1
  39. package/dist/v1/builder/schema/handle.d.ts +2 -1
  40. package/dist/v1/builder/schema/input.d.ts +9 -1
  41. package/dist/v1/builder/schema/projection/callable.d.ts +51 -0
  42. package/dist/v1/builder/schema/projection/callable.js +1 -0
  43. package/dist/v1/builder/schema/projection/class.d.ts +89 -0
  44. package/dist/v1/builder/schema/projection/class.js +1 -0
  45. package/dist/v1/builder/schema/projection/core-input.d.ts +32 -0
  46. package/dist/v1/builder/schema/projection/core-input.js +1 -0
  47. package/dist/v1/builder/schema/projection/domain.d.ts +59 -0
  48. package/dist/v1/builder/schema/projection/domain.js +1 -0
  49. package/dist/v1/builder/schema/projection/identity.d.ts +39 -0
  50. package/dist/v1/builder/schema/projection/identity.js +1 -0
  51. package/dist/v1/builder/schema/projection/model.d.ts +59 -0
  52. package/dist/v1/builder/schema/projection/model.js +1 -0
  53. package/dist/v1/builder/schema/projection/property.d.ts +32 -0
  54. package/dist/v1/builder/schema/projection/property.js +1 -0
  55. package/dist/v1/builder/schema/projection/resolved-class.d.ts +76 -0
  56. package/dist/v1/builder/schema/projection/resolved-class.js +1 -0
  57. package/dist/v1/builder/schema/projection.d.ts +4 -258
  58. package/dist/v1/builder/value/full-match.js +6 -3
  59. package/dist/v1/builder/value/path.d.ts +2 -2
  60. package/dist/v1/builder/value/path.js +2 -2
  61. package/dist/v1/builder/view/authoring.d.ts +6 -14
  62. package/dist/v1/builder/view/authoring.js +13 -5
  63. package/dist/v1/bundle/structure.d.ts +2 -1
  64. package/dist/v1/compiled/admission/accept.d.ts +1 -1
  65. package/dist/v1/compiled/admission/accept.js +11 -814
  66. package/dist/v1/compiled/admission/closure.d.ts +3 -0
  67. package/dist/v1/compiled/admission/closure.js +173 -0
  68. package/dist/v1/compiled/admission/diagnostic.d.ts +7 -0
  69. package/dist/v1/compiled/admission/diagnostic.js +13 -0
  70. package/dist/v1/compiled/admission/revision.js +9 -1
  71. package/dist/v1/compiled/admission/semantics/cardinality.d.ts +5 -0
  72. package/dist/v1/compiled/admission/semantics/cardinality.js +113 -0
  73. package/dist/v1/compiled/admission/semantics/class.d.ts +5 -0
  74. package/dist/v1/compiled/admission/semantics/class.js +125 -0
  75. package/dist/v1/compiled/admission/semantics/context.d.ts +60 -0
  76. package/dist/v1/compiled/admission/semantics/context.js +81 -0
  77. package/dist/v1/compiled/admission/semantics/core.d.ts +35 -0
  78. package/dist/v1/compiled/admission/semantics/core.js +123 -0
  79. package/dist/v1/compiled/admission/semantics/edge.d.ts +8 -0
  80. package/dist/v1/compiled/admission/semantics/edge.js +89 -0
  81. package/dist/v1/compiled/admission/semantics/policy/admit.d.ts +4 -0
  82. package/dist/v1/compiled/admission/semantics/policy/admit.js +63 -0
  83. package/dist/v1/compiled/admission/semantics/policy/callable.d.ts +5 -0
  84. package/dist/v1/compiled/admission/semantics/policy/callable.js +72 -0
  85. package/dist/v1/compiled/admission/semantics/policy/contracts.d.ts +24 -0
  86. package/dist/v1/compiled/admission/semantics/policy/contracts.js +45 -0
  87. package/dist/v1/compiled/admission/semantics/policy/equality.d.ts +8 -0
  88. package/dist/v1/compiled/admission/semantics/policy/equality.js +27 -0
  89. package/dist/v1/compiled/admission/semantics/policy/measure.d.ts +9 -0
  90. package/dist/v1/compiled/admission/semantics/policy/measure.js +81 -0
  91. package/dist/v1/compiled/admission/semantics/policy/parity.d.ts +4 -0
  92. package/dist/v1/compiled/admission/semantics/policy/parity.js +138 -0
  93. package/dist/v1/compiled/admission/semantics/policy/pattern.d.ts +8 -0
  94. package/dist/v1/compiled/admission/semantics/policy/pattern.js +78 -0
  95. package/dist/v1/compiled/admission/semantics/policy/typing.d.ts +28 -0
  96. package/dist/v1/compiled/admission/semantics/policy/typing.js +206 -0
  97. package/dist/v1/compiled/admission/semantics/policy/variants.d.ts +10 -0
  98. package/dist/v1/compiled/admission/semantics/policy/variants.js +65 -0
  99. package/dist/v1/compiled/admission/semantics.d.ts +1 -1
  100. package/dist/v1/compiled/admission/semantics.js +8 -1078
  101. package/dist/v1/compiled/admission/wire/callable.d.ts +6 -0
  102. package/dist/v1/compiled/admission/wire/callable.js +90 -0
  103. package/dist/v1/compiled/admission/wire/class.d.ts +4 -0
  104. package/dist/v1/compiled/admission/wire/class.js +133 -0
  105. package/dist/v1/compiled/admission/wire/core.d.ts +5 -0
  106. package/dist/v1/compiled/admission/wire/core.js +32 -0
  107. package/dist/v1/compiled/admission/wire/dependency.d.ts +14 -0
  108. package/dist/v1/compiled/admission/wire/dependency.js +43 -0
  109. package/dist/v1/compiled/admission/wire/entry.d.ts +5 -0
  110. package/dist/v1/compiled/admission/wire/entry.js +100 -0
  111. package/dist/v1/compiled/admission/wire/pattern.d.ts +12 -0
  112. package/dist/v1/compiled/admission/wire/pattern.js +111 -0
  113. package/dist/v1/compiled/admission/wire/policy.d.ts +10 -0
  114. package/dist/v1/compiled/admission/wire/policy.js +189 -0
  115. package/dist/v1/compiled/admission/wire/program.d.ts +4 -0
  116. package/dist/v1/compiled/admission/wire/program.js +52 -0
  117. package/dist/v1/compiled/admission/wire/property.d.ts +4 -0
  118. package/dist/v1/compiled/admission/wire/property.js +74 -0
  119. package/dist/v1/compiled/admission/wire/reference.d.ts +8 -0
  120. package/dist/v1/compiled/admission/wire/reference.js +33 -0
  121. package/dist/v1/compiled/admission/wire/value.d.ts +29 -0
  122. package/dist/v1/compiled/admission/wire/value.js +98 -0
  123. package/dist/v1/compiled/admission/wire/view.d.ts +3 -0
  124. package/dist/v1/compiled/admission/wire/view.js +17 -0
  125. package/dist/v1/compiled/compiler/compile.js +43 -11
  126. package/dist/v1/compiled/generated.d.ts +10 -0
  127. package/dist/v1/compiled/generated.js +15 -0
  128. package/dist/v1/compiled/loader/load.d.ts +5 -0
  129. package/dist/v1/compiled/loader/load.js +18 -4
  130. package/dist/v1/compiled/model/schema.d.ts +16 -7
  131. package/dist/v1/domain/create.js +18 -28
  132. package/dist/v1/domain/model/domain.d.ts +0 -1
  133. package/dist/v1/domain/model/input.d.ts +3 -0
  134. package/dist/v1/domain/projection/classes.js +13 -41
  135. package/dist/v1/domain/validation/create.d.ts +2 -0
  136. package/dist/v1/domain/validation/create.js +12 -0
  137. package/dist/v1/index.d.ts +5 -2
  138. package/dist/v1/index.js +3 -1
  139. package/dist/v1/language/callable/composition.d.ts +27 -0
  140. package/dist/v1/language/callable/composition.js +52 -0
  141. package/dist/v1/language/callable/executable.d.ts +6 -0
  142. package/dist/v1/language/callable/executable.js +4 -0
  143. package/dist/v1/language/callable/model/callable.d.ts +34 -9
  144. package/dist/v1/language/callable/model/callable.js +3 -1
  145. package/dist/v1/language/callable/resolved.d.ts +23 -8
  146. package/dist/v1/language/class/facets.d.ts +5 -2
  147. package/dist/v1/language/class/inheritance.d.ts +12 -0
  148. package/dist/v1/language/class/inheritance.js +25 -0
  149. package/dist/v1/language/class/lifetime.d.ts +17 -0
  150. package/dist/v1/language/class/lifetime.js +26 -0
  151. package/dist/v1/language/class/model/class.d.ts +8 -4
  152. package/dist/v1/language/class/model/property.d.ts +4 -2
  153. package/dist/v1/language/class/property-values.js +5 -2
  154. package/dist/v1/language/class/resolved.d.ts +25 -15
  155. package/dist/v1/language/core/model/core.d.ts +7 -1
  156. package/dist/v1/language/core/resolved.d.ts +6 -2
  157. package/dist/v1/language/definition/metadata.d.ts +8 -0
  158. package/dist/v1/language/definition/metadata.js +12 -0
  159. package/dist/v1/language/index.d.ts +9 -0
  160. package/dist/v1/language/index.js +6 -0
  161. package/dist/v1/language/policy/analysis/branches.d.ts +4 -3
  162. package/dist/v1/language/policy/analysis/branches.js +54 -12
  163. package/dist/v1/language/policy/analysis/budgets.js +1 -1
  164. package/dist/v1/language/policy/analysis/checks.d.ts +28 -0
  165. package/dist/v1/language/policy/analysis/checks.js +80 -0
  166. package/dist/v1/language/policy/index.d.ts +1 -0
  167. package/dist/v1/language/policy/index.js +1 -0
  168. package/dist/v1/language/policy/model/policy.d.ts +71 -5
  169. package/dist/v1/language/policy/model/policy.js +52 -1
  170. package/dist/v1/language/policy/normalization/normalize.d.ts +12 -1
  171. package/dist/v1/language/policy/normalization/normalize.js +178 -44
  172. package/dist/v1/language/state/index.d.ts +3 -0
  173. package/dist/v1/language/state/index.js +1 -0
  174. package/dist/v1/language/state/machine.d.ts +28 -0
  175. package/dist/v1/language/state/machine.js +40 -0
  176. package/dist/v1/language/state/topology.d.ts +14 -0
  177. package/dist/v1/language/state/topology.js +69 -0
  178. package/dist/v1/language/value/compile/fields.d.ts +1 -1
  179. package/dist/v1/language/value/compile/load.d.ts +4 -2
  180. package/dist/v1/language/value/compile/load.js +22 -1
  181. package/dist/v1/language/value/compile/model.d.ts +16 -1
  182. package/dist/v1/language/value/evaluate/assertions.d.ts +2 -0
  183. package/dist/v1/language/value/evaluate/assertions.js +13 -0
  184. package/dist/v1/language/value/evaluate/evaluator.js +111 -28
  185. package/dist/v1/language/value/evaluate/preparation.d.ts +10 -1
  186. package/dist/v1/language/value/evaluate/preparation.js +17 -26
  187. package/dist/v1/language/value/evaluate/program.js +1 -1
  188. package/dist/v1/language/value/evaluate/validate.d.ts +6 -2
  189. package/dist/v1/language/value/evaluate/validate.js +18 -11
  190. package/dist/v1/language/value/inclusion/includes.d.ts +9 -0
  191. package/dist/v1/language/value/inclusion/includes.js +777 -0
  192. package/dist/v1/language/value/model/blob.d.ts +31 -0
  193. package/dist/v1/language/value/model/blob.js +90 -0
  194. package/dist/v1/language/value/model/instant.d.ts +0 -2
  195. package/dist/v1/language/value/model/instant.js +1 -1
  196. package/dist/v1/language/value/model/schema.d.ts +2 -1
  197. package/dist/v1/language/value/model/schema.js +1 -5
  198. package/dist/v1/language/value/ordering.d.ts +2 -0
  199. package/dist/v1/language/value/ordering.js +4 -8
  200. package/dist/v1/language/value/profile/json.validate.js +1 -1
  201. package/dist/v1/language/value/profile/rules.js +48 -12
  202. package/dist/v1/language/value/reference/registry.d.ts +2 -1
  203. package/dist/v1/language/value/regexp/ast.js +3 -64
  204. package/dist/v1/language/value/regexp/compile.d.ts +32 -3
  205. package/dist/v1/language/value/regexp/compile.js +117 -21
  206. package/dist/v1/language/value/regexp/matcher.d.ts +6 -3
  207. package/dist/v1/language/value/regexp/matcher.js +185 -28
  208. package/dist/v1/language/value/regexp/syntax.d.ts +12 -1
  209. package/dist/v1/language/value/regexp/syntax.js +14 -2
  210. package/dist/v1/language/value/regexp/unicode.d.ts +32 -0
  211. package/dist/v1/language/value/regexp/unicode.js +139 -0
  212. package/dist/v1/language/value/syntax/full-match.js +8 -5
  213. package/dist/v1/language/value/syntax/node-path/validate.js +4 -6
  214. package/dist/v1/language/view/model/view.d.ts +2 -4
  215. package/dist/v1/language/view/resolved.d.ts +2 -2
  216. package/dist/v1/schema/analysis/class.d.ts +36 -6
  217. package/dist/v1/schema/analysis/class.js +31 -66
  218. package/dist/v1/schema/canonical/revision.d.ts +2 -1
  219. package/dist/v1/schema/canonical/revision.js +4 -1
  220. package/dist/v1/schema/compatibility/api.d.ts +3 -0
  221. package/dist/v1/schema/compatibility/api.js +2 -0
  222. package/dist/v1/schema/compatibility/comparators/callables.d.ts +39 -0
  223. package/dist/v1/schema/compatibility/comparators/callables.js +101 -0
  224. package/dist/v1/schema/compatibility/comparators/classes.d.ts +47 -0
  225. package/dist/v1/schema/compatibility/comparators/classes.js +160 -0
  226. package/dist/v1/schema/compatibility/comparators/index.d.ts +12 -0
  227. package/dist/v1/schema/compatibility/comparators/index.js +53 -0
  228. package/dist/v1/schema/compatibility/comparators/members.d.ts +4 -0
  229. package/dist/v1/schema/compatibility/comparators/members.js +49 -0
  230. package/dist/v1/schema/compatibility/comparators/values.d.ts +5 -0
  231. package/dist/v1/schema/compatibility/comparators/values.js +37 -0
  232. package/dist/v1/schema/compatibility/compare.d.ts +5 -0
  233. package/dist/v1/schema/compatibility/compare.js +23 -0
  234. package/dist/v1/schema/compatibility/context.d.ts +19 -0
  235. package/dist/v1/schema/compatibility/context.js +49 -0
  236. package/dist/v1/schema/compatibility/coordinate.d.ts +40 -0
  237. package/dist/v1/schema/compatibility/coordinate.js +38 -0
  238. package/dist/v1/schema/compatibility/diff.d.ts +12 -0
  239. package/dist/v1/schema/compatibility/diff.js +39 -0
  240. package/dist/v1/schema/compatibility/evidence.d.ts +16 -0
  241. package/dist/v1/schema/compatibility/evidence.js +62 -0
  242. package/dist/v1/schema/compatibility/fields.d.ts +194 -0
  243. package/dist/v1/schema/compatibility/fields.js +94 -0
  244. package/dist/v1/schema/compatibility/index.d.ts +6 -0
  245. package/dist/v1/schema/compatibility/index.js +3 -0
  246. package/dist/v1/schema/compatibility/meaning/footprint.d.ts +7 -0
  247. package/dist/v1/schema/compatibility/meaning/footprint.js +59 -0
  248. package/dist/v1/schema/compatibility/meaning/index.d.ts +3 -0
  249. package/dist/v1/schema/compatibility/meaning/index.js +16 -0
  250. package/dist/v1/schema/compatibility/model.d.ts +131 -0
  251. package/dist/v1/schema/compatibility/model.js +1 -0
  252. package/dist/v1/schema/compatibility/references.d.ts +38 -0
  253. package/dist/v1/schema/compatibility/references.js +149 -0
  254. package/dist/v1/schema/compatibility/report.d.ts +27 -0
  255. package/dist/v1/schema/compatibility/report.js +100 -0
  256. package/dist/v1/schema/compatibility/scope.d.ts +36 -0
  257. package/dist/v1/schema/compatibility/scope.js +110 -0
  258. package/dist/v1/schema/compatibility/structure/index.d.ts +3 -0
  259. package/dist/v1/schema/compatibility/structure/index.js +40 -0
  260. package/dist/v1/schema/compatibility/structure/inheritance.d.ts +7 -0
  261. package/dist/v1/schema/compatibility/structure/inheritance.js +68 -0
  262. package/dist/v1/schema/compatibility/structure/requirements.d.ts +7 -0
  263. package/dist/v1/schema/compatibility/structure/requirements.js +97 -0
  264. package/dist/v1/schema/compatibility/subjects.d.ts +39 -0
  265. package/dist/v1/schema/compatibility/subjects.js +143 -0
  266. package/dist/v1/schema/compatibility/versioning/index.d.ts +8 -0
  267. package/dist/v1/schema/compatibility/versioning/index.js +50 -0
  268. package/dist/v1/schema/compatibility/versioning/members.d.ts +12 -0
  269. package/dist/v1/schema/compatibility/versioning/members.js +47 -0
  270. package/dist/v1/schema/compatibility/versioning/surface.d.ts +11 -0
  271. package/dist/v1/schema/compatibility/versioning/surface.js +61 -0
  272. package/dist/v1/schema/diagnostic.d.ts +1 -1
  273. package/dist/v1/schema/fingerprint.d.ts +2 -0
  274. package/dist/v1/schema/fingerprint.js +1 -0
  275. package/dist/v1/schema/index.d.ts +4 -3
  276. package/dist/v1/schema/index.js +2 -1
  277. package/dist/v1/schema/model/schema.d.ts +8 -11
  278. package/dist/v1/schema/normalization/domain.js +57 -13
  279. package/dist/v1/schema/resolution/definition.index.d.ts +1 -2
  280. package/dist/v1/schema/resolution/definition.index.js +0 -3
  281. package/dist/v1/schema/resolution/domain.d.ts +4 -1
  282. package/dist/v1/schema/resolution/domain.js +26 -18
  283. package/dist/v1/schema/resolution/origins.d.ts +28 -5
  284. package/dist/v1/schema/resolution/origins.js +68 -31
  285. package/dist/v1/schema/validation/callable.d.ts +4 -0
  286. package/dist/v1/schema/validation/callable.js +39 -0
  287. package/dist/v1/schema/validation/class.d.ts +10 -0
  288. package/dist/v1/schema/validation/class.js +79 -60
  289. package/dist/v1/schema/validation/core.js +83 -55
  290. package/dist/v1/schema/validation/domain.d.ts +2 -1
  291. package/dist/v1/schema/validation/domain.js +2 -0
  292. package/dist/v1/schema/validation/domain.structure.d.ts +0 -2
  293. package/dist/v1/schema/validation/domain.structure.js +214 -171
  294. package/dist/v1/schema/validation/policy/budgets.js +36 -6
  295. package/dist/v1/schema/validation/policy/context.js +5 -16
  296. package/dist/v1/schema/validation/policy/objects.d.ts +4 -0
  297. package/dist/v1/schema/validation/policy/objects.js +71 -0
  298. package/dist/v1/schema/validation/policy/references.js +16 -4
  299. package/dist/v1/schema/validation/policy/typing.d.ts +2 -0
  300. package/dist/v1/schema/validation/policy/typing.js +55 -7
  301. package/dist/v1/schema/validation/policy/uses.js +73 -99
  302. package/dist/v1/schema/validation/value-api.d.ts +2 -0
  303. package/dist/v1/schema/validation/value-api.js +1 -0
  304. package/dist/v1/schema/validation/value.js +7 -1
  305. package/dist/v1/schema/validation/view.js +14 -9
  306. package/dist/value/accept.d.ts +9 -0
  307. package/dist/value/accept.js +106 -7
  308. package/dist/value/canonical.d.ts +3 -0
  309. package/dist/value/canonical.js +22 -6
  310. package/dist/value/immutable.optimization.d.ts +15 -0
  311. package/dist/value/immutable.optimization.js +34 -0
  312. package/dist/value/index.d.ts +1 -1
  313. package/dist/value/index.js +1 -1
  314. package/dist/value/json.d.ts +1 -1
  315. package/dist/value/json.js +1 -1
  316. package/dist/value/limits.d.ts +1 -1
  317. package/dist/value/unicode.d.ts +4 -1
  318. package/dist/value/unicode.js +28 -0
  319. package/package.json +20 -5
  320. package/dist/v1/schema/compatibility/meaning.d.ts +0 -29
  321. package/dist/v1/schema/compatibility/meaning.js +0 -605
@@ -0,0 +1,110 @@
1
+ import { compareUnicode } from '../../addressing/ordering.js';
2
+ import { SchemaError, diagnostic } from '../diagnostic.js';
3
+ import { knownDomainClosure } from '../resolution/closure.js';
4
+ import { resolve } from '../resolution/domain.js';
5
+ import { contextOf } from './context.js';
6
+ import { policyReliance, rootReferences, schemaIdentity, usageOf } from './references.js';
7
+ import { capabilityCoordinates, coordinateForKey, resolveSubject } from './subjects.js';
8
+ export function prepare(request) {
9
+ const { scope, target } = request;
10
+ if (scope.kind === 'members') {
11
+ const { source, roots: keys } = scope;
12
+ if (source.origin !== target.origin)
13
+ throw new SchemaError([
14
+ diagnostic('DM_MEMBER_ORIGIN_MISMATCH', '/target/origin', `Member comparison target ${target.origin} does not match source ${source.origin}.`),
15
+ ]);
16
+ if (!Array.isArray(keys) || keys.length === 0 || new Set(keys).size !== keys.length) {
17
+ throw new SchemaError([
18
+ diagnostic('DM_MEMBER_ROOT_INVALID', '/roots', 'Member comparison roots must be one non-empty duplicate-free Key set.'),
19
+ ]);
20
+ }
21
+ return selectMembers(source, target, keys);
22
+ }
23
+ const { dependent } = scope;
24
+ const { source, context: before } = retainedContext(dependent, target.origin, '/target/origin');
25
+ const keys = scope.capabilities;
26
+ if (keys !== undefined && !Array.isArray(keys)) {
27
+ throw new SchemaError([
28
+ diagnostic('DM_CAPABILITY_INVALID', '/capabilities', 'Declared capabilities must be one Key list.'),
29
+ ]);
30
+ }
31
+ const usage = usageOf(dependent, 'capability');
32
+ const capabilities = capabilityCoordinates(before, source, keys ?? []).map((coordinate) => ({
33
+ coordinate,
34
+ usage,
35
+ }));
36
+ return comparisonContext({
37
+ kind: 'dependency',
38
+ source,
39
+ target,
40
+ dependent,
41
+ before,
42
+ roots: [...rootReferences(dependent), ...capabilities],
43
+ capabilities,
44
+ reliance: policyReliance(dependent, source.origin),
45
+ });
46
+ }
47
+ /**
48
+ * Select distinct Keys of the source against a target the caller checked to be of the same origin.
49
+ * The selection may be empty, which a public request cannot be: `requiredBump` selects every member
50
+ * of a version that may declare none.
51
+ */
52
+ export function selectMembers(source, target, keys) {
53
+ resolve(source);
54
+ const before = contextOf(source);
55
+ return comparisonContext({
56
+ kind: 'members',
57
+ source,
58
+ target,
59
+ before,
60
+ roots: keys.map((key, index) => ({
61
+ coordinate: coordinateForKey(before, source, key, index),
62
+ usage: usageOf(source, 'selection', key),
63
+ })),
64
+ capabilities: [],
65
+ reliance: [],
66
+ });
67
+ }
68
+ function comparisonContext({ kind, source, target, dependent, before, roots, capabilities, reliance, }) {
69
+ resolve(target);
70
+ const after = contextOf(target);
71
+ const pairs = new Map();
72
+ return {
73
+ source,
74
+ target,
75
+ dependent,
76
+ before,
77
+ after,
78
+ roots,
79
+ capabilities,
80
+ reliance,
81
+ scope: Object.freeze({
82
+ kind,
83
+ source: schemaIdentity(source),
84
+ target: schemaIdentity(target),
85
+ ...(dependent === undefined ? {} : { dependent: schemaIdentity(dependent) }),
86
+ roots: Object.freeze([...new Set(roots.map(({ coordinate }) => coordinate.key))].sort(compareUnicode)),
87
+ }),
88
+ pair(coordinate) {
89
+ let pair = pairs.get(coordinate.key);
90
+ if (pair === undefined) {
91
+ pair = {
92
+ coordinate,
93
+ source: resolveSubject({ context: before, coordinate }),
94
+ target: resolveSubject({ context: after, coordinate }),
95
+ };
96
+ pairs.set(coordinate.key, pair);
97
+ }
98
+ return pair;
99
+ },
100
+ };
101
+ }
102
+ function retainedContext(dependent, origin, path) {
103
+ resolve(dependent);
104
+ const source = (knownDomainClosure(dependent) ?? []).find((entry) => entry.schema.origin === origin)?.schema;
105
+ if (source === undefined)
106
+ throw new SchemaError([
107
+ diagnostic('DM_DEPENDENCY_NOT_RETAINED', path, `Domain ${dependent.origin} was not admitted with a dependency at ${origin}.`),
108
+ ]);
109
+ return { source, context: contextOf(dependent) };
110
+ }
@@ -0,0 +1,3 @@
1
+ import type { StructureComparison } from '../model.js';
2
+ import type { ComparisonContext } from '../scope.js';
3
+ export declare function analyzeStructure(context: ComparisonContext): StructureComparison;
@@ -0,0 +1,40 @@
1
+ import { evidenceOf } from '../evidence.js';
2
+ import { createReport } from '../report.js';
3
+ import { compareInheritance } from './inheritance.js';
4
+ import { compareRequirements } from './requirements.js';
5
+ export function analyzeStructure(context) {
6
+ const report = createReport();
7
+ compareRequirements({ context, report });
8
+ compareInheritance({ context, report });
9
+ const result = { scope: context.scope, ...report.finish() };
10
+ return Object.freeze({
11
+ kind: 'structure',
12
+ ...result,
13
+ compatible: result.assessments.every(({ satisfied }) => satisfied),
14
+ // Each version adds one requirement policy and applies only when its fact is present: 3 a
15
+ // declared capability root, 4 a lost effective Property of a reached Class or a failed Policy
16
+ // reliance, facts recorded only when they fail. Without one, evidence keeps its version-2 bytes.
17
+ evidence: evidenceOf({
18
+ kind: 'structure',
19
+ version: recordsFailureOnlyFact(result.assessments)
20
+ ? 4
21
+ : context.capabilities.length > 0
22
+ ? 3
23
+ : 2,
24
+ ...result,
25
+ }),
26
+ });
27
+ }
28
+ /**
29
+ * The facts structure records only when they fail: a referenced or inherited Class that lost an
30
+ * effective Property, and what a dependent Policy relies on (a Method object, a matched Edge's
31
+ * endpoints).
32
+ */
33
+ const FAILURE_ONLY_FACETS = new Set([
34
+ 'class.properties',
35
+ 'method.object',
36
+ 'class.endpoints',
37
+ ]);
38
+ function recordsFailureOnlyFact(assessments) {
39
+ return assessments.some(({ requirement }) => FAILURE_ONLY_FACETS.has(requirement.kind));
40
+ }
@@ -0,0 +1,7 @@
1
+ import type { Report } from '../report.js';
2
+ import type { ComparisonContext } from '../scope.js';
3
+ /** Recompose retained descendants using the same obligations as source and compiled admission. */
4
+ export declare function compareInheritance({ context, report, }: {
5
+ readonly context: ComparisonContext;
6
+ readonly report: Report;
7
+ }): void;
@@ -0,0 +1,68 @@
1
+ import { json } from '@astrale-os/kernel-dsl/value';
2
+ import { compareUnicode, definitionRefIndex } from '../../../addressing/ordering.js';
3
+ import { composeMethods } from '../../../language/callable/composition.js';
4
+ import { sameMethodSignature } from '../../analysis/class.js';
5
+ import { methodInheritance } from '../comparators/callables.js';
6
+ import { effectiveDefinition, requireOwner } from '../context.js';
7
+ import { classCoordinate, keyForDefinitionRef } from '../coordinate.js';
8
+ import { inherits, usageOf } from '../references.js';
9
+ import { resolveSubject } from '../subjects.js';
10
+ /** Recompose retained descendants using the same obligations as source and compiled admission. */
11
+ export function compareInheritance({ context, report, }) {
12
+ if (context.dependent === undefined)
13
+ return;
14
+ const memo = new Map();
15
+ const visit = (ref) => {
16
+ const index = definitionRefIndex(ref);
17
+ const retained = memo.get(index);
18
+ if (retained !== undefined)
19
+ return retained;
20
+ const owner = requireOwner(context.before, ref, keyForDefinitionRef(ref));
21
+ const original = effectiveDefinition(context.before, owner, ref);
22
+ if (ref.origin === context.target.origin) {
23
+ const replacement = effectiveDefinition(context.after, context.target, ref);
24
+ return { composition: replacement ?? original, affected: replacement !== undefined };
25
+ }
26
+ const parents = original.declaration.extends.map(visit);
27
+ if (!parents.some((parent) => parent.affected)) {
28
+ const unchanged = { composition: original, affected: false };
29
+ memo.set(index, unchanged);
30
+ return unchanged;
31
+ }
32
+ const declaration = original.declaration;
33
+ const own = new Map(Object.keys(declaration.kind === 'node' ? declaration.methods : {}).map((name) => [
34
+ name,
35
+ original.methods.get(name),
36
+ ]));
37
+ const issues = [];
38
+ const composition = composeMethods(parents.map((parent) => parent.composition), own, declaration.abstract, (left, right) => sameMethodSignature(left.declaration, right.declaration), (_message, issue) => issues.push(issue));
39
+ const coordinate = classCoordinate(ref);
40
+ const subject = resolveSubject({ context: context.before, coordinate });
41
+ report.note({ coordinate, usage: usageOf(owner, 'extends', coordinate.key) });
42
+ report.record({
43
+ pair: { coordinate, source: subject, target: subject },
44
+ facet: 'class.composition',
45
+ before: compositionValue(original, []),
46
+ after: compositionValue(composition, issues),
47
+ requirement: { kind: 'class.composition', satisfied: issues.length === 0 },
48
+ });
49
+ const result = { composition, affected: true };
50
+ memo.set(index, result);
51
+ return result;
52
+ };
53
+ for (const declaration of Object.values(context.dependent.classes))
54
+ visit(declaration.ref);
55
+ for (const root of context.roots) {
56
+ if (root.coordinate.kind === 'class' && inherits(root.usage))
57
+ visit(root.coordinate.ref);
58
+ }
59
+ }
60
+ function compositionValue(composition, issues) {
61
+ return {
62
+ requirements: [...composition.requirements.values()]
63
+ .sort((a, b) => compareUnicode(a.key, b.key))
64
+ .map(methodInheritance),
65
+ frontier: [...composition.frontier.keys()].sort(compareUnicode),
66
+ issues: [...issues].sort((a, b) => compareUnicode(json.serialize(a), json.serialize(b))),
67
+ };
68
+ }
@@ -0,0 +1,7 @@
1
+ import type { Report } from '../report.js';
2
+ import type { ComparisonContext } from '../scope.js';
3
+ /** Structure follows data and abstract obligations; concrete IO never expands its requirements. */
4
+ export declare function compareRequirements({ context, report, }: {
5
+ readonly context: ComparisonContext;
6
+ readonly report: Report;
7
+ }): void;
@@ -0,0 +1,97 @@
1
+ import { Key } from '../../../addressing/index.js';
2
+ import { compareAddedProperties, compareLostProperties } from '../comparators/classes.js';
3
+ import { compareFacet } from '../comparators/index.js';
4
+ import { fingerprintMeaning } from '../comparators/values.js';
5
+ import { contextInvalid } from '../context.js';
6
+ import { methodCoordinate } from '../coordinate.js';
7
+ import { callableReferences, classReferences, inherits, memberReferences, usageOf, valueReferences, } from '../references.js';
8
+ /** Structure follows data and abstract obligations; concrete IO never expands its requirements. */
9
+ export function compareRequirements({ context, report, }) {
10
+ const queue = [...context.roots];
11
+ const visited = new Set();
12
+ for (const reference of queue) {
13
+ report.note(reference);
14
+ const { coordinate, usage } = reference;
15
+ const visit = `${coordinate.key}:${usage.relation}`;
16
+ if (visited.has(visit))
17
+ continue;
18
+ visited.add(visit);
19
+ const pair = context.pair(coordinate);
20
+ const subject = pair.source;
21
+ if (subject === undefined)
22
+ throw contextInvalid(`Retained acceptance context has no meaning for ${coordinate.key}.`, coordinate.key);
23
+ let facet;
24
+ switch (subject.kind) {
25
+ case 'class': {
26
+ facet = inherits(usage) ? 'class.inherit' : 'class.reference';
27
+ queue.push(...classReferences(subject, false));
28
+ if (inherits(usage)) {
29
+ queue.push(...classReferences(subject, true));
30
+ for (const method of subject.analysis.requirements.values())
31
+ queue.push({
32
+ coordinate: methodCoordinate(method.owner, method.name),
33
+ usage: usageOf(subject.schema, 'abstract', coordinate.key),
34
+ });
35
+ }
36
+ break;
37
+ }
38
+ case 'property':
39
+ facet = 'property';
40
+ queue.push(...valueReferences(subject));
41
+ break;
42
+ case 'method': {
43
+ facet = usage.relation === 'abstract' ? 'method.inheritance' : 'method.existence';
44
+ if (facet === 'method.inheritance')
45
+ queue.push(...callableReferences(subject));
46
+ break;
47
+ }
48
+ case 'member': {
49
+ facet =
50
+ subject.coordinate.ref.kind === 'function'
51
+ ? 'function.existence'
52
+ : subject.coordinate.ref.kind;
53
+ if (facet !== 'function.existence')
54
+ queue.push(...memberReferences(subject));
55
+ }
56
+ }
57
+ if (Key.origin(coordinate.key) !== context.source.origin)
58
+ continue;
59
+ // Class membership does not establish an invocation dependency. Explicit member selection,
60
+ // a Method the dependent declares as a capability, and inherited abstract obligations do.
61
+ const required = facet !== 'method.existence' ||
62
+ usage.relation === 'selection' ||
63
+ usage.relation === 'capability';
64
+ report.record({
65
+ pair,
66
+ facet,
67
+ ...compareFacet({ context, pair, facet }),
68
+ ...(required ? { requirement: { kind: facet } } : {}),
69
+ });
70
+ if (facet === 'class.inherit')
71
+ compareAddedProperties({ context, pair, report });
72
+ if (subject.kind === 'class')
73
+ compareLostProperties({ pair, report });
74
+ }
75
+ compareReliance({ context, report });
76
+ }
77
+ /**
78
+ * What a dependent Policy relies on is recorded only when it fails: a Method it names that is gone
79
+ * or no longer executable by its owner, or an Edge it matches whose orientation or accepted endpoint
80
+ * Classes changed. A held reliance adds no fact, so a compatible comparison keeps its evidence bytes
81
+ * and no coordinate minted from it moves; a failed one is a refusal, from which none is minted.
82
+ */
83
+ function compareReliance({ context, report, }) {
84
+ for (const reference of context.reliance) {
85
+ const pair = context.pair(reference.coordinate);
86
+ if (pair.source === undefined)
87
+ throw contextInvalid(`Retained acceptance context has no meaning for ${reference.coordinate.key}.`, reference.coordinate.key);
88
+ const facet = reference.coordinate.kind === 'method' ? 'method.object' : 'class.endpoints';
89
+ const { before, after } = compareFacet({ context, pair, facet });
90
+ if (before !== undefined &&
91
+ after !== undefined &&
92
+ fingerprintMeaning(before) === fingerprintMeaning(after))
93
+ continue;
94
+ report.note(reference);
95
+ report.record({ pair, facet, before, after, requirement: { kind: facet } });
96
+ }
97
+ }
@@ -0,0 +1,39 @@
1
+ import type { Key as SemanticKey } from '../../addressing/index.js';
2
+ import type { DefinitionAnalysis, EffectiveField, EffectiveMethod } from '../analysis/class.js';
3
+ import type { DomainSchema } from '../model/schema.js';
4
+ import type { Context } from './context.js';
5
+ import type { ClassCoordinate, Coordinate, MemberCoordinate, MethodCoordinate, PropertyCoordinate } from './coordinate.js';
6
+ import type { Subject } from './model.js';
7
+ export type ResolvedSubject = {
8
+ readonly kind: 'class';
9
+ readonly coordinate: ClassCoordinate;
10
+ readonly schema: DomainSchema;
11
+ readonly analysis: DefinitionAnalysis;
12
+ } | {
13
+ readonly kind: 'property';
14
+ readonly coordinate: PropertyCoordinate;
15
+ readonly schema: DomainSchema;
16
+ readonly field: EffectiveField;
17
+ } | {
18
+ readonly kind: 'method';
19
+ readonly coordinate: MethodCoordinate;
20
+ readonly schema: DomainSchema;
21
+ readonly method: EffectiveMethod;
22
+ } | {
23
+ readonly kind: 'member';
24
+ readonly coordinate: MemberCoordinate;
25
+ readonly schema: DomainSchema;
26
+ };
27
+ /** Resolve a trusted coordinate within one exact accepted closure. */
28
+ export declare function resolveSubject({ context, coordinate, }: {
29
+ readonly context: Context;
30
+ readonly coordinate: Coordinate;
31
+ }): ResolvedSubject | undefined;
32
+ export declare function identityOf(coordinate: Coordinate): Subject;
33
+ /** Resolve one caller-supplied Key of the source into an exact coordinate that exists there. */
34
+ export declare function coordinateForKey(context: Context, source: DomainSchema, input: SemanticKey, index: number): Coordinate;
35
+ /**
36
+ * Resolve the Function, Method and Class Keys a dependent declares as capabilities into exact
37
+ * coordinates of its retained source. Keys of other origins belong to other comparisons.
38
+ */
39
+ export declare function capabilityCoordinates(context: Context, source: DomainSchema, capabilities: readonly SemanticKey[]): readonly Coordinate[];
@@ -0,0 +1,143 @@
1
+ import { Key } from '../../addressing/index.js';
2
+ import { SchemaError, diagnostic } from '../diagnostic.js';
3
+ import { effectiveDefinition, effectiveMethod } from './context.js';
4
+ import { classCoordinate, keyReference, memberCoordinate, methodCoordinate, propertyCoordinate, } from './coordinate.js';
5
+ /** Resolve a trusted coordinate within one exact accepted closure. */
6
+ export function resolveSubject({ context, coordinate, }) {
7
+ const schema = context.schemas.get(Key.origin(coordinate.key));
8
+ if (schema === undefined)
9
+ return undefined;
10
+ if (coordinate.kind === 'member') {
11
+ const { ref } = coordinate;
12
+ const declaration = ref.kind === 'function'
13
+ ? schema.functions[ref.name]
14
+ : ref.kind === 'policy'
15
+ ? schema.policies[ref.name]
16
+ : ref.kind === 'view'
17
+ ? schema.views[ref.name]
18
+ : schema.core.nodes[ref.name];
19
+ return declaration === undefined ? undefined : { kind: 'member', coordinate, schema };
20
+ }
21
+ const analysis = effectiveDefinition(context, schema, coordinate.kind === 'class' ? coordinate.ref : coordinate.owner);
22
+ if (analysis === undefined)
23
+ return undefined;
24
+ if (coordinate.kind === 'class')
25
+ return { kind: 'class', coordinate, schema, analysis };
26
+ if (coordinate.kind === 'property') {
27
+ const field = analysis.properties.get(coordinate.key);
28
+ return field === undefined ? undefined : { kind: 'property', coordinate, schema, field };
29
+ }
30
+ const method = effectiveMethod(analysis, coordinate.key);
31
+ return method === undefined ? undefined : { kind: 'method', coordinate, schema, method };
32
+ }
33
+ export function identityOf(coordinate) {
34
+ return Object.freeze({
35
+ key: coordinate.key,
36
+ kind: coordinate.kind === 'member' ? coordinate.ref.kind : coordinate.kind,
37
+ });
38
+ }
39
+ /** Resolve one caller-supplied Key of the source into an exact coordinate that exists there. */
40
+ export function coordinateForKey(context, source, input, index) {
41
+ let key;
42
+ try {
43
+ key = Key(input);
44
+ }
45
+ catch {
46
+ return invalidMemberRoot(input, index, 'is not a canonical semantic Key');
47
+ }
48
+ if (Key.origin(key) !== source.origin) {
49
+ return invalidMemberRoot(key, index, `belongs to ${Key.origin(key)}, not source ${source.origin}`);
50
+ }
51
+ const reference = keyReference(key);
52
+ let coordinate;
53
+ if (reference.member !== undefined && reference.ownerName !== undefined) {
54
+ if (source.classes[reference.ownerName] === undefined) {
55
+ return invalidMemberRoot(key, index, 'has no exact owning Definition');
56
+ }
57
+ const owner = { origin: source.origin, kind: 'class', name: reference.ownerName };
58
+ coordinate =
59
+ reference.member === 'property'
60
+ ? propertyCoordinate(owner, reference.name)
61
+ : methodCoordinate(owner, reference.name);
62
+ }
63
+ else if (reference.kind === 'class') {
64
+ if (source.classes[reference.name] === undefined) {
65
+ return invalidMemberRoot(key, index, 'does not exist in the source');
66
+ }
67
+ // Explicit Class selection compares its surface without inferring inheritance.
68
+ coordinate = classCoordinate({ origin: source.origin, kind: 'class', name: reference.name });
69
+ }
70
+ else {
71
+ coordinate = memberCoordinate({
72
+ origin: source.origin,
73
+ kind: reference.kind,
74
+ name: reference.name,
75
+ });
76
+ }
77
+ if (resolveSubject({ context, coordinate }) === undefined) {
78
+ return invalidMemberRoot(key, index, 'does not exist in the source');
79
+ }
80
+ return coordinate;
81
+ }
82
+ /**
83
+ * Resolve the Function, Method and Class Keys a dependent declares as capabilities into exact
84
+ * coordinates of its retained source. Keys of other origins belong to other comparisons.
85
+ */
86
+ export function capabilityCoordinates(context, source, capabilities) {
87
+ return capabilities.flatMap((key, index) => {
88
+ if (!Key.is(key))
89
+ return invalidCapability(key, index, 'is not a canonical semantic Key');
90
+ if (Key.origin(key) !== source.origin)
91
+ return [];
92
+ const coordinate = capabilityCoordinate(source, key);
93
+ if (coordinate === undefined) {
94
+ return invalidCapability(key, index, 'is not a Function, Method or Class');
95
+ }
96
+ if (resolveSubject({ context, coordinate }) === undefined) {
97
+ return invalidCapability(key, index, `does not exist in the retained ${source.origin}`);
98
+ }
99
+ return [coordinate];
100
+ });
101
+ }
102
+ /** A capability names a Function, a Method by its declaring Class, or a Class. */
103
+ function capabilityCoordinate(source, key) {
104
+ const { kind, name, member, ownerName } = keyReference(key);
105
+ const { origin } = source;
106
+ if (member === 'method')
107
+ return methodCoordinate({ origin, kind: 'class', name: ownerName }, name);
108
+ if (member !== undefined)
109
+ return undefined;
110
+ if (kind === 'class')
111
+ return classCoordinate({ origin, kind: 'class', name });
112
+ if (kind === 'function')
113
+ return memberCoordinate({ origin, kind: 'function', name });
114
+ return undefined;
115
+ }
116
+ function invalidCapability(key, index, reason) {
117
+ throw new SchemaError([
118
+ diagnostic('DM_CAPABILITY_INVALID', `/capabilities/${index}`, `Capability ${shown(key)} ${reason}.`, typeof key === 'string' ? key : undefined),
119
+ ]);
120
+ }
121
+ function invalidMemberRoot(key, index, reason) {
122
+ throw new SchemaError([
123
+ diagnostic('DM_MEMBER_ROOT_INVALID', `/roots/${index}`, `Key ${shown(key)} ${reason}.`, typeof key === 'string' ? key : undefined),
124
+ ]);
125
+ }
126
+ /**
127
+ * A caller-supplied item as diagnostic text. Formatting never throws, so the caller always gets the
128
+ * diagnostic: a bigint is shown as its literal, and another item JSON cannot encode, such as a cyclic
129
+ * object, is named by its type.
130
+ */
131
+ function shown(item) {
132
+ if (typeof item === 'bigint')
133
+ return `${item}n`;
134
+ try {
135
+ const text = JSON.stringify(item);
136
+ if (text !== undefined)
137
+ return text;
138
+ }
139
+ catch {
140
+ // Not encodable as JSON: named by its type below.
141
+ }
142
+ return `<${typeof item}>`;
143
+ }
@@ -0,0 +1,8 @@
1
+ import type { DomainSchema } from '../../model/schema.js';
2
+ import type { RequiredBump } from '../model.js';
3
+ /**
4
+ * Minimum schema bump: unsatisfied requirements are major, additions minor, other changes patch.
5
+ * Concrete callable authorization and code behavior are outside this floor; abstract Method auth
6
+ * belongs to the inherited signature. Version arithmetic stays with the caller.
7
+ */
8
+ export declare function requiredBump(previous: DomainSchema, next: DomainSchema): RequiredBump;
@@ -0,0 +1,50 @@
1
+ import { deepFreeze } from '../../canonical/freeze.js';
2
+ import { SchemaError, diagnostic } from '../../diagnostic.js';
3
+ import { compareFootprint } from '../meaning/footprint.js';
4
+ import { schemaIdentity } from '../references.js';
5
+ import { createReport } from '../report.js';
6
+ import { selectMembers } from '../scope.js';
7
+ import { compareRequirements } from '../structure/requirements.js';
8
+ import { compareAdditions, memberCoordinates } from './members.js';
9
+ import { compareSurface } from './surface.js';
10
+ const LEVELS = ['patch', 'minor', 'major'];
11
+ /**
12
+ * Minimum schema bump: unsatisfied requirements are major, additions minor, other changes patch.
13
+ * Concrete callable authorization and code behavior are outside this floor; abstract Method auth
14
+ * belongs to the inherited signature. Version arithmetic stays with the caller.
15
+ */
16
+ export function requiredBump(previous, next) {
17
+ if (previous.origin !== next.origin)
18
+ throw new SchemaError([
19
+ diagnostic('DM_MEMBER_ORIGIN_MISMATCH', '/next/origin', `Next version ${next.origin} does not match previous version ${previous.origin}.`),
20
+ ]);
21
+ const identities = { previous: schemaIdentity(previous), next: schemaIdentity(next) };
22
+ if (identities.previous.revision === identities.next.revision)
23
+ return deepFreeze({ level: 'patch', ...identities, changes: [] });
24
+ const members = memberCoordinates(previous);
25
+ const context = selectMembers(previous, next, members.map(({ key }) => key));
26
+ // Surface observations must win when an existing obligation becomes newly imposed on a Class.
27
+ const report = createReport();
28
+ compareSurface({ context, report });
29
+ compareRequirements({ context, report });
30
+ compareFootprint({ context, report });
31
+ compareAdditions({ context, report, previous: members });
32
+ const { entries, assessments } = report.finish();
33
+ const unsatisfied = new Set(assessments.filter(({ satisfied }) => !satisfied).map(({ observation }) => observation.id));
34
+ const changes = entries.flatMap(({ subject, observations }) => observations
35
+ .filter(({ state }) => state !== 'equal')
36
+ .map((observation) => ({
37
+ subject,
38
+ observation,
39
+ bump: unsatisfied.has(observation.id)
40
+ ? 'major'
41
+ : observation.state === 'added'
42
+ ? 'minor'
43
+ : 'patch',
44
+ })));
45
+ return deepFreeze({
46
+ level: changes.reduce((level, { bump }) => (LEVELS.indexOf(bump) > LEVELS.indexOf(level) ? bump : level), 'patch'),
47
+ ...identities,
48
+ changes,
49
+ });
50
+ }
@@ -0,0 +1,12 @@
1
+ import type { DomainSchema } from '../../model/schema.js';
2
+ import type { Coordinate } from '../coordinate.js';
3
+ import type { Report } from '../report.js';
4
+ import type { ComparisonContext } from '../scope.js';
5
+ /** Inherited members count once, at their declaring Class. */
6
+ export declare function memberCoordinates(schema: DomainSchema): readonly Coordinate[];
7
+ /** New declarations impose no requirements here; the surface pass checks obligations on existing Classes. */
8
+ export declare function compareAdditions({ context, report, previous, }: {
9
+ readonly context: ComparisonContext;
10
+ readonly report: Report;
11
+ readonly previous: readonly Coordinate[];
12
+ }): void;
@@ -0,0 +1,47 @@
1
+ import { compareFacet } from '../comparators/index.js';
2
+ import { classCoordinate, memberCoordinate, methodCoordinate, propertyCoordinate, } from '../coordinate.js';
3
+ /** Inherited members count once, at their declaring Class. */
4
+ export function memberCoordinates(schema) {
5
+ const result = [];
6
+ for (const declaration of Object.values(schema.classes)) {
7
+ result.push(classCoordinate(declaration.ref));
8
+ for (const name of Object.keys(declaration.properties))
9
+ result.push(propertyCoordinate(declaration.ref, name));
10
+ if (declaration.kind === 'node')
11
+ for (const name of Object.keys(declaration.methods))
12
+ result.push(methodCoordinate(declaration.ref, name));
13
+ }
14
+ for (const { ref } of [
15
+ ...Object.values(schema.functions),
16
+ ...Object.values(schema.policies),
17
+ ...Object.values(schema.views),
18
+ ...Object.values(schema.core.nodes),
19
+ ])
20
+ result.push(memberCoordinate(ref));
21
+ return result;
22
+ }
23
+ /** New declarations impose no requirements here; the surface pass checks obligations on existing Classes. */
24
+ export function compareAdditions({ context, report, previous, }) {
25
+ const known = new Set(previous.map(({ key }) => key));
26
+ for (const coordinate of memberCoordinates(context.target)) {
27
+ if (known.has(coordinate.key))
28
+ continue;
29
+ const pair = context.pair(coordinate);
30
+ for (const facet of selectedFacets(coordinate))
31
+ report.record({ pair, facet, ...compareFacet({ context, pair, facet }) });
32
+ }
33
+ }
34
+ function selectedFacets(coordinate) {
35
+ switch (coordinate.kind) {
36
+ case 'class':
37
+ return ['class.reference'];
38
+ case 'property':
39
+ return ['property'];
40
+ case 'method':
41
+ return ['method.existence', 'method.signature'];
42
+ case 'member':
43
+ return coordinate.ref.kind === 'function'
44
+ ? ['function.existence', 'function.signature']
45
+ : [coordinate.ref.kind];
46
+ }
47
+ }
@@ -0,0 +1,11 @@
1
+ import type { Report } from '../report.js';
2
+ import type { ComparisonContext } from '../scope.js';
3
+ /**
4
+ * Compare inherited contracts and newly imposed obligations on existing Classes.
5
+ * Obligations are reported at their declaring Method: changed signatures retain their comparison;
6
+ * an unchanged obligation newly inherited by a Class is added and unsatisfied.
7
+ */
8
+ export declare function compareSurface({ context, report, }: {
9
+ readonly context: ComparisonContext;
10
+ readonly report: Report;
11
+ }): void;