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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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 +139 -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
@@ -1,5 +1,6 @@
1
1
  import { Key } from '../../../addressing/index.js';
2
2
  import { definitionRefIndex } from '../../../addressing/ordering.js';
3
+ import { classSatisfies } from '../../../language/class/inheritance.js';
3
4
  import { diagnostic } from '../../diagnostic.js';
4
5
  const formatDefinitionRef = Key.of;
5
6
  export class PolicyValidationContext {
@@ -63,22 +64,10 @@ export class PolicyValidationContext {
63
64
  }
64
65
  /** Return true when candidate is the required Class or a same-kind descendant. */
65
66
  classExtends(candidate, required) {
66
- if (definitionRefIndex(candidate) === definitionRefIndex(required))
67
- return true;
68
- const visited = new Set();
69
- const visit = (ref) => {
70
- const key = definitionRefIndex(ref);
71
- if (key === definitionRefIndex(required))
72
- return true;
73
- if (visited.has(key))
74
- return false;
75
- visited.add(key);
76
- const resolved = this.environment.resolveAny(ref);
77
- if (resolved === undefined || resolved.ref.kind !== 'class')
78
- return false;
79
- return resolved.declaration.extends.some(visit);
80
- };
81
- return visit(candidate);
67
+ const resolve = (ref) => this.environment.resolveAny(ref)?.declaration;
68
+ const actual = resolve(candidate);
69
+ const target = resolve(required);
70
+ return actual !== undefined && target !== undefined && classSatisfies(actual, target, resolve);
82
71
  }
83
72
  add(code, pointer, message, ref) {
84
73
  this.diagnostics.push(diagnostic(code, pointer, message, ref));
@@ -0,0 +1,4 @@
1
+ import type { PolicyObjectRef } from '../../../language/index.js';
2
+ import type { PolicyValidationContext } from './context.js';
3
+ import type { ObjectContract } from './typing.js';
4
+ export declare function referenceContracts(validation: PolicyValidationContext, ref: PolicyObjectRef, pointer: string): readonly ObjectContract[] | undefined;
@@ -0,0 +1,71 @@
1
+ import { definitionRefIndex } from '../../../addressing/ordering.js';
2
+ import { isMethodExecutable } from '../../../language/callable/executable.js';
3
+ import { policyObjectKey, policyObjectOrigin } from '../../../language/index.js';
4
+ const KERNEL_ORIGIN = 'kernel.astrale.ai';
5
+ const PROJECTION_CLASS = nodeClassRef('Class');
6
+ const PROJECTION_FUNCTION = nodeClassRef('Function');
7
+ const PROJECTION_POLICY = nodeClassRef('Policy');
8
+ const PROJECTION_VIEW = nodeClassRef('View');
9
+ export function referenceContracts(validation, ref, pointer) {
10
+ const candidate = validation.environment.candidate;
11
+ const local = policyObjectOrigin(ref) === candidate.origin;
12
+ const direct = Object.values(candidate.dependencies).some((entry) => entry.origin === policyObjectOrigin(ref));
13
+ const owner = local
14
+ ? candidate
15
+ : direct
16
+ ? validation.environment.dependencies.get(policyObjectOrigin(ref))
17
+ : undefined;
18
+ if (owner === undefined)
19
+ return invalidPolicyObjectRef(validation, ref, pointer);
20
+ switch (ref.kind) {
21
+ case 'class': {
22
+ const resolved = validation.environment.resolve(ref);
23
+ return resolved?.ref.kind === ref.kind
24
+ ? [{ kind: 'exact', ref: PROJECTION_CLASS }]
25
+ : invalidPolicyObjectRef(validation, ref, pointer);
26
+ }
27
+ case 'method': {
28
+ const declaringClass = owner.classes[ref.owner.name];
29
+ const method = declaringClass?.kind === 'node' ? declaringClass.methods[ref.name] : undefined;
30
+ return method === undefined || !isMethodExecutable(declaringClass, method)
31
+ ? invalidPolicyObjectRef(validation, ref, pointer)
32
+ : [{ kind: 'exact', ref: PROJECTION_FUNCTION }];
33
+ }
34
+ case 'function':
35
+ return owner.functions[ref.name] === undefined
36
+ ? invalidPolicyObjectRef(validation, ref, pointer)
37
+ : [{ kind: 'exact', ref: PROJECTION_FUNCTION }];
38
+ case 'policy':
39
+ return owner.policies[ref.name] === undefined
40
+ ? invalidPolicyObjectRef(validation, ref, pointer)
41
+ : [{ kind: 'exact', ref: PROJECTION_POLICY }];
42
+ case 'view':
43
+ return owner.views[ref.name] === undefined
44
+ ? invalidPolicyObjectRef(validation, ref, pointer)
45
+ : [{ kind: 'exact', ref: PROJECTION_VIEW }];
46
+ case 'core': {
47
+ const node = owner.core.nodes[ref.name];
48
+ if (node === undefined)
49
+ return invalidPolicyObjectRef(validation, ref, pointer);
50
+ const resolved = validation.environment.resolve(node.class);
51
+ const analyzed = validation.analysis.definitions.get(definitionRefIndex(node.class));
52
+ // Core validation owns invalid Core Class diagnostics. Avoid adding Policy noise for
53
+ // a Node that cannot materialize in the first place.
54
+ if (node.class.origin !== owner.origin ||
55
+ resolved?.ref.kind !== 'class' ||
56
+ resolved.kind !== 'node' ||
57
+ analyzed === undefined) {
58
+ return undefined;
59
+ }
60
+ return [{ kind: 'exact', ref: node.class }];
61
+ }
62
+ }
63
+ return invalidPolicyObjectRef(validation, ref, pointer);
64
+ }
65
+ function invalidPolicyObjectRef(validation, ref, pointer) {
66
+ validation.add('PL_REF', `${pointer}/ref`, `${policyObjectKey(ref)} is not an exact local or direct-dependency projected Policy object.`, policyObjectKey(ref));
67
+ return undefined;
68
+ }
69
+ function nodeClassRef(name) {
70
+ return { origin: KERNEL_ORIGIN, kind: 'class', name };
71
+ }
@@ -1,7 +1,9 @@
1
1
  import { branchesOf, isConnected, targetMode } from '../../../language/policy/analysis/branches.js';
2
+ import { policyVariableClass } from '../../../language/policy/model/policy.js';
2
3
  import { normalizePolicyExpression, normalizePolicyPattern, } from '../../../language/policy/normalization/normalize.js';
3
4
  import { MAX_REPEAT, MAX_VARIABLES } from './budgets.js';
4
5
  import { escapePointer } from './context.js';
6
+ import { referenceContracts } from './objects.js';
5
7
  export function validatePolicyReferences(context) {
6
8
  for (const [name, declaration] of Object.entries(context.environment.candidate.policies)) {
7
9
  const pointer = `/policies/${escapePointer(name)}`;
@@ -34,15 +36,20 @@ function validateMatch(context, name, pattern, pointer) {
34
36
  for (const [index, branch] of branches.entries()) {
35
37
  const mode = targetMode(branch);
36
38
  if (mode === undefined) {
37
- context.add('PL_TARGET', `${pointer}/match`, `Normalized branch ${index} must use object or both source and target, without mixing target modes.`);
39
+ context.add('PL_TARGET', `${pointer}/match`, `Normalized branch ${index} must use object or at least one of source and target, without mixing target modes.`);
38
40
  continue;
39
41
  }
40
42
  if (!isConnected(branch)) {
41
- context.add('PL_CONNECTIVITY', `${pointer}/match`, `Normalized ${mode} branch ${index} does not connect subject, its target terms, and every scoped term.`);
43
+ context.add('PL_CONNECTIVITY', `${pointer}/match`, `Normalized ${mode} branch ${index} does not connect subject, every referenced protected term, and every scoped term.`);
42
44
  }
43
45
  }
44
46
  }
45
47
  function validatePatternNode(context, pattern, pointer, scope, declarations, uses) {
48
+ if ('sameNode' in pattern) {
49
+ validateTerm(context, pattern.sameNode.left, `${pointer}/sameNode/left`, scope, uses);
50
+ validateTerm(context, pattern.sameNode.right, `${pointer}/sameNode/right`, scope, uses);
51
+ return;
52
+ }
46
53
  if (isEdge(pattern)) {
47
54
  context.resolveEdge(pattern.class, `${pointer}/class`);
48
55
  validateTerm(context, pattern.source, `${pointer}/source`, scope, uses);
@@ -71,13 +78,16 @@ function validatePatternNode(context, pattern, pointer, scope, declarations, use
71
78
  context.add('PL_VARIABLE_SCOPE', `${declarationPointer}/variable/id`, `Variable ${id} is declared more than once; variable IDs are globally unique.`);
72
79
  }
73
80
  else {
74
- declarations.set(id, { ref: node.class, pointer: declarationPointer });
81
+ declarations.set(id, { pointer: declarationPointer });
75
82
  }
76
83
  if (nested.has(id)) {
77
84
  context.add('PL_VARIABLE_SCOPE', `${declarationPointer}/variable/id`, `Variable ${id} shadows an enclosing variable.`);
78
85
  }
79
86
  nested.add(id);
80
- context.resolveNodeClass(node.class, `${declarationPointer}/class`);
87
+ const classRef = policyVariableClass(node);
88
+ if (classRef !== undefined) {
89
+ context.resolveNodeClass(classRef, `${declarationPointer}/${'class' in node ? 'class' : 'selector/class'}`);
90
+ }
81
91
  }
82
92
  validatePatternNode(context, pattern.exists.where, `${pointer}/exists/where`, nested, declarations, uses);
83
93
  return;
@@ -89,6 +99,8 @@ function validatePatternNode(context, pattern, pointer, scope, declarations, use
89
99
  values.forEach((child, index) => validatePatternNode(context, child, `${pointer}/${key}/${index}`, scope, declarations, uses));
90
100
  }
91
101
  function validateTerm(context, term, pointer, scope, uses) {
102
+ if (term.kind === 'ref')
103
+ referenceContracts(context, term.ref, pointer);
92
104
  if (term.kind === 'variable') {
93
105
  if (!scope.has(term.id)) {
94
106
  context.add('PL_VARIABLE_SCOPE', pointer, `Variable ${term.id} is free, escaped, or outside its defining exists scope.`);
@@ -12,6 +12,8 @@ export declare class PolicyTyping {
12
12
  constructor(context: PolicyValidationContext);
13
13
  validatePolicies(): void;
14
14
  policyAccepts(name: string, object: ObjectContract): boolean;
15
+ /** Whether each normalized branch of the Policy is typed for an object of this contract. */
16
+ policyBranchTyping(name: string, object: ObjectContract): readonly boolean[] | undefined;
15
17
  policyAcceptsEdge(name: string, source: ObjectContract, target: ObjectContract): boolean;
16
18
  concreteEndpointClasses(accepts: readonly ClassRef[]): readonly ClassRef[];
17
19
  endpointsOverlap(left: readonly ClassRef[], right: readonly ClassRef[]): boolean;
@@ -2,8 +2,16 @@ import { definitionRefIndex } from '../../../addressing/ordering.js';
2
2
  import { branchesOf, branchProduct, capBranches, targetMode, termKey, } from '../../../language/policy/analysis/branches.js';
3
3
  import { MAX_REPEAT } from './budgets.js';
4
4
  import { escapePointer } from './context.js';
5
+ import { referenceContracts } from './objects.js';
5
6
  export class PolicyTyping {
6
7
  context;
8
+ // Expanded branches of each named Policy, cached by node identity. A Policy's expansion is reused
9
+ // across every composition path that reaches it (and across every use site and object contract,
10
+ // none of which the expansion depends on), so a shared-child composition DAG is expanded in work
11
+ // linear in the number of Policies instead of enumerating every path. The expansion result is
12
+ // independent of the reaching path up to the opaque term-namespace labels, which only ever
13
+ // disambiguate variables within one branch and leave targetMode and branch typing unchanged.
14
+ #expansions = new Map();
7
15
  constructor(context) {
8
16
  this.context = context;
9
17
  }
@@ -16,7 +24,7 @@ export class PolicyTyping {
16
24
  const mode = targetMode(branch);
17
25
  if (mode === undefined) {
18
26
  if (!('match' in this.context.environment.candidate.policies[name].expression)) {
19
- this.context.add('PL_TARGET', `/policies/${escapePointer(name)}`, `Expanded normalized branch ${index} must use object or both source and target, without mixing target modes.`);
27
+ this.context.add('PL_TARGET', `/policies/${escapePointer(name)}`, `Expanded normalized branch ${index} must use object or at least one of source and target, without mixing target modes.`);
20
28
  }
21
29
  continue;
22
30
  }
@@ -34,9 +42,13 @@ export class PolicyTyping {
34
42
  }
35
43
  }
36
44
  policyAccepts(name, object) {
45
+ return this.policyBranchTyping(name, object)?.every(Boolean) ?? false;
46
+ }
47
+ /** Whether each normalized branch of the Policy is typed for an object of this contract. */
48
+ policyBranchTyping(name, object) {
37
49
  const branches = this.#expandedBranches(name, new Set(), `$use:${name}`);
38
50
  const use = { kind: 'object', object };
39
- return branches !== undefined && branches.every((branch) => this.#branchIsTyped(branch, use));
51
+ return branches?.map((branch) => this.#branchIsTyped(branch, use));
40
52
  }
41
53
  policyAcceptsEdge(name, source, target) {
42
54
  const branches = this.#expandedBranches(name, new Set(), `$edge-use:${name}`);
@@ -54,6 +66,14 @@ export class PolicyTyping {
54
66
  #expandedBranches(name, visiting, namespace) {
55
67
  if (visiting.has(name))
56
68
  return undefined;
69
+ const cached = this.#expansions.get(name);
70
+ if (cached !== undefined || this.#expansions.has(name))
71
+ return cached;
72
+ const expanded = this.#expandDeclaration(name, visiting, namespace);
73
+ this.#expansions.set(name, expanded);
74
+ return expanded;
75
+ }
76
+ #expandDeclaration(name, visiting, namespace) {
57
77
  const declaration = this.context.normalized.get(name);
58
78
  if (declaration === undefined)
59
79
  return undefined;
@@ -83,11 +103,15 @@ export class PolicyTyping {
83
103
  const terms = new Set(use.kind === 'object' ? ['subject', 'object'] : ['subject', 'source', 'target']);
84
104
  for (const key of branch.variables.keys())
85
105
  terms.add(key);
106
+ for (const key of branch.terms.keys())
107
+ terms.add(key);
86
108
  for (const edge of branch.edges) {
87
109
  terms.add(termKey(edge.pattern.source, edge.namespace));
88
110
  terms.add(termKey(edge.pattern.target, edge.namespace));
89
111
  }
90
112
  const union = new UnionFind(terms);
113
+ for (const [left, right] of branch.equalities)
114
+ union.join(left, right);
91
115
  for (const variant of variants) {
92
116
  for (const [left, right] of variant.equalities)
93
117
  union.join(left, right);
@@ -136,11 +160,19 @@ export class PolicyTyping {
136
160
  }
137
161
  return candidates;
138
162
  }
139
- const exact = this.#exactInitial(term, branch);
140
- return exact === undefined ? [] : this.#applyExact(candidates, exact);
141
- }
142
- #exactInitial(term, branch) {
143
- return branch.variables.get(term);
163
+ const referenced = branch.terms.get(term);
164
+ if (referenced?.kind === 'ref') {
165
+ const contract = referenceContracts(this.context, referenced.ref, '/policies')?.[0];
166
+ return contract?.kind === 'exact' ? this.#applyExact(candidates, contract.ref) : [];
167
+ }
168
+ const selector = branch.variables.get(term);
169
+ if (selector === undefined)
170
+ return [];
171
+ if (selector.kind === 'exact')
172
+ return this.#applyExact(candidates, selector.class);
173
+ if (selector.kind === 'any')
174
+ return candidates;
175
+ return this.#applyRequirement(candidates, selector.class);
144
176
  }
145
177
  #applyExact(candidates, exact) {
146
178
  const result = [];
@@ -162,6 +194,22 @@ export class PolicyTyping {
162
194
  .filter((ref) => candidate.requirements.every((required) => this.context.classExtends(ref, required)))
163
195
  .map((ref) => ({ kind: 'exact', ref }))));
164
196
  }
197
+ #applyRequirement(candidates, required) {
198
+ const result = [];
199
+ for (const candidate of candidates) {
200
+ if (candidate.kind === 'exact') {
201
+ if (this.context.classExtends(candidate.ref, required))
202
+ result.push(candidate);
203
+ }
204
+ else {
205
+ result.push({
206
+ kind: 'open',
207
+ requirements: uniqueClasses([...candidate.requirements, required]),
208
+ });
209
+ }
210
+ }
211
+ return uniqueCandidates(result);
212
+ }
165
213
  #applyEndpoint(candidates, accepts) {
166
214
  const result = [];
167
215
  for (const candidate of candidates) {
@@ -1,40 +1,43 @@
1
1
  import { Key } from '../../../addressing/index.js';
2
2
  import { definitionRefIndex } from '../../../addressing/ordering.js';
3
+ import { isBinaryInput } from '../../../language/callable/model/callable.js';
4
+ import { admittedCheckClasses, neverAdmittedClasses, } from '../../../language/policy/analysis/checks.js';
5
+ import { checksNameTheCaller, isClassRuleChecks } from '../../../language/policy/model/policy.js';
3
6
  import { normalizePolicyChecks } from '../../../language/policy/normalization/normalize.js';
4
7
  import { GRAPH_NODE_PATH_SCHEMA_ID } from '../../../language/value/syntax/node-path/schema.js';
5
8
  import { MAX_BRANCHES, MAX_CHECK_DEPTH, MAX_CHECK_LEAVES, measureChecks } from './budgets.js';
6
9
  import { escapePointer } from './context.js';
10
+ import { referenceContracts } from './objects.js';
7
11
  import { contractOfNodeDefinition } from './typing.js';
8
12
  const formatDefinitionRef = Key.of;
9
- const KERNEL_ORIGIN = 'kernel.astrale.ai';
10
- const PROJECTION_CLASS = nodeClassRef('Class');
11
- const PROJECTION_FUNCTION = nodeClassRef('Function');
12
- const PROJECTION_POLICY = nodeClassRef('Policy');
13
- const PROJECTION_VIEW = nodeClassRef('View');
13
+ /** How a refusal names the checks of each site and the contract of their objects. */
14
+ const SITE = {
15
+ callable: { checks: 'Callable checks', objects: 'the callable object contract' },
16
+ class: { checks: 'Class rule checks', objects: 'the Class rule object contract' },
17
+ };
14
18
  export function validateReadUses(context, typing) {
15
- for (const [name, declaration] of Object.entries(context.environment.candidate.classes)) {
16
- if (declaration.kind !== 'node' || declaration.policies.read === undefined) {
17
- continue;
18
- }
19
- const pointer = `/classes/${escapePointer(name)}/policies/read`;
20
- const ref = declaration.policies.read;
21
- if (!context.resolvePolicy(ref, pointer))
22
- continue;
23
- const object = {
24
- kind: 'exact',
25
- ref: { origin: context.environment.candidate.origin, kind: 'class', name },
26
- };
27
- if (!typing.policyAccepts(ref.name, object)) {
28
- context.add('PL_USE', pointer, `${formatDefinitionRef(ref)} is not valid for every normalized branch of protected Class ${name}.`, formatDefinitionRef(ref));
29
- }
30
- }
19
+ validateClassPolicyUses(context, typing, 'read');
31
20
  }
32
21
  export function validateTraverseUses(context, typing) {
22
+ validateClassPolicyUses(context, typing, 'traverse');
23
+ }
24
+ function validateClassPolicyUses(context, typing, operation) {
33
25
  for (const [name, declaration] of Object.entries(context.environment.candidate.classes)) {
34
- const ref = declaration.policies.traverse;
35
- if (ref === undefined)
26
+ const ref = declaration.policies[operation];
27
+ if (typeof ref !== 'object')
28
+ continue;
29
+ const pointer = `/classes/${escapePointer(name)}/policies/${operation}`;
30
+ if (isClassRuleChecks(ref)) {
31
+ // Structure admits Policy checks only on a Node Class: `self` is the observed exact Class.
32
+ validateChecks(context, typing, ref, {
33
+ site: 'class',
34
+ pointer,
35
+ input: {},
36
+ receiver: { origin: context.environment.candidate.origin, kind: 'class', name },
37
+ instanceMethod: true,
38
+ });
36
39
  continue;
37
- const pointer = `/classes/${escapePointer(name)}/policies/traverse`;
40
+ }
38
41
  if (!context.resolvePolicy(ref, pointer))
39
42
  continue;
40
43
  if (declaration.kind === 'node') {
@@ -42,9 +45,9 @@ export function validateTraverseUses(context, typing) {
42
45
  kind: 'exact',
43
46
  ref: { origin: context.environment.candidate.origin, kind: 'class', name },
44
47
  };
45
- if (!typing.policyAccepts(ref.name, object)) {
46
- context.add('PL_USE', pointer, `${formatDefinitionRef(ref)} is not valid for every normalized branch of traversed Node Class ${name}.`, formatDefinitionRef(ref));
47
- }
48
+ if (typing.policyAccepts(ref.name, object))
49
+ continue;
50
+ context.add('PL_USE', pointer, `${formatDefinitionRef(ref)} is not valid for every normalized branch of ${operation} Node Class ${name}.`, formatDefinitionRef(ref));
48
51
  continue;
49
52
  }
50
53
  const endpoints = declaration.orientation === 'directed'
@@ -52,29 +55,20 @@ export function validateTraverseUses(context, typing) {
52
55
  : declaration.endpoints;
53
56
  const sources = typing.concreteEndpointClasses(endpoints[0].accepts);
54
57
  const targets = typing.concreteEndpointClasses(endpoints[1].accepts);
55
- let accepted = true;
56
- for (const source of sources) {
57
- for (const target of targets) {
58
- if (!typing.policyAcceptsEdge(ref.name, { kind: 'exact', ref: source }, { kind: 'exact', ref: target })) {
59
- accepted = false;
60
- break;
61
- }
62
- }
63
- if (!accepted)
64
- break;
65
- }
58
+ const accepted = sources.every((source) => targets.every((target) => typing.policyAcceptsEdge(ref.name, { kind: 'exact', ref: source }, { kind: 'exact', ref: target })));
66
59
  if (!accepted) {
67
- context.add('PL_USE', pointer, `${formatDefinitionRef(ref)} is not valid for every concrete source/target pair of traversed Edge Class ${name}.`, formatDefinitionRef(ref));
60
+ context.add('PL_USE', pointer, `${formatDefinitionRef(ref)} is not valid for every concrete source/target pair of ${operation} Edge Class ${name}.`, formatDefinitionRef(ref));
68
61
  }
69
62
  }
70
63
  }
71
64
  export function validateCallableUses(context, typing) {
72
65
  for (const [name, declaration] of Object.entries(context.environment.candidate.functions)) {
73
- if (declaration.policy === undefined)
66
+ if (typeof declaration.policy !== 'object')
74
67
  continue;
75
68
  validateChecks(context, typing, declaration.policy, {
69
+ site: 'callable',
76
70
  pointer: `/functions/${escapePointer(name)}/policy`,
77
- input: declaration.input,
71
+ input: isBinaryInput(declaration.input) ? declaration.input.metadata : declaration.input,
78
72
  instanceMethod: false,
79
73
  });
80
74
  }
@@ -91,7 +85,7 @@ export function validateCallableUses(context, typing) {
91
85
  function validateDeclaredMethods(context, typing, namespace, name, methods, receiver) {
92
86
  const ownerAnalysis = context.analysis.definitions.get(definitionRefIndex(receiver));
93
87
  for (const [methodName, method] of Object.entries(methods)) {
94
- if (method.policy === undefined)
88
+ if (typeof method.policy !== 'object')
95
89
  continue;
96
90
  // Definition analysis is the authority for the effective callable. A
97
91
  // missing entry is already a definition diagnostic, so avoid inventing a
@@ -99,6 +93,7 @@ function validateDeclaredMethods(context, typing, namespace, name, methods, rece
99
93
  if (ownerAnalysis !== undefined && !ownerAnalysis.methods.has(methodName))
100
94
  continue;
101
95
  validateChecks(context, typing, method.policy, {
96
+ site: 'callable',
102
97
  pointer: `/${namespace}/${escapePointer(name)}/methods/${escapePointer(methodName)}/policy`,
103
98
  input: method.input,
104
99
  receiver,
@@ -107,16 +102,37 @@ function validateDeclaredMethods(context, typing, namespace, name, methods, rece
107
102
  }
108
103
  }
109
104
  function validateChecks(validation, typing, expression, context) {
105
+ // Checks decide the caller the way a named Policy does, so, as a Policy connects its subject,
106
+ // each way they hold must pass through a check of the caller.
107
+ if (!checksNameTheCaller(expression)) {
108
+ validation.add('PL_CONNECTIVITY', context.pointer, `${SITE[context.site].checks} must check a Policy on every branch: sameNode alone names no caller.`);
109
+ }
110
110
  const normalized = normalizePolicyChecks(expression);
111
111
  const measure = measureChecks(normalized);
112
112
  if (measure.depth > MAX_CHECK_DEPTH ||
113
113
  measure.branches > MAX_BRANCHES ||
114
114
  measure.leaves > MAX_CHECK_LEAVES) {
115
- validation.add('PL_BUDGET', context.pointer, `Callable checks require depth <= ${MAX_CHECK_DEPTH}, branches <= ${MAX_BRANCHES}, and leaves <= ${MAX_CHECK_LEAVES}; got ${measure.depth}, ${measure.branches}, ${measure.leaves}.`);
115
+ validation.add('PL_BUDGET', context.pointer, `${SITE[context.site].checks} require depth <= ${MAX_CHECK_DEPTH}, branches <= ${MAX_BRANCHES}, and leaves <= ${MAX_CHECK_LEAVES}; got ${measure.depth}, ${measure.branches}, ${measure.leaves}.`);
116
+ }
117
+ const leaves = new Map();
118
+ visitChecks(validation, typing, normalized, context, context.pointer, leaves);
119
+ for (const [object, className] of neverAdmittedClasses(normalized, leaves)) {
120
+ validation.add('PL_USE', context.pointer, `${SITE[context.site].checks} can never admit ${object} of Class ${className}.`, className);
116
121
  }
117
- visitChecks(validation, typing, normalized, context, context.pointer);
118
122
  }
119
- function visitChecks(validation, typing, expression, context, pointer) {
123
+ function visitChecks(validation, typing, expression, context, pointer, leaves) {
124
+ if ('sameNode' in expression) {
125
+ for (const [side, object] of Object.entries(expression.sameNode)) {
126
+ const objectPointer = `${pointer}/sameNode/${side}`;
127
+ if (object.kind === 'self')
128
+ selfContracts(validation, context, objectPointer);
129
+ else if (object.kind === 'input')
130
+ inputContracts(validation, context, object.field, objectPointer);
131
+ else
132
+ referenceContracts(validation, object.ref, objectPointer);
133
+ }
134
+ return;
135
+ }
120
136
  if ('check' in expression) {
121
137
  if (!validation.resolvePolicy(expression.check, `${pointer}/check`))
122
138
  return;
@@ -128,65 +144,26 @@ function visitChecks(validation, typing, expression, context, pointer) {
128
144
  : referenceContracts(validation, expression.object.ref, objectPointer);
129
145
  if (contracts === undefined)
130
146
  return;
131
- for (const contract of contracts) {
132
- if (!typing.policyAccepts(expression.check.name, contract)) {
133
- validation.add('PL_USE', pointer, `${formatDefinitionRef(expression.check)} is incompatible with the callable object contract.`, formatDefinitionRef(expression.check));
134
- break;
135
- }
147
+ const typings = new Map(contracts.map((contract) => [
148
+ contractName(contract),
149
+ typing.policyBranchTyping(expression.check.name, contract),
150
+ ]));
151
+ const admitted = admittedCheckClasses(typings);
152
+ if (admitted === undefined) {
153
+ validation.add('PL_USE', pointer, `${formatDefinitionRef(expression.check)} is incompatible with ${SITE[context.site].objects}.`, formatDefinitionRef(expression.check));
154
+ return;
136
155
  }
156
+ leaves.set(expression, { accepted: [...typings.keys()], admitted });
137
157
  return;
138
158
  }
139
159
  const { key, values } = checkOperands(expression);
140
160
  if (values.length === 0) {
141
161
  validation.add('PL_COMPOSITION', `${pointer}/${key}`, `${key} must be non-empty.`);
142
162
  }
143
- values.forEach((child, index) => visitChecks(validation, typing, child, context, `${pointer}/${key}/${index}`));
163
+ values.forEach((child, index) => visitChecks(validation, typing, child, context, `${pointer}/${key}/${index}`, leaves));
144
164
  }
145
- function referenceContracts(validation, ref, pointer) {
146
- const candidate = validation.environment.candidate;
147
- if (ref.origin !== candidate.origin)
148
- return invalidPolicyObjectRef(validation, ref, pointer);
149
- switch (ref.kind) {
150
- case 'class': {
151
- const resolved = validation.environment.resolve(ref);
152
- return resolved?.ref.kind === ref.kind
153
- ? [{ kind: 'exact', ref: PROJECTION_CLASS }]
154
- : invalidPolicyObjectRef(validation, ref, pointer);
155
- }
156
- case 'function':
157
- return candidate.functions[ref.name] === undefined
158
- ? invalidPolicyObjectRef(validation, ref, pointer)
159
- : [{ kind: 'exact', ref: PROJECTION_FUNCTION }];
160
- case 'policy':
161
- return candidate.policies[ref.name] === undefined
162
- ? invalidPolicyObjectRef(validation, ref, pointer)
163
- : [{ kind: 'exact', ref: PROJECTION_POLICY }];
164
- case 'view':
165
- return candidate.views[ref.name] === undefined
166
- ? invalidPolicyObjectRef(validation, ref, pointer)
167
- : [{ kind: 'exact', ref: PROJECTION_VIEW }];
168
- case 'core': {
169
- const node = candidate.core.nodes[ref.name];
170
- if (node === undefined)
171
- return invalidPolicyObjectRef(validation, ref, pointer);
172
- const resolved = validation.environment.resolve(node.class);
173
- const analyzed = validation.analysis.definitions.get(definitionRefIndex(node.class));
174
- // Core validation owns invalid Core Class diagnostics. Avoid adding Policy noise for
175
- // a Node that cannot materialize in the first place.
176
- if (node.class.origin !== candidate.origin ||
177
- resolved?.ref.kind !== 'class' ||
178
- resolved.kind !== 'node' ||
179
- analyzed === undefined) {
180
- return undefined;
181
- }
182
- return [contractOfNodeDefinition(node.class)];
183
- }
184
- }
185
- return invalidPolicyObjectRef(validation, ref, pointer);
186
- }
187
- function invalidPolicyObjectRef(validation, ref, pointer) {
188
- validation.add('PL_REF', `${pointer}/ref`, `${formatDefinitionRef(ref)} is not an exact local projected Policy object.`, formatDefinitionRef(ref));
189
- return undefined;
165
+ function contractName(contract) {
166
+ return contract.kind === 'exact' ? formatDefinitionRef(contract.ref) : 'default';
190
167
  }
191
168
  function selfContracts(validation, context, pointer) {
192
169
  if (!context.instanceMethod || context.receiver === undefined) {
@@ -253,6 +230,3 @@ function checkOperands(value) {
253
230
  ? { key: 'allOf', values: value.allOf }
254
231
  : { key: 'anyOf', values: value.anyOf };
255
232
  }
256
- function nodeClassRef(name) {
257
- return { origin: KERNEL_ORIGIN, kind: 'class', name };
258
- }
@@ -4,6 +4,8 @@ import type { JsonSchema } from '../../language/value/model/schema.js';
4
4
  import type { OrderingKind } from '../../language/value/ordering.js';
5
5
  import type { DomainSchema } from '../model/schema.js';
6
6
  export { VALUE_SCHEMA_DIALECT as DIALECT, VALUE_SCHEMA_VOCABULARY as VOCABULARY, } from '../../language/value/model/schema.js';
7
+ export { blob, isBlobValueSchema as isBlob } from '../../language/value/model/blob.js';
8
+ export type { BlobOptions, BlobReceipt, BlobRef, BlobSchema, } from '../../language/value/model/blob.js';
7
9
  export type { JsonSchema as Schema, JsonSchemaObject as SchemaObject, PathAnnotation, PropertyObjectSchema as PropertySchema, ValueSchemaContext as Context, } from '../../language/value/model/schema.js';
8
10
  export { instant } from '../../language/value/model/instant.js';
9
11
  export type { OrderingKind } from '../../language/value/ordering.js';
@@ -4,6 +4,7 @@ import { classifyOrdering as classifyOrderingWithRegistry } from '../../language
4
4
  import { createDomainValueSchemaRegistry } from '../resolution/value.registry.js';
5
5
  const registries = new WeakMap();
6
6
  export { VALUE_SCHEMA_DIALECT as DIALECT, VALUE_SCHEMA_VOCABULARY as VOCABULARY, } from '../../language/value/model/schema.js';
7
+ export { blob, isBlobValueSchema as isBlob } from '../../language/value/model/blob.js';
7
8
  export { instant } from '../../language/value/model/instant.js';
8
9
  /** Validate one complete JSON value under the exact accepted schema that owns the contract. */
9
10
  export function validate(owner, contract, input, pointer = '') {
@@ -1,3 +1,4 @@
1
+ import { isBinaryInput } from '../../language/callable/model/callable.js';
1
2
  import { validateValueSchema } from '../../language/value/profile/validate.js';
2
3
  import { diagnostic } from '../diagnostic.js';
3
4
  export function validateEmbeddedValueSchemas(schema, registry) {
@@ -21,7 +22,12 @@ function validateDefinition(declaration, pointer, registry, diagnostics) {
21
22
  }
22
23
  }
23
24
  function validateCallable(declaration, pointer, registry, diagnostics) {
24
- validate(declaration.input, 'callable-input', `${pointer}/input`, registry, diagnostics);
25
+ if (isBinaryInput(declaration.input)) {
26
+ validate(declaration.input.metadata, 'callable-input', `${pointer}/input/metadata`, registry, diagnostics);
27
+ }
28
+ else {
29
+ validate(declaration.input, 'callable-input', `${pointer}/input`, registry, diagnostics);
30
+ }
25
31
  if (declaration.output.mode === 'value') {
26
32
  validate(declaration.output.schema, 'callable-output', `${pointer}/output/schema`, registry, diagnostics);
27
33
  }
@@ -9,21 +9,26 @@ export function validateViews(environment) {
9
9
  if (!sameRef(view.ref, ref)) {
10
10
  diagnostics.push(diagnostic('DV_REF_RESOLVES', `${pointer}/ref`, `View ref must be exactly ${formatDefinitionRef(ref)}.`, formatDefinitionRef(view.ref)));
11
11
  }
12
- if (view.target.kind === 'definition') {
13
- view.target.definitions.forEach((ref, index) => validateDefinitionTarget(environment, ref, `${pointer}/target/definitions/${index}`, diagnostics));
14
- }
15
12
  }
13
+ validateEntrypoint(environment, diagnostics);
16
14
  return Object.freeze(diagnostics);
17
15
  }
16
+ /** The entrypoint names one View this Domain declares for itself. */
17
+ function validateEntrypoint(environment, diagnostics) {
18
+ const { entrypoint, origin, views } = environment.candidate;
19
+ if (entrypoint === undefined)
20
+ return;
21
+ // An own member only: a name such as `constructor` must not resolve on the prototype.
22
+ const view = entrypoint.origin === origin && Object.hasOwn(views, entrypoint.name)
23
+ ? views[entrypoint.name]
24
+ : undefined;
25
+ if (view === undefined) {
26
+ diagnostics.push(diagnostic('DV_ENTRYPOINT', '/entrypoint', `Entrypoint ${formatDefinitionRef(entrypoint)} is not a Domain-targeted View of ${origin}.`, formatDefinitionRef(entrypoint)));
27
+ }
28
+ }
18
29
  function sameRef(left, right) {
19
30
  return left.origin === right.origin && left.kind === right.kind && left.name === right.name;
20
31
  }
21
- function validateDefinitionTarget(environment, ref, pointer, diagnostics) {
22
- const target = environment.resolve(ref);
23
- if (target === undefined || target.ref.kind !== 'class' || target.kind !== 'node') {
24
- diagnostics.push(diagnostic('DV_VIEW_TARGET', pointer, `Definition target ${formatDefinitionRef(ref)} does not resolve to a Node Class.`, formatDefinitionRef(ref)));
25
- }
26
- }
27
32
  function escapePointer(value) {
28
33
  return value.replaceAll('~', '~0').replaceAll('/', '~1');
29
34
  }