@astrale-os/kernel-dsl 1.0.0-beta.2 → 1.0.0-beta.20

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 (307) hide show
  1. package/dist/v1/addressing/class-key.js +3 -3
  2. package/dist/v1/addressing/definition-ref.js +21 -37
  3. package/dist/v1/addressing/domain-dependency.d.ts +0 -6
  4. package/dist/v1/addressing/domain-dependency.js +1 -6
  5. package/dist/v1/addressing/key.d.ts +4 -1
  6. package/dist/v1/addressing/key.js +23 -3
  7. package/dist/v1/addressing/ordering.d.ts +2 -0
  8. package/dist/v1/addressing/ordering.js +4 -0
  9. package/dist/v1/addressing/patterns.d.ts +1 -1
  10. package/dist/v1/addressing/patterns.js +2 -6
  11. package/dist/v1/builder/callable/authoring.d.ts +11 -5
  12. package/dist/v1/builder/callable/authoring.js +2 -0
  13. package/dist/v1/builder/class/authoring.d.ts +94 -224
  14. package/dist/v1/builder/class/authoring.js +31 -33
  15. package/dist/v1/builder/class/handle.d.ts +27 -0
  16. package/dist/v1/builder/class/handle.js +1 -0
  17. package/dist/v1/builder/class/input.d.ts +159 -0
  18. package/dist/v1/builder/class/projection.d.ts +129 -0
  19. package/dist/v1/builder/class/projection.js +1 -0
  20. package/dist/v1/builder/class/property.d.ts +3 -9
  21. package/dist/v1/builder/class/property.js +1 -0
  22. package/dist/v1/builder/core/authoring.d.ts +1 -1
  23. package/dist/v1/builder/index.d.ts +5 -2
  24. package/dist/v1/builder/lowering/callable.js +1 -0
  25. package/dist/v1/builder/lowering/class.d.ts +9 -1
  26. package/dist/v1/builder/lowering/class.js +62 -17
  27. package/dist/v1/builder/lowering/policy.js +2 -0
  28. package/dist/v1/builder/lowering/property-keys.d.ts +27 -0
  29. package/dist/v1/builder/lowering/property-keys.js +108 -0
  30. package/dist/v1/builder/lowering/schema/compile.js +11 -6
  31. package/dist/v1/builder/lowering/schema/context.d.ts +9 -1
  32. package/dist/v1/builder/lowering/schema/context.js +36 -4
  33. package/dist/v1/builder/lowering/schema/lifetime.d.ts +11 -0
  34. package/dist/v1/builder/lowering/schema/lifetime.js +55 -0
  35. package/dist/v1/builder/lowering/value/path.d.ts +1 -1
  36. package/dist/v1/builder/lowering/value/path.js +2 -4
  37. package/dist/v1/builder/lowering/value/zod.js +1 -3
  38. package/dist/v1/builder/policy/authoring.d.ts +85 -5
  39. package/dist/v1/builder/policy/authoring.js +107 -68
  40. package/dist/v1/builder/schema/define.d.ts +0 -1
  41. package/dist/v1/builder/schema/diagnostic.d.ts +3 -2
  42. package/dist/v1/builder/schema/diagnostic.js +5 -10
  43. package/dist/v1/builder/schema/input.d.ts +1 -1
  44. package/dist/v1/builder/schema/projection/callable.d.ts +7 -5
  45. package/dist/v1/builder/schema/projection/class.d.ts +118 -15
  46. package/dist/v1/builder/schema/projection/core-input.d.ts +2 -1
  47. package/dist/v1/builder/schema/projection/identity.d.ts +2 -1
  48. package/dist/v1/builder/schema/projection/model.d.ts +4 -2
  49. package/dist/v1/builder/schema/projection/property.d.ts +1 -1
  50. package/dist/v1/builder/schema/projection/resolved-class.d.ts +2 -1
  51. package/dist/v1/builder/schema/projection.d.ts +1 -1
  52. package/dist/v1/builder/value/full-match.d.ts +0 -1
  53. package/dist/v1/builder/value/full-match.js +0 -1
  54. package/dist/v1/builder/value/path-metadata.d.ts +1 -1
  55. package/dist/v1/builder/value/path.d.ts +1 -1
  56. package/dist/v1/bundle/codec.js +11 -13
  57. package/dist/v1/bundle/diagnostic.d.ts +2 -0
  58. package/dist/v1/bundle/diagnostic.js +9 -7
  59. package/dist/v1/bundle/model.js +1 -1
  60. package/dist/v1/bundle/structure.js +4 -6
  61. package/dist/v1/compiled/admission/accept.js +4 -10
  62. package/dist/v1/compiled/admission/closure.js +2 -2
  63. package/dist/v1/compiled/admission/diagnostic.d.ts +1 -1
  64. package/dist/v1/compiled/admission/diagnostic.js +1 -3
  65. package/dist/v1/compiled/admission/revision.d.ts +9 -1
  66. package/dist/v1/compiled/admission/revision.js +6 -3
  67. package/dist/v1/compiled/admission/semantics/class.d.ts +4 -1
  68. package/dist/v1/compiled/admission/semantics/class.js +37 -12
  69. package/dist/v1/compiled/admission/semantics/core.d.ts +1 -24
  70. package/dist/v1/compiled/admission/semantics/core.js +56 -24
  71. package/dist/v1/compiled/admission/semantics/edge.d.ts +2 -4
  72. package/dist/v1/compiled/admission/semantics/edge.js +6 -65
  73. package/dist/v1/compiled/admission/semantics/policy/callable.js +0 -2
  74. package/dist/v1/compiled/admission/semantics/policy/contracts.d.ts +5 -20
  75. package/dist/v1/compiled/admission/semantics/policy/contracts.js +8 -21
  76. package/dist/v1/compiled/admission/semantics/policy/parity.js +40 -43
  77. package/dist/v1/compiled/admission/semantics/policy/pattern.d.ts +4 -1
  78. package/dist/v1/compiled/admission/semantics/policy/pattern.js +4 -16
  79. package/dist/v1/compiled/admission/semantics/policy/typing.d.ts +2 -24
  80. package/dist/v1/compiled/admission/semantics/policy/typing.js +19 -201
  81. package/dist/v1/compiled/admission/wire/callable.js +11 -1
  82. package/dist/v1/compiled/admission/wire/class.js +73 -21
  83. package/dist/v1/compiled/admission/wire/policy.d.ts +4 -3
  84. package/dist/v1/compiled/admission/wire/policy.js +8 -7
  85. package/dist/v1/compiled/compiler/compile.js +8 -8
  86. package/dist/v1/compiled/diagnostic.js +2 -3
  87. package/dist/v1/compiled/loader/load.d.ts +3 -2
  88. package/dist/v1/compiled/loader/load.js +11 -45
  89. package/dist/v1/domain/create.js +5 -6
  90. package/dist/v1/domain/model/domain.d.ts +2 -7
  91. package/dist/v1/domain/model/input.d.ts +2 -1
  92. package/dist/v1/domain/namespace/member-collection.js +4 -6
  93. package/dist/v1/domain/projection/classes.js +4 -1
  94. package/dist/v1/domain/validation/create.d.ts +6 -3
  95. package/dist/v1/domain/validation/create.js +21 -69
  96. package/dist/v1/index.d.ts +2 -1
  97. package/dist/v1/language/.spec/schemas/draft-2020-12.schema.json +462 -0
  98. package/dist/v1/language/.spec/schemas/value-schema.schema.json +22 -0
  99. package/dist/v1/language/callable/admission.d.ts +15 -0
  100. package/dist/v1/language/callable/admission.js +43 -0
  101. package/dist/v1/language/callable/model/callable.d.ts +10 -0
  102. package/dist/v1/language/callable/resolved.d.ts +16 -3
  103. package/dist/v1/language/class/inheritance.d.ts +36 -5
  104. package/dist/v1/language/class/inheritance.js +87 -1
  105. package/dist/v1/language/class/lifetime.d.ts +50 -11
  106. package/dist/v1/language/class/lifetime.js +89 -20
  107. package/dist/v1/language/class/model/class.d.ts +45 -9
  108. package/dist/v1/language/class/model/edge.d.ts +31 -2
  109. package/dist/v1/language/class/model/property.d.ts +16 -7
  110. package/dist/v1/language/class/property-values.js +2 -4
  111. package/dist/v1/language/class/unique.d.ts +143 -0
  112. package/dist/v1/language/class/unique.js +264 -0
  113. package/dist/v1/language/core/facts.d.ts +85 -0
  114. package/dist/v1/language/core/facts.js +116 -0
  115. package/dist/v1/language/definition/metadata.d.ts +5 -0
  116. package/dist/v1/language/definition/metadata.js +7 -0
  117. package/dist/v1/language/freeze.d.ts +5 -0
  118. package/dist/v1/{schema/canonical → language}/freeze.js +4 -0
  119. package/dist/v1/language/index.d.ts +7 -2
  120. package/dist/v1/language/index.js +5 -1
  121. package/dist/v1/language/limits.d.ts +64 -0
  122. package/dist/v1/language/limits.js +60 -0
  123. package/dist/v1/language/policy/analysis/branches.d.ts +8 -0
  124. package/dist/v1/language/policy/analysis/branches.js +2 -1
  125. package/dist/v1/language/policy/analysis/budgets.d.ts +45 -12
  126. package/dist/v1/language/policy/analysis/budgets.js +133 -19
  127. package/dist/v1/language/policy/analysis/checks.js +3 -2
  128. package/dist/v1/language/policy/analysis/typing.d.ts +51 -0
  129. package/dist/v1/language/policy/analysis/typing.js +455 -0
  130. package/dist/v1/language/policy/model/policy.d.ts +49 -9
  131. package/dist/v1/language/policy/model/policy.js +14 -0
  132. package/dist/v1/language/policy/normalization/normalize.d.ts +6 -6
  133. package/dist/v1/language/policy/normalization/normalize.js +22 -21
  134. package/dist/v1/language/validation/diagnostic.d.ts +15 -1
  135. package/dist/v1/language/validation/diagnostic.js +21 -0
  136. package/dist/v1/language/validation/rule.d.ts +45 -0
  137. package/dist/v1/language/validation/rule.js +109 -0
  138. package/dist/v1/language/value/compile/fields.js +4 -8
  139. package/dist/v1/language/value/evaluate/program.d.ts +2 -1
  140. package/dist/v1/language/value/evaluate/program.js +2 -2
  141. package/dist/v1/language/value/evaluate/validate.d.ts +2 -2
  142. package/dist/v1/language/value/evaluate/validate.js +6 -2
  143. package/dist/v1/language/value/evaluate/validity.optimization.d.ts +14 -0
  144. package/dist/v1/language/value/evaluate/validity.optimization.js +342 -0
  145. package/dist/v1/language/value/inclusion/arrays.d.ts +3 -0
  146. package/dist/v1/language/value/inclusion/arrays.js +85 -0
  147. package/dist/v1/language/value/inclusion/assertions.d.ts +18 -0
  148. package/dist/v1/language/value/inclusion/assertions.js +29 -0
  149. package/dist/v1/language/value/inclusion/combinators.d.ts +3 -0
  150. package/dist/v1/language/value/inclusion/combinators.js +67 -0
  151. package/dist/v1/language/value/inclusion/equivalence.d.ts +4 -0
  152. package/dist/v1/language/value/inclusion/equivalence.js +74 -0
  153. package/dist/v1/language/value/inclusion/evidence.d.ts +34 -0
  154. package/dist/v1/language/value/inclusion/evidence.js +138 -0
  155. package/dist/v1/language/value/inclusion/includes.d.ts +17 -0
  156. package/dist/v1/language/value/inclusion/includes.js +25 -719
  157. package/dist/v1/language/value/inclusion/keywords.d.ts +5 -0
  158. package/dist/v1/language/value/inclusion/keywords.js +31 -0
  159. package/dist/v1/language/value/inclusion/kinds.d.ts +17 -0
  160. package/dist/v1/language/value/inclusion/kinds.js +57 -0
  161. package/dist/v1/language/value/inclusion/location.d.ts +24 -0
  162. package/dist/v1/language/value/inclusion/location.js +63 -0
  163. package/dist/v1/language/value/inclusion/numbers.d.ts +3 -0
  164. package/dist/v1/language/value/inclusion/numbers.js +41 -0
  165. package/dist/v1/language/value/inclusion/objects.d.ts +3 -0
  166. package/dist/v1/language/value/inclusion/objects.js +190 -0
  167. package/dist/v1/language/value/inclusion/strings.d.ts +3 -0
  168. package/dist/v1/language/value/inclusion/strings.js +29 -0
  169. package/dist/v1/language/value/inclusion/types.d.ts +3 -0
  170. package/dist/v1/language/value/inclusion/types.js +11 -0
  171. package/dist/v1/language/value/ordering.d.ts +14 -0
  172. package/dist/v1/language/value/ordering.js +86 -9
  173. package/dist/v1/language/value/profile/canonicalize.js +6 -5
  174. package/dist/v1/language/value/profile/json.validate.d.ts +3 -1
  175. package/dist/v1/language/value/profile/json.validate.js +3 -2
  176. package/dist/v1/language/value/profile/meta-schema.compiled.js +4 -1
  177. package/dist/v1/language/value/profile/rules.js +17 -43
  178. package/dist/v1/language/value/profile/validate.js +1 -10
  179. package/dist/v1/language/value/profile/vocabulary.d.ts +35 -2
  180. package/dist/v1/language/value/profile/vocabulary.js +52 -5
  181. package/dist/v1/language/value/reference/closure.js +3 -4
  182. package/dist/v1/language/value/reference/recursion.js +2 -22
  183. package/dist/v1/language/value/reference/registry.index.d.ts +2 -0
  184. package/dist/v1/language/value/reference/registry.index.js +33 -16
  185. package/dist/v1/language/value/regexp/ast.js +6 -7
  186. package/dist/v1/language/value/regexp/compile.d.ts +5 -11
  187. package/dist/v1/language/value/regexp/compile.js +14 -12
  188. package/dist/v1/language/value/regexp/syntax.js +3 -2
  189. package/dist/v1/language/value/syntax/keywords.d.ts +3 -3
  190. package/dist/v1/language/value/syntax/keywords.js +4 -20
  191. package/dist/v1/language/value/syntax/node-path/validate.js +2 -3
  192. package/dist/v1/language/value/syntax/pointer.d.ts +2 -0
  193. package/dist/v1/language/value/syntax/pointer.js +5 -2
  194. package/dist/v1/language/value/syntax/walk.d.ts +2 -0
  195. package/dist/v1/language/value/syntax/walk.js +19 -20
  196. package/dist/v1/schema/.spec/schemas/domain-schema.schema.json +2519 -0
  197. package/dist/v1/schema/admission/accept.js +3 -14
  198. package/dist/v1/schema/admission/callable.d.ts +21 -0
  199. package/dist/v1/schema/admission/callable.js +96 -0
  200. package/dist/v1/schema/analysis/class.js +33 -15
  201. package/dist/v1/schema/canonical/revision.js +4 -4
  202. package/dist/v1/schema/compatibility/api.d.ts +2 -1
  203. package/dist/v1/schema/compatibility/api.js +1 -0
  204. package/dist/v1/schema/compatibility/comparators/callables.js +1 -1
  205. package/dist/v1/schema/compatibility/comparators/classes.d.ts +9 -4
  206. package/dist/v1/schema/compatibility/comparators/classes.js +29 -8
  207. package/dist/v1/schema/compatibility/comparators/index.d.ts +1 -1
  208. package/dist/v1/schema/compatibility/comparators/members.js +1 -1
  209. package/dist/v1/schema/compatibility/comparators/values.js +2 -2
  210. package/dist/v1/schema/compatibility/coordinate.js +3 -3
  211. package/dist/v1/schema/compatibility/diff.js +2 -4
  212. package/dist/v1/schema/compatibility/extension.d.ts +11 -0
  213. package/dist/v1/schema/compatibility/extension.js +22 -0
  214. package/dist/v1/schema/compatibility/fields.d.ts +20 -4
  215. package/dist/v1/schema/compatibility/fields.js +13 -3
  216. package/dist/v1/schema/compatibility/meaning/footprint.js +16 -50
  217. package/dist/v1/schema/compatibility/model.d.ts +17 -5
  218. package/dist/v1/schema/compatibility/report.js +1 -1
  219. package/dist/v1/schema/compatibility/scope.d.ts +2 -0
  220. package/dist/v1/schema/compatibility/scope.js +4 -1
  221. package/dist/v1/schema/compatibility/structure/index.js +6 -4
  222. package/dist/v1/schema/compatibility/structure/requirements.js +57 -58
  223. package/dist/v1/schema/compatibility/versioning/index.js +1 -1
  224. package/dist/v1/schema/compatibility/versioning/surface.d.ts +1 -1
  225. package/dist/v1/schema/compatibility/versioning/surface.js +30 -2
  226. package/dist/v1/schema/compatibility/walk.d.ts +17 -0
  227. package/dist/v1/schema/compatibility/walk.js +41 -0
  228. package/dist/v1/schema/diagnostic.d.ts +17 -3
  229. package/dist/v1/schema/diagnostic.js +14 -11
  230. package/dist/v1/schema/index.d.ts +10 -1
  231. package/dist/v1/schema/index.js +4 -0
  232. package/dist/v1/schema/model/schema.d.ts +20 -1
  233. package/dist/v1/schema/model/schema.js +1 -1
  234. package/dist/v1/schema/normalization/domain.d.ts +2 -0
  235. package/dist/v1/schema/normalization/domain.js +29 -9
  236. package/dist/v1/schema/resolution/closure.js +2 -1
  237. package/dist/v1/schema/resolution/context.js +13 -13
  238. package/dist/v1/schema/resolution/domain.d.ts +5 -0
  239. package/dist/v1/schema/resolution/domain.js +2 -2
  240. package/dist/v1/schema/resolution/origins.js +3 -2
  241. package/dist/v1/schema/rule.d.ts +26 -0
  242. package/dist/v1/schema/rule.js +440 -0
  243. package/dist/v1/schema/validation/callable.d.ts +35 -2
  244. package/dist/v1/schema/validation/callable.js +65 -9
  245. package/dist/v1/schema/validation/class.d.ts +6 -2
  246. package/dist/v1/schema/validation/class.js +127 -104
  247. package/dist/v1/schema/validation/core.js +90 -168
  248. package/dist/v1/schema/validation/domain.js +4 -13
  249. package/dist/v1/schema/validation/domain.json-schema.d.ts +15 -0
  250. package/dist/v1/schema/validation/domain.json-schema.js +197 -0
  251. package/dist/v1/schema/validation/domain.route.d.ts +6 -1
  252. package/dist/v1/schema/validation/domain.route.js +18 -0
  253. package/dist/v1/schema/validation/domain.structure.d.ts +7780 -0
  254. package/dist/v1/schema/validation/domain.structure.js +398 -147
  255. package/dist/v1/schema/validation/json.json-schema.d.ts +40 -0
  256. package/dist/v1/schema/validation/json.json-schema.js +46 -0
  257. package/dist/v1/schema/validation/policy/budgets.d.ts +33 -2
  258. package/dist/v1/schema/validation/policy/budgets.js +87 -121
  259. package/dist/v1/schema/validation/policy/context.d.ts +6 -5
  260. package/dist/v1/schema/validation/policy/context.js +7 -10
  261. package/dist/v1/schema/validation/policy/objects.d.ts +1 -1
  262. package/dist/v1/schema/validation/policy/objects.js +6 -14
  263. package/dist/v1/schema/validation/policy/references.js +11 -27
  264. package/dist/v1/schema/validation/policy/typing.d.ts +3 -18
  265. package/dist/v1/schema/validation/policy/typing.js +22 -356
  266. package/dist/v1/schema/validation/policy/uses.d.ts +40 -3
  267. package/dist/v1/schema/validation/policy/uses.js +66 -89
  268. package/dist/v1/schema/validation/policy/validate.js +5 -5
  269. package/dist/v1/schema/validation/value-api.d.ts +22 -0
  270. package/dist/v1/schema/validation/value-api.js +34 -1
  271. package/dist/v1/schema/validation/value.d.ts +3 -0
  272. package/dist/v1/schema/validation/value.js +9 -17
  273. package/dist/v1/schema/validation/value.json-schema.d.ts +49 -0
  274. package/dist/v1/schema/validation/value.json-schema.js +137 -0
  275. package/dist/v1/schema/validation/view.js +4 -8
  276. package/dist/value/canonical.d.ts +6 -0
  277. package/dist/value/canonical.js +36 -0
  278. package/dist/value/decode.d.ts +7 -0
  279. package/dist/value/decode.js +159 -9
  280. package/dist/value/index.d.ts +1 -1
  281. package/dist/value/json.d.ts +2 -2
  282. package/dist/value/json.js +2 -2
  283. package/dist/value/types.d.ts +6 -0
  284. package/dist/value/unicode.d.ts +2 -1
  285. package/dist/value/unicode.js +2 -0
  286. package/package.json +8 -1
  287. package/dist/v1/builder/lowering/core-properties.d.ts +0 -10
  288. package/dist/v1/builder/lowering/core-properties.js +0 -76
  289. package/dist/v1/compiled/admission/semantics/cardinality.d.ts +0 -5
  290. package/dist/v1/compiled/admission/semantics/cardinality.js +0 -113
  291. package/dist/v1/compiled/admission/semantics/policy/equality.d.ts +0 -8
  292. package/dist/v1/compiled/admission/semantics/policy/equality.js +0 -27
  293. package/dist/v1/compiled/admission/semantics/policy/measure.d.ts +0 -9
  294. package/dist/v1/compiled/admission/semantics/policy/measure.js +0 -81
  295. package/dist/v1/compiled/admission/semantics/policy/variants.d.ts +0 -10
  296. package/dist/v1/compiled/admission/semantics/policy/variants.js +0 -65
  297. package/dist/v1/language/class/index.d.ts +0 -8
  298. package/dist/v1/language/class/index.js +0 -1
  299. package/dist/v1/language/core/index.d.ts +0 -2
  300. package/dist/v1/language/value/index.d.ts +0 -11
  301. package/dist/v1/language/value/index.js +0 -8
  302. package/dist/v1/schema/canonical/domain.d.ts +0 -3
  303. package/dist/v1/schema/canonical/domain.digest.d.ts +0 -3
  304. package/dist/v1/schema/canonical/domain.digest.js +0 -5
  305. package/dist/v1/schema/canonical/domain.js +0 -5
  306. package/dist/v1/schema/canonical/freeze.d.ts +0 -1
  307. /package/dist/v1/{language/core/index.js → builder/class/input.js} +0 -0
@@ -1,22 +1,11 @@
1
- import { accept as acceptJsonValue, BoundaryError as JsonBoundaryError, } from '@astrale-os/kernel-dsl/value';
2
1
  import { canonicalDomainSchemaAfterValidation } from '../canonical/revision.js';
3
2
  import { emptyDomainSchemaLookup } from '../dependency/lookup.js';
4
- import { SchemaError, diagnostic } from '../diagnostic.js';
3
+ import { SchemaError } from '../diagnostic.js';
5
4
  import { rememberDomainClosure } from '../resolution/closure.js';
6
5
  import { validateDomainSchemaSemantics } from '../validation/domain.js';
7
- import { routeDomainSchema } from '../validation/domain.route.js';
6
+ import { structureDomainSchema } from '../validation/domain.route.js';
8
7
  export function acceptDomainSchema(input, lookup = emptyDomainSchemaLookup()) {
9
- let admitted;
10
- try {
11
- admitted = acceptJsonValue(input);
12
- }
13
- catch (error) {
14
- if (error instanceof JsonBoundaryError) {
15
- throw new SchemaError([diagnostic('DV_JSON_VALUE', error.pointer, error.message)]);
16
- }
17
- throw error;
18
- }
19
- const structured = routeDomainSchema(admitted);
8
+ const structured = structureDomainSchema(input);
20
9
  const validation = validateDomainSchemaSemantics(structured, lookup);
21
10
  if (validation.diagnostics.length > 0)
22
11
  throw new SchemaError(validation.diagnostics);
@@ -0,0 +1,21 @@
1
+ import type { ClassRef } from '../../addressing/index.js';
2
+ import type { CallableValidation } from '../../domain/validation/create.js';
3
+ import type { CallableDefinition } from '../../language/callable/model/callable.js';
4
+ import type { DomainSchema } from '../model/schema.js';
5
+ /** One admitted callable contract and the validators of its exact owner environment. */
6
+ export interface AcceptedCallable extends CallableValidation {
7
+ readonly definition: CallableDefinition;
8
+ }
9
+ /**
10
+ * Accept one callable contract in the exact environment of its owner Domain, by the one validation
11
+ * every contract passes wherever it is declared (`validateContract`, `validateContractPolicy`,
12
+ * `validateCheckBudget`): the structure of a Function declaration without `ref`, its value schemas
13
+ * against the owner registry, its execution modifier and admission age, and its Policy with the
14
+ * budget of its checks. `receiver` is the owner Node Class whose Node receives the call and which
15
+ * the Policy names `self`: the Class of a Function instance, whose Node carries the contract, or
16
+ * the owner of an instance Method. Without it, as at a Function declaration, the Policy names none.
17
+ * Returns the canonical definition and its validators.
18
+ */
19
+ export declare function acceptCallable(input: unknown, owner: DomainSchema, options?: {
20
+ readonly receiver?: ClassRef;
21
+ }): AcceptedCallable;
@@ -0,0 +1,96 @@
1
+ import { accept as acceptJsonValue, BoundaryError as JsonBoundaryError, } from '@astrale-os/kernel-dsl/value';
2
+ import { definitionRefIndex } from '../../addressing/ordering.js';
3
+ import { isBinaryInput } from '../../language/callable/model/callable.js';
4
+ import { deepFreeze } from '../../language/freeze.js';
5
+ import { measureChecks } from '../../language/policy/analysis/budgets.js';
6
+ import { PolicyTyping } from '../../language/policy/analysis/typing.js';
7
+ import { normalizePolicyChecks } from '../../language/policy/normalization/normalize.js';
8
+ import {} from '../../language/value/evaluate/preparation.js';
9
+ import { analyzeDefinitions } from '../analysis/class.js';
10
+ import { SchemaError, diagnostic } from '../diagnostic.js';
11
+ import { canonicalizeCallable } from '../normalization/domain.js';
12
+ import { lookupForDomainClosure } from '../resolution/closure.js';
13
+ import { buildDomainResolutionContext } from '../resolution/context.js';
14
+ import { callableValidation } from '../resolution/domain.js';
15
+ import { createDomainValueSchemaRegistry } from '../resolution/value.registry.js';
16
+ import { validateContract } from '../validation/callable.js';
17
+ import { parseCallableContract } from '../validation/domain.structure.js';
18
+ import { validateCheckBudget } from '../validation/policy/budgets.js';
19
+ import { PolicyValidationContext } from '../validation/policy/context.js';
20
+ import { validatePolicyReferences } from '../validation/policy/references.js';
21
+ import { validateContractPolicy } from '../validation/policy/uses.js';
22
+ // An accepted DomainSchema is immutable and retains its closure, so its environment is reusable.
23
+ const environments = new WeakMap();
24
+ /**
25
+ * Accept one callable contract in the exact environment of its owner Domain, by the one validation
26
+ * every contract passes wherever it is declared (`validateContract`, `validateContractPolicy`,
27
+ * `validateCheckBudget`): the structure of a Function declaration without `ref`, its value schemas
28
+ * against the owner registry, its execution modifier and admission age, and its Policy with the
29
+ * budget of its checks. `receiver` is the owner Node Class whose Node receives the call and which
30
+ * the Policy names `self`: the Class of a Function instance, whose Node carries the contract, or
31
+ * the owner of an instance Method. Without it, as at a Function declaration, the Policy names none.
32
+ * Returns the canonical definition and its validators.
33
+ */
34
+ export function acceptCallable(input, owner, options = {}) {
35
+ let value;
36
+ try {
37
+ value = acceptJsonValue(input);
38
+ }
39
+ catch (error) {
40
+ if (error instanceof JsonBoundaryError) {
41
+ throw new SchemaError([diagnostic('DV_JSON_VALUE', error.pointer, error.message)]);
42
+ }
43
+ throw error;
44
+ }
45
+ const callable = parseCallableContract(value);
46
+ const environment = ownerEnvironment(owner);
47
+ const { receiver } = options;
48
+ if (receiver !== undefined) {
49
+ const resolved = environment.resolution.resolve(receiver);
50
+ if (resolved === undefined ||
51
+ resolved.ref.kind !== 'class' ||
52
+ resolved.kind !== 'node' ||
53
+ definitionRefIndex(resolved.ref) !== definitionRefIndex(receiver) ||
54
+ receiver.origin !== owner.origin) {
55
+ throw new SchemaError([
56
+ diagnostic('DV_REF_RESOLVES', '', 'A receiver must be a Node Class of the owner Domain.'),
57
+ ]);
58
+ }
59
+ }
60
+ const issues = [];
61
+ validateContract(callable, '', environment.registry, issues);
62
+ if (typeof callable.policy === 'object') {
63
+ const policies = new PolicyValidationContext(environment.resolution, environment.analysis);
64
+ // Normalizes the owner's named Policies, which the Policy's checks are typed against.
65
+ validatePolicyReferences(policies);
66
+ validateContractPolicy(policies, new PolicyTyping(policies), callable, '', receiver);
67
+ // A document measures its own check trees (`validatePolicyBudgets`); this one is in none.
68
+ validateCheckBudget(policies, '/policy', measureChecks(normalizePolicyChecks(callable.policy)));
69
+ issues.push(...policies.diagnostics);
70
+ }
71
+ if (issues.length > 0)
72
+ throw new SchemaError(issues);
73
+ const definition = deepFreeze(canonicalizeCallable(callable));
74
+ const validation = callableValidation(isBinaryInput(definition.input) ? definition.input.metadata : definition.input, definition.output.mode === 'binary'
75
+ ? undefined
76
+ : definition.output.mode === 'value'
77
+ ? definition.output.schema
78
+ : definition.output.item, environment.registry,
79
+ // Patterns live with these validators: carried contracts never grow a process-wide pool.
80
+ new Map());
81
+ return Object.freeze({ ...validation, definition });
82
+ }
83
+ function ownerEnvironment(owner) {
84
+ const cached = environments.get(owner);
85
+ if (cached !== undefined)
86
+ return cached;
87
+ const lookup = lookupForDomainClosure(owner);
88
+ const resolution = buildDomainResolutionContext(owner, lookup);
89
+ const environment = Object.freeze({
90
+ resolution,
91
+ analysis: analyzeDefinitions(resolution),
92
+ registry: createDomainValueSchemaRegistry(owner, lookup),
93
+ });
94
+ environments.set(owner, environment);
95
+ return environment;
96
+ }
@@ -3,39 +3,48 @@ import { Key, PropertyKey } from '../../addressing/index.js';
3
3
  import { definitionRefIndex } from '../../addressing/ordering.js';
4
4
  import { composeMethods } from '../../language/callable/composition.js';
5
5
  import { canonicalizeValueSchema } from '../../language/value/profile/canonicalize.js';
6
+ import { escapePointerToken } from '../../language/value/syntax/pointer.js';
6
7
  import { diagnostic } from '../diagnostic.js';
7
8
  const formatDefinitionRef = Key.of;
8
9
  export function analyzeDefinitions(environment) {
9
10
  const diagnostics = [];
10
11
  const result = new Map();
11
12
  const visiting = new Set();
13
+ // A dependency was accepted against this same exact closure: a rule breaks here only at a Class
14
+ // of the candidate, or on an incomplete closure, which the dependency diagnostics report. An
15
+ // unresolved parent is reported where the candidate names it, by Class validation.
16
+ const reporter = (owner) => (code, at, message, ref) => {
17
+ if (owner.origin !== environment.candidate.origin)
18
+ return;
19
+ const pointer = `/classes/${escapePointerToken(owner.name)}${at}`;
20
+ diagnostics.push(diagnostic(code, pointer, message, ref));
21
+ };
12
22
  const analyze = (ref) => {
13
23
  const key = definitionRefIndex(ref);
14
24
  const cached = result.get(key);
15
25
  if (cached !== undefined)
16
26
  return cached;
17
- if (visiting.has(key)) {
18
- diagnostics.push(diagnostic('DV_CLASS_ACYCLIC', '', `Inheritance cycle reaches ${formatDefinitionRef(ref)}.`, formatDefinitionRef(ref)));
19
- return undefined;
20
- }
21
27
  const resolved = environment.resolveAny(ref);
22
28
  if (resolved === undefined)
23
29
  return undefined;
24
30
  visiting.add(key);
31
+ const report = reporter(ref);
25
32
  const declaration = resolved.declaration;
26
33
  const parents = declaration.extends;
27
- const parentAnalyses = parents.flatMap((parent) => {
34
+ const parentAnalyses = parents.flatMap((parent, index) => {
28
35
  const target = environment.resolveAny(parent);
29
- if (target === undefined) {
30
- diagnostics.push(diagnostic('DV_REF_RESOLVES', '', `Inheritance ref ${formatDefinitionRef(parent)} does not resolve.`, formatDefinitionRef(parent)));
36
+ if (target?.ref.kind !== 'class')
37
+ return [];
38
+ if (visiting.has(definitionRefIndex(target.ref))) {
39
+ report('DV_CLASS_ACYCLIC', `/extends/${index}`, `Inheritance cycle reaches ${formatDefinitionRef(parent)}.`, formatDefinitionRef(parent));
31
40
  return [];
32
41
  }
33
- const analysis = target.ref.kind === 'class' ? analyze(target.ref) : undefined;
42
+ const analysis = analyze(target.ref);
34
43
  return analysis === undefined ? [] : [analysis];
35
44
  });
36
45
  const properties = mergeFields(parentAnalyses.map((parent) => parent.properties), ownFields(ref, declaration));
37
- const data = mergeData(ref, declaration, parentAnalyses, diagnostics);
38
- const methods = mergeMethods(ref, declaration, parentAnalyses, diagnostics);
46
+ const data = mergeData(ref, declaration, parentAnalyses, report);
47
+ const methods = mergeMethods(ref, declaration, parentAnalyses, report);
39
48
  const analysis = {
40
49
  ref,
41
50
  declaration,
@@ -82,7 +91,7 @@ function mergeFields(inherited, own) {
82
91
  }
83
92
  return result;
84
93
  }
85
- function mergeData(owner, declaration, parents, diagnostics) {
94
+ function mergeData(owner, declaration, parents, report) {
86
95
  let effective;
87
96
  for (const parent of parents) {
88
97
  if (parent.data === undefined)
@@ -92,14 +101,15 @@ function mergeData(owner, declaration, parents, diagnostics) {
92
101
  continue;
93
102
  }
94
103
  if (effective.identity !== parent.data.identity) {
95
- diagnostics.push(diagnostic('DV_DATA_COMPOSITION', '', `Data has distinct declaring owners ${formatDefinitionRef(effective.owner)} and ${formatDefinitionRef(parent.data.owner)}.`));
104
+ const index = declaration.extends.findIndex((ref) => definitionRefIndex(ref) === definitionRefIndex(parent.ref));
105
+ report('DV_DATA_COMPOSITION', `/extends/${index}`, `Data has distinct declaring owners ${formatDefinitionRef(effective.owner)} and ${formatDefinitionRef(parent.data.owner)}.`);
96
106
  }
97
107
  }
98
108
  const own = 'data' in declaration ? declaration.data : undefined;
99
109
  if (own === undefined)
100
110
  return effective;
101
111
  if (effective !== undefined) {
102
- diagnostics.push(diagnostic('DV_DATA_COMPOSITION', '', `Data redeclares the inherited contract from ${formatDefinitionRef(effective.owner)}.`));
112
+ report('DV_DATA_COMPOSITION', '/data', `Data redeclares the inherited contract from ${formatDefinitionRef(effective.owner)}.`);
103
113
  }
104
114
  return {
105
115
  identity: `${definitionRefIndex(owner)}\u0000data`,
@@ -107,12 +117,20 @@ function mergeData(owner, declaration, parents, diagnostics) {
107
117
  declaration: own,
108
118
  };
109
119
  }
110
- function mergeMethods(owner, declaration, parents, diagnostics) {
120
+ function mergeMethods(owner, declaration, parents, report) {
111
121
  const own = new Map(Object.entries('methods' in declaration ? declaration.methods : {}).map(([name, method]) => [
112
122
  name,
113
123
  { key: `${Key.of(owner)}.method.${name}`, owner, name, declaration: method },
114
124
  ]));
115
- return composeMethods(parents, own, declaration.abstract, (left, right) => sameMethodSignature(left.declaration, right.declaration), (message) => diagnostics.push(diagnostic('DV_METHOD_COMPOSITION', '', message, Key.of(owner))));
125
+ return composeMethods(parents, own, declaration.abstract, (left, right) => sameMethodSignature(left.declaration, right.declaration),
126
+ // A changed signature is the local Method's; an ambiguous or missing one needs a local Method.
127
+ (message, issue) => {
128
+ const local = issue.kind === 'signature'
129
+ ? [...own.values()].find(({ key }) => key === issue.local)
130
+ : undefined;
131
+ const at = local === undefined ? '/methods' : `/methods/${escapePointerToken(local.name)}`;
132
+ report('DV_METHOD_COMPOSITION', at, message, Key.of(owner));
133
+ });
116
134
  }
117
135
  /** The exact signature required by abstract Method composition. */
118
136
  export function sameMethodSignature(left, right) {
@@ -1,7 +1,7 @@
1
1
  import { json } from '@astrale-os/kernel-dsl/value';
2
+ import { digestRevisionBytes } from '../../addressing/revision.js';
2
3
  import { asDomainSchema } from '../model/schema.js';
3
- import { digestDomainSchemaBytes } from './domain.digest.js';
4
- import { canonicalizeDomainSchema } from './domain.js';
4
+ import { normalizeDomainSchema } from '../normalization/domain.js';
5
5
  // Only canonical schemas created here own a retained revision, never caller-owned input.
6
6
  const revisions = new WeakMap();
7
7
  export function canonicalDomainSchema(value) {
@@ -9,9 +9,9 @@ export function canonicalDomainSchema(value) {
9
9
  }
10
10
  /** Internal acceptance seam. The caller must establish whole-Domain validity first. */
11
11
  export function canonicalDomainSchemaAfterValidation(value) {
12
- const schema = asDomainSchema(canonicalizeDomainSchema(value));
12
+ const schema = asDomainSchema(normalizeDomainSchema(value));
13
13
  const bytes = json.encode(schema);
14
- const revision = digestDomainSchemaBytes(bytes);
14
+ const revision = digestRevisionBytes(bytes);
15
15
  revisions.set(schema, revision);
16
16
  return Object.freeze({ schema, bytes, revision });
17
17
  }
@@ -1,3 +1,4 @@
1
1
  export { compare, compareMeaning, compareStructure } from './compare.js';
2
+ export { closedParents } from './extension.js';
2
3
  export { requiredBump } from './versioning/index.js';
3
- export type { Analysis, Assessment, Bump, Comparison, ComparisonEntry, ComparisonEvidence, ComparisonRequest, ComparisonScope, Facet, Fingerprint, MeaningComparison, Observation, RequiredBump, SchemaIdentity, StructureComparison, Subject, Usage, VersionChange, } from './model.js';
4
+ export type { Analysis, Assessment, Bump, Comparison, ComparisonEntry, ComparisonEvidence, ComparisonRequest, ComparisonScope, DiagnosticCode, Facet, Fingerprint, MeaningComparison, Observation, RequiredBump, SchemaIdentity, StructureComparison, Subject, Usage, VersionChange, } from './model.js';
@@ -1,2 +1,3 @@
1
1
  export { compare, compareMeaning, compareStructure } from './compare.js';
2
+ export { closedParents } from './extension.js';
2
3
  export { requiredBump } from './versioning/index.js';
@@ -1,7 +1,7 @@
1
1
  import { isMethodExecutable } from '../../../language/callable/executable.js';
2
2
  import { isBinaryInput } from '../../../language/callable/model/callable.js';
3
+ import { deepFreeze } from '../../../language/freeze.js';
3
4
  import { methodSignature as inheritedSignature } from '../../analysis/class.js';
4
- import { deepFreeze } from '../../canonical/freeze.js';
5
5
  import { keyForDefinitionRef } from '../coordinate.js';
6
6
  import { CALLABLE_FIELDS, fieldsOf } from '../fields.js';
7
7
  import { fingerprintMeaning, semanticValueSchema } from './values.js';
@@ -1,5 +1,6 @@
1
1
  import type { Value as JsonValue } from '@astrale-os/kernel-dsl/value';
2
2
  import type { Key as SemanticKey } from '../../../addressing/index.js';
3
+ import type { Inheritance } from '../../../language/class/model/class.js';
3
4
  import type { EffectiveField } from '../../analysis/class.js';
4
5
  import type { Context } from '../context.js';
5
6
  import type { ClassCoordinate } from '../coordinate.js';
@@ -10,10 +11,12 @@ interface ClassRequirement {
10
11
  readonly ancestors: readonly SemanticKey[];
11
12
  }
12
13
  /**
13
- * A reference needs the Class to exist with its kind, abstractness and orientation; inheritance
14
- * additionally takes on the source ancestors, class policies, data contract and, for an Edge, the
15
- * endpoint and constraint contracts. A target projected onto a source requirement keeps only the
16
- * ancestors the source named, so a superset satisfies it while a removal changes it.
14
+ * A reference needs the Class to exist with its kind, abstractness and orientation, and, for an
15
+ * Edge, the uniqueness tuples that cover it, its ancestors' included: a dependent may name one of
16
+ * its Edges by any of them. Inheritance additionally takes on the source ancestors, class
17
+ * policies, data contract and, for an Edge, the endpoint and constraint contracts. A target
18
+ * projected onto a source requirement keeps only the ancestors the source named, so a superset
19
+ * satisfies it while a removal changes it.
17
20
  */
18
21
  export declare function classMeaning(context: Context, coordinate: ClassCoordinate, level: DependencyMeaningLevel, onto?: ClassRequirement): {
19
22
  readonly meaning: JsonValue;
@@ -38,6 +41,8 @@ export declare function compareLostProperties({ pair, report, }: {
38
41
  readonly pair: SubjectPair;
39
42
  readonly report: Report;
40
43
  }): void;
44
+ /** Which Classes may extend a Class, as an extension facet compares it. */
45
+ export declare function inheritanceMeaning(inheritance: Inheritance): JsonValue;
41
46
  /** Newly required data is an obligation even though it was absent from the source footprint. */
42
47
  export declare function compareAddedProperties({ context, pair, report, }: {
43
48
  readonly context: ComparisonContext;
@@ -1,6 +1,7 @@
1
1
  import { compareUnicode } from '../../../addressing/ordering.js';
2
+ import { compareEdgeUniqueTuples, coveringEdgeUniqueTuples, } from '../../../language/class/unique.js';
3
+ import { deepFreeze } from '../../../language/freeze.js';
2
4
  import { isClassRuleChecks } from '../../../language/policy/model/policy.js';
3
- import { deepFreeze } from '../../canonical/freeze.js';
4
5
  import { effectiveDefinition } from '../context.js';
5
6
  import { propertyCoordinate } from '../coordinate.js';
6
7
  import { keyForDefinitionRef } from '../coordinate.js';
@@ -8,10 +9,12 @@ import { CLASS_FIELDS, PROPERTY_FIELDS, fieldsOf } from '../fields.js';
8
9
  import { usageOf } from '../references.js';
9
10
  import { semanticValueSchema } from './values.js';
10
11
  /**
11
- * A reference needs the Class to exist with its kind, abstractness and orientation; inheritance
12
- * additionally takes on the source ancestors, class policies, data contract and, for an Edge, the
13
- * endpoint and constraint contracts. A target projected onto a source requirement keeps only the
14
- * ancestors the source named, so a superset satisfies it while a removal changes it.
12
+ * A reference needs the Class to exist with its kind, abstractness and orientation, and, for an
13
+ * Edge, the uniqueness tuples that cover it, its ancestors' included: a dependent may name one of
14
+ * its Edges by any of them. Inheritance additionally takes on the source ancestors, class
15
+ * policies, data contract and, for an Edge, the endpoint and constraint contracts. A target
16
+ * projected onto a source requirement keeps only the ancestors the source named, so a superset
17
+ * satisfies it while a removal changes it.
15
18
  */
16
19
  export function classMeaning(context, coordinate, level, onto) {
17
20
  const owner = context.schemas.get(coordinate.ref.origin);
@@ -23,10 +26,12 @@ export function classMeaning(context, coordinate, level, onto) {
23
26
  const requirement = Object.freeze({
24
27
  ancestors,
25
28
  });
29
+ const covering = coveringTuples(context, declaration);
26
30
  const meaning = {
27
31
  coordinate: 'class',
28
32
  level: level,
29
33
  ...fieldsOf({ declaration, roles: CLASS_FIELDS, level }),
34
+ ...(covering.length === 0 ? {} : { unique: covering }),
30
35
  ...(level === 'inherit'
31
36
  ? {
32
37
  extends: onto === undefined
@@ -51,12 +56,12 @@ export function classMeaning(context, coordinate, level, onto) {
51
56
  return { meaning: deepFreeze(meaning), requirement };
52
57
  }
53
58
  /**
54
- * A named Policy compares by its key; `false` or Policy checks by their value, as a callable's
59
+ * A named Policy compares by its key; a constant or Policy checks by their value, as a callable's
55
60
  * Policy does.
56
61
  */
57
62
  function classPolicyMeaning(policy) {
58
- if (policy === false)
59
- return false;
63
+ if (typeof policy === 'boolean')
64
+ return policy;
60
65
  return isClassRuleChecks(policy) ? policy : keyForDefinitionRef(policy);
61
66
  }
62
67
  /**
@@ -109,6 +114,18 @@ function ancestorKeys(context, ref) {
109
114
  visit(ref);
110
115
  return [...seen].sort(compareUnicode);
111
116
  }
117
+ /**
118
+ * The uniqueness tuples covering an Edge Class (`coveringEdgeUniqueTuples`): those it and each of
119
+ * its ancestors declare, each with the Class declaring it, whose extent it bounds, in Class then
120
+ * tuple order. A Node Class's own tuples stay its declared field.
121
+ */
122
+ function coveringTuples(context, declaration) {
123
+ if (declaration.kind !== 'edge')
124
+ return [];
125
+ return [
126
+ ...coveringEdgeUniqueTuples(declaration, (ref) => context.schemas.get(ref.origin)?.classes[ref.name]),
127
+ ].sort((left, right) => compareUnicode(left.class, right.class) || compareEdgeUniqueTuples(left.fields, right.fields));
128
+ }
112
129
  /**
113
130
  * A Class a dependent references or inherits keeps every effective Property it had, whichever
114
131
  * ancestor declares it. Each Property is compared on its owner, which still declares it when the
@@ -139,6 +156,10 @@ function propertyIdentities(identities) {
139
156
  properties: Object.fromEntries(identities.map((identity) => [identity, true])),
140
157
  });
141
158
  }
159
+ /** Which Classes may extend a Class, as an extension facet compares it. */
160
+ export function inheritanceMeaning(inheritance) {
161
+ return deepFreeze({ coordinate: 'class', inheritance });
162
+ }
142
163
  /** Newly required data is an obligation even though it was absent from the source footprint. */
143
164
  export function compareAddedProperties({ context, pair, report, }) {
144
165
  if (pair.source?.kind !== 'class' || pair.target?.kind !== 'class')
@@ -5,7 +5,7 @@ import type { ComparisonContext, SubjectPair } from '../scope.js';
5
5
  export declare function compareFacet({ context, pair, facet, }: {
6
6
  readonly context: ComparisonContext;
7
7
  readonly pair: SubjectPair;
8
- readonly facet: Exclude<Facet, 'class.composition' | 'class.properties' | 'property.required'>;
8
+ readonly facet: Exclude<Facet, 'class.composition' | 'class.properties' | 'class.inheritance' | 'property.required'>;
9
9
  }): {
10
10
  readonly before?: Value;
11
11
  readonly after?: Value;
@@ -1,4 +1,4 @@
1
- import { deepFreeze } from '../../canonical/freeze.js';
1
+ import { deepFreeze } from '../../../language/freeze.js';
2
2
  import { CORE_FIELDS, POLICY_FIELDS, VIEW_FIELDS, fieldsOf } from '../fields.js';
3
3
  import { functionSignature } from './callables.js';
4
4
  export function memberMeaning(owner, ref) {
@@ -1,7 +1,7 @@
1
1
  import { json } from '@astrale-os/kernel-dsl/value';
2
+ import { digestRevisionBytes } from '../../../addressing/revision.js';
2
3
  import { isValueObject as isJsonObject } from '../../../language/value/model/object.js';
3
4
  import { SCHEMA_ARRAY_KEYWORDS, SCHEMA_MAP_KEYWORDS, SCHEMA_SINGLE_KEYWORDS, } from '../../../language/value/syntax/keywords.js';
4
- import { digestDomainSchemaBytes } from '../../canonical/domain.digest.js';
5
5
  import { ANNOTATION_KEYWORDS } from '../fields.js';
6
6
  /** Drop annotation keywords wherever a schema keyword nests a schema; never inside data. */
7
7
  export function semanticValueSchema(value) {
@@ -30,7 +30,7 @@ export function semanticValueSchema(value) {
30
30
  return semantic;
31
31
  }
32
32
  export function fingerprintMeaning(value) {
33
- return digestDomainSchemaBytes(json.encode(value));
33
+ return digestRevisionBytes(json.encode(value));
34
34
  }
35
35
  function isJsonSchema(value) {
36
36
  return typeof value === 'boolean' || isJsonObject(value);
@@ -20,10 +20,10 @@ export function keyForDefinitionRef(ref) {
20
20
  /** Interpret one canonical V1 Key as a Definition or a Class member location. */
21
21
  export function keyReference(key) {
22
22
  const semantic = key.slice(key.indexOf(':') + 1);
23
+ // A Core slug may hold `.`: the name of a Core key is the whole rest of its coordinate.
24
+ if (semantic.startsWith('core.'))
25
+ return { kind: 'core', name: semantic.slice('core.'.length) };
23
26
  const parts = semantic.split('.');
24
- if (parts[0] === 'core' && parts.length === 2) {
25
- return { kind: 'core', name: parts[1] };
26
- }
27
27
  if (parts.length === 2) {
28
28
  return { kind: parts[0], name: parts[1] };
29
29
  }
@@ -1,5 +1,6 @@
1
1
  import { compareUnicode } from '../../addressing/ordering.js';
2
2
  import { isValueObject as isJsonObject } from '../../language/value/model/object.js';
3
+ import { escapePointerToken } from '../../language/value/syntax/pointer.js';
3
4
  /** Structural differences between two portable values, leaf by leaf, in JSON Pointer order. */
4
5
  export function differences(before, after) {
5
6
  const found = [];
@@ -17,7 +18,7 @@ function collect(before, after, path, found) {
17
18
  if (isJsonObject(before) && isJsonObject(after)) {
18
19
  const keys = [...new Set([...Object.keys(before), ...Object.keys(after)])].sort(compareUnicode);
19
20
  for (const key of keys) {
20
- collect(before[key], after[key], `${path}/${escape(key)}`, found);
21
+ collect(before[key], after[key], `${path}/${escapePointerToken(key)}`, found);
21
22
  }
22
23
  return;
23
24
  }
@@ -34,6 +35,3 @@ function collect(before, after, path, found) {
34
35
  ...(after === undefined ? {} : { after }),
35
36
  }));
36
37
  }
37
- function escape(segment) {
38
- return segment.replaceAll('~', '~0').replaceAll('/', '~1');
39
- }
@@ -0,0 +1,11 @@
1
+ import type { Key } from '../../addressing/index.js';
2
+ import type { DomainSchema } from '../model/schema.js';
3
+ /**
4
+ * The Classes of the target's origin that a Class of the dependent extends and the target does not
5
+ * open to it, as Keys in order (DM-CLASS-INHERITANCE). A parent the target no longer declares is
6
+ * not closed: losing it is an ancestry change.
7
+ */
8
+ export declare function closedParents({ dependent, target, }: {
9
+ readonly dependent: DomainSchema;
10
+ readonly target: DomainSchema;
11
+ }): readonly Key[];
@@ -0,0 +1,22 @@
1
+ import { compareUnicode } from '../../addressing/ordering.js';
2
+ import { admitsForeignSubclass } from '../../language/class/inheritance.js';
3
+ import { keyForDefinitionRef } from './coordinate.js';
4
+ /**
5
+ * The Classes of the target's origin that a Class of the dependent extends and the target does not
6
+ * open to it, as Keys in order (DM-CLASS-INHERITANCE). A parent the target no longer declares is
7
+ * not closed: losing it is an ancestry change.
8
+ */
9
+ export function closedParents({ dependent, target, }) {
10
+ const closed = new Set();
11
+ if (dependent.origin === target.origin)
12
+ return [];
13
+ for (const declaration of Object.values(dependent.classes))
14
+ for (const parent of declaration.extends) {
15
+ if (parent.origin !== target.origin)
16
+ continue;
17
+ const declared = target.classes[parent.name];
18
+ if (declared !== undefined && !admitsForeignSubclass(declared))
19
+ closed.add(keyForDefinitionRef(parent));
20
+ }
21
+ return Object.freeze([...closed].sort(compareUnicode));
22
+ }
@@ -15,7 +15,7 @@ export type DependencyMeaningLevel = 'reference' | 'inherit';
15
15
  * compile until it is classified, so meaning can only be narrowed by an explicit decision.
16
16
  */
17
17
  export type FieldRole = 'always' | 'inherit' | 'members' | {
18
- readonly excluded: 'identity' | 'annotation' | 'authorization' | 'presentation';
18
+ readonly excluded: 'identity' | 'annotation' | 'authorization' | 'extension' | 'presentation';
19
19
  };
20
20
  /** The coordinate Key already names the declaration; its `ref` is never repeated in the meaning. */
21
21
  export declare const CLASS_FIELDS: Readonly<{
@@ -24,12 +24,16 @@ export declare const CLASS_FIELDS: Readonly<{
24
24
  }>;
25
25
  kind: "always";
26
26
  abstract: "always";
27
+ inheritance: Readonly<{
28
+ excluded: 'extension';
29
+ }>;
27
30
  orientation: "always";
28
31
  extends: "inherit";
29
32
  policies: "inherit";
30
33
  data: "inherit";
31
34
  endpoints: "inherit";
32
35
  constraints: "inherit";
36
+ unique: "always";
33
37
  properties: "members";
34
38
  methods: "members";
35
39
  description: Readonly<{
@@ -50,9 +54,11 @@ export declare const PROPERTY_FIELDS: Readonly<{
50
54
  }>;
51
55
  }>;
52
56
  /**
53
- * The auth level and Policy check are decided by the Runtime at invocation, never compiled against.
54
- * The execution modifier decides what an invocation returns; an accepted Schema carries it only
55
- * when durable, so ordinary callables keep their meaning unchanged.
57
+ * The auth level, the Policy check and the admission age are authorization: decided by the Runtime
58
+ * at invocation, never compiled against. The admission age only bounds how old the admission a
59
+ * destination decides a call under may be. The execution modifier decides what an invocation
60
+ * returns; an accepted Schema carries it only when durable, so ordinary callables keep their meaning
61
+ * unchanged.
56
62
  */
57
63
  export declare const CALLABLE_FIELDS: Readonly<{
58
64
  ref: Readonly<{
@@ -63,6 +69,9 @@ export declare const CALLABLE_FIELDS: Readonly<{
63
69
  static: "always";
64
70
  abstract: "always";
65
71
  execution: "always";
72
+ admission: Readonly<{
73
+ excluded: 'authorization';
74
+ }>;
66
75
  auth: Readonly<{
67
76
  excluded: 'authorization';
68
77
  }>;
@@ -114,12 +123,16 @@ export declare const FIELD_ROLES: Readonly<{
114
123
  }>;
115
124
  kind: "always";
116
125
  abstract: "always";
126
+ inheritance: Readonly<{
127
+ excluded: 'extension';
128
+ }>;
117
129
  orientation: "always";
118
130
  extends: "inherit";
119
131
  policies: "inherit";
120
132
  data: "inherit";
121
133
  endpoints: "inherit";
122
134
  constraints: "inherit";
135
+ unique: "always";
123
136
  properties: "members";
124
137
  methods: "members";
125
138
  description: Readonly<{
@@ -148,6 +161,9 @@ export declare const FIELD_ROLES: Readonly<{
148
161
  static: "always";
149
162
  abstract: "always";
150
163
  execution: "always";
164
+ admission: Readonly<{
165
+ excluded: 'authorization';
166
+ }>;
151
167
  auth: Readonly<{
152
168
  excluded: 'authorization';
153
169
  }>;