@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,119 +1,92 @@
1
1
  import { Key } from '../../../addressing/index.js';
2
2
  import { definitionRefIndex } from '../../../addressing/ordering.js';
3
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';
4
+ import { neverAdmittedClasses, } from '../../../language/policy/analysis/checks.js';
5
+ import { CLASS_OPERATIONS, checksNameTheCaller, isClassRuleChecks, } from '../../../language/policy/model/policy.js';
6
6
  import { normalizePolicyChecks } from '../../../language/policy/normalization/normalize.js';
7
7
  import { GRAPH_NODE_PATH_SCHEMA_ID } from '../../../language/value/syntax/node-path/schema.js';
8
- import { MAX_BRANCHES, MAX_CHECK_DEPTH, MAX_CHECK_LEAVES, measureChecks } from './budgets.js';
9
- import { escapePointer } from './context.js';
8
+ import { escapePointerToken } from '../../../language/value/syntax/pointer.js';
9
+ import { declaredContracts } from '../callable.js';
10
10
  import { referenceContracts } from './objects.js';
11
11
  import { contractOfNodeDefinition } from './typing.js';
12
12
  const formatDefinitionRef = Key.of;
13
13
  /** How a refusal names the checks of each site and the contract of their objects. */
14
- const SITE = {
14
+ export const SITE = {
15
15
  callable: { checks: 'Callable checks', objects: 'the callable object contract' },
16
16
  class: { checks: 'Class rule checks', objects: 'the Class rule object contract' },
17
17
  };
18
- export function validateReadUses(context, typing) {
19
- validateClassPolicyUses(context, typing, 'read');
20
- }
21
- export function validateTraverseUses(context, typing) {
22
- validateClassPolicyUses(context, typing, 'traverse');
18
+ /** Type every Class slot: its Policy against the instance it decides, or its Policy checks. */
19
+ export function validateClassUses(context, typing) {
20
+ for (const operation of CLASS_OPERATIONS)
21
+ validateClassPolicyUses(context, typing, operation);
23
22
  }
24
23
  function validateClassPolicyUses(context, typing, operation) {
25
24
  for (const [name, declaration] of Object.entries(context.environment.candidate.classes)) {
26
25
  const ref = declaration.policies[operation];
27
26
  if (typeof ref !== 'object')
28
27
  continue;
29
- const pointer = `/classes/${escapePointer(name)}/policies/${operation}`;
28
+ const pointer = `/classes/${escapePointerToken(name)}/policies/${operation}`;
29
+ const self = { origin: context.environment.candidate.origin, kind: 'class', name };
30
30
  if (isClassRuleChecks(ref)) {
31
- // A rule decides the caller the way a named Policy does, so, as a Policy connects its
32
- // subject, each way the rule holds must pass through a check of the caller.
33
- if (!checksNameTheCaller(ref)) {
34
- context.add('PL_CONNECTIVITY', pointer, `Every branch of the ${operation} rule of Node Class ${name} must check a Policy: sameNode alone names no caller.`);
35
- }
36
- // Structure admits Policy checks only on a Node Class: `self` is the observed exact Class.
31
+ // Structure admits `self` everywhere but in a Node create rule: there is no Node yet.
37
32
  validateChecks(context, typing, ref, {
38
33
  site: 'class',
39
34
  pointer,
40
35
  input: {},
41
- receiver: { origin: context.environment.candidate.origin, kind: 'class', name },
42
- instanceMethod: true,
36
+ ...(declaration.kind === 'node'
37
+ ? { receiver: self }
38
+ : { edge: { ref: self, declaration } }),
43
39
  });
44
40
  continue;
45
41
  }
46
42
  if (!context.resolvePolicy(ref, pointer))
47
43
  continue;
48
44
  if (declaration.kind === 'node') {
49
- const object = {
50
- kind: 'exact',
51
- ref: { origin: context.environment.candidate.origin, kind: 'class', name },
52
- };
45
+ const object = { kind: 'exact', ref: self };
53
46
  if (typing.policyAccepts(ref.name, object))
54
47
  continue;
55
48
  context.add('PL_USE', pointer, `${formatDefinitionRef(ref)} is not valid for every normalized branch of ${operation} Node Class ${name}.`, formatDefinitionRef(ref));
56
49
  continue;
57
50
  }
58
- const endpoints = declaration.orientation === 'directed'
59
- ? [declaration.endpoints.source, declaration.endpoints.target]
60
- : declaration.endpoints;
61
- const sources = typing.concreteEndpointClasses(endpoints[0].accepts);
62
- const targets = typing.concreteEndpointClasses(endpoints[1].accepts);
63
- const accepted = sources.every((source) => targets.every((target) => typing.policyAcceptsEdge(ref.name, { kind: 'exact', ref: source }, { kind: 'exact', ref: target })));
64
- if (!accepted) {
51
+ if (!typing.policyAcceptsEdgeClass(ref.name, declaration)) {
65
52
  context.add('PL_USE', pointer, `${formatDefinitionRef(ref)} is not valid for every concrete source/target pair of ${operation} Edge Class ${name}.`, formatDefinitionRef(ref));
66
53
  }
67
54
  }
68
55
  }
69
56
  export function validateCallableUses(context, typing) {
70
- for (const [name, declaration] of Object.entries(context.environment.candidate.functions)) {
71
- if (typeof declaration.policy !== 'object')
72
- continue;
73
- validateChecks(context, typing, declaration.policy, {
74
- site: 'callable',
75
- pointer: `/functions/${escapePointer(name)}/policy`,
76
- input: isBinaryInput(declaration.input) ? declaration.input.metadata : declaration.input,
77
- instanceMethod: false,
78
- });
79
- }
80
- for (const [name, declaration] of Object.entries(context.environment.candidate.classes)) {
81
- if (declaration.kind !== 'node')
82
- continue;
83
- validateDeclaredMethods(context, typing, 'classes', name, declaration.methods, {
84
- origin: context.environment.candidate.origin,
85
- kind: 'class',
86
- name,
87
- });
57
+ for (const { contract, pointer, receiver, method } of declaredContracts(context.environment.candidate)) {
58
+ // Definition analysis is the authority for the effective callable. A missing Method is already
59
+ // a definition diagnostic, so avoid inventing a second Policy interpretation for it.
60
+ if (method !== undefined) {
61
+ const owner = context.analysis.definitions.get(definitionRefIndex(method.owner));
62
+ if (owner !== undefined && !owner.methods.has(method.name))
63
+ continue;
64
+ }
65
+ validateContractPolicy(context, typing, contract, pointer, receiver);
88
66
  }
89
67
  }
90
- function validateDeclaredMethods(context, typing, namespace, name, methods, receiver) {
91
- const ownerAnalysis = context.analysis.definitions.get(definitionRefIndex(receiver));
92
- for (const [methodName, method] of Object.entries(methods)) {
93
- if (typeof method.policy !== 'object')
94
- continue;
95
- // Definition analysis is the authority for the effective callable. A
96
- // missing entry is already a definition diagnostic, so avoid inventing a
97
- // second Policy interpretation for it.
98
- if (ownerAnalysis !== undefined && !ownerAnalysis.methods.has(methodName))
99
- continue;
100
- validateChecks(context, typing, method.policy, {
101
- site: 'callable',
102
- pointer: `/${namespace}/${escapePointer(name)}/methods/${escapePointer(methodName)}/policy`,
103
- input: method.input,
104
- receiver,
105
- instanceMethod: !method.static,
106
- });
107
- }
68
+ /**
69
+ * Validate the Policy of one callable contract written at `pointer`, wherever it is declared:
70
+ * `self` names the Node of the `receiver` Class, and nothing where the call has no receiver.
71
+ */
72
+ export function validateContractPolicy(context, typing, contract, pointer, receiver) {
73
+ if (typeof contract.policy !== 'object')
74
+ return;
75
+ validateChecks(context, typing, contract.policy, {
76
+ site: 'callable',
77
+ pointer: `${pointer}/policy`,
78
+ input: isBinaryInput(contract.input) ? contract.input.metadata : contract.input,
79
+ ...(receiver === undefined ? {} : { receiver }),
80
+ });
108
81
  }
109
- function validateChecks(validation, typing, expression, context) {
110
- const normalized = normalizePolicyChecks(expression);
111
- const measure = measureChecks(normalized);
112
- if (measure.depth > MAX_CHECK_DEPTH ||
113
- measure.branches > MAX_BRANCHES ||
114
- measure.leaves > MAX_CHECK_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}.`);
82
+ export function validateChecks(validation, typing, expression, context) {
83
+ // Checks decide the caller the way a named Policy does, so, as a Policy connects its subject,
84
+ // each way they hold must pass through a check of the caller.
85
+ if (!checksNameTheCaller(expression)) {
86
+ validation.add('PL_CONNECTIVITY', context.pointer, `${SITE[context.site].checks} must check a Policy on every branch: sameNode alone names no caller.`);
116
87
  }
88
+ // Their budget is checked with the named Policies', from the same measure (`budgets.ts`).
89
+ const normalized = normalizePolicyChecks(expression);
117
90
  const leaves = new Map();
118
91
  visitChecks(validation, typing, normalized, context, context.pointer, leaves);
119
92
  for (const [object, className] of neverAdmittedClasses(normalized, leaves)) {
@@ -124,7 +97,11 @@ function visitChecks(validation, typing, expression, context, pointer, leaves) {
124
97
  if ('sameNode' in expression) {
125
98
  for (const [side, object] of Object.entries(expression.sameNode)) {
126
99
  const objectPointer = `${pointer}/sameNode/${side}`;
127
- if (object.kind === 'self')
100
+ if (object.kind === 'self' && context.edge !== undefined) {
101
+ // `self` is an Edge there, and sameNode compares Nodes.
102
+ validation.add('PL_USE', objectPointer, 'sameNode compares Nodes: self is an Edge here.');
103
+ }
104
+ else if (object.kind === 'self')
128
105
  selfContracts(validation, context, objectPointer);
129
106
  else if (object.kind === 'input')
130
107
  inputContracts(validation, context, object.field, objectPointer);
@@ -136,6 +113,16 @@ function visitChecks(validation, typing, expression, context, pointer, leaves) {
136
113
  if ('check' in expression) {
137
114
  if (!validation.resolvePolicy(expression.check, `${pointer}/check`))
138
115
  return;
116
+ if (expression.object.kind === 'self' && context.edge !== undefined) {
117
+ // An Edge is checked as an Edge Class Policy is: over every concrete endpoint pair.
118
+ if (!typing.policyAcceptsEdgeClass(expression.check.name, context.edge.declaration)) {
119
+ validation.add('PL_USE', pointer, `${formatDefinitionRef(expression.check)} is not valid for every concrete source/target pair of Edge Class ${context.edge.ref.name}.`, formatDefinitionRef(expression.check));
120
+ return;
121
+ }
122
+ const edge = formatDefinitionRef(context.edge.ref);
123
+ leaves.set(expression, { accepted: [edge], admitted: new Set([edge]) });
124
+ return;
125
+ }
139
126
  const objectPointer = `${pointer}/object`;
140
127
  const contracts = expression.object.kind === 'self'
141
128
  ? selfContracts(validation, context, objectPointer)
@@ -144,30 +131,20 @@ function visitChecks(validation, typing, expression, context, pointer, leaves) {
144
131
  : referenceContracts(validation, expression.object.ref, objectPointer);
145
132
  if (contracts === undefined)
146
133
  return;
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) {
134
+ const classes = typing.checkLeafClasses(expression.check.name, contracts);
135
+ if (classes === undefined) {
153
136
  validation.add('PL_USE', pointer, `${formatDefinitionRef(expression.check)} is incompatible with ${SITE[context.site].objects}.`, formatDefinitionRef(expression.check));
154
137
  return;
155
138
  }
156
- leaves.set(expression, { accepted: [...typings.keys()], admitted });
139
+ leaves.set(expression, classes);
157
140
  return;
158
141
  }
159
142
  const { key, values } = checkOperands(expression);
160
- if (values.length === 0) {
161
- validation.add('PL_COMPOSITION', `${pointer}/${key}`, `${key} must be non-empty.`);
162
- }
163
143
  values.forEach((child, index) => visitChecks(validation, typing, child, context, `${pointer}/${key}/${index}`, leaves));
164
144
  }
165
- function contractName(contract) {
166
- return contract.kind === 'exact' ? formatDefinitionRef(contract.ref) : 'default';
167
- }
168
145
  function selfContracts(validation, context, pointer) {
169
- if (!context.instanceMethod || context.receiver === undefined) {
170
- validation.add('PL_USE', pointer, 'self is valid only for a Node instance Method.');
146
+ if (context.receiver === undefined) {
147
+ validation.add('PL_USE', pointer, 'self is valid only where a Node receives the call: a Node instance Method, or a Function instance, whose Node carries the contract.');
171
148
  return undefined;
172
149
  }
173
150
  return [contractOfNodeDefinition(context.receiver)];
@@ -1,8 +1,9 @@
1
+ import { PolicyTyping } from '../../../language/policy/analysis/typing.js';
1
2
  import { validatePolicyBudgets } from './budgets.js';
2
3
  import { PolicyValidationContext } from './context.js';
3
4
  import { validatePolicyReferences } from './references.js';
4
- import { PolicyTyping } from './typing.js';
5
- import { validateCallableUses, validateReadUses, validateTraverseUses } from './uses.js';
5
+ import { validatePolicyTyping } from './typing.js';
6
+ import { validateCallableUses, validateClassUses } from './uses.js';
6
7
  /**
7
8
  * Validates the closed V1 Policy language after structural parsing.
8
9
  *
@@ -15,9 +16,8 @@ export function validatePolicies(environment, analysis) {
15
16
  validatePolicyReferences(context);
16
17
  validatePolicyBudgets(context);
17
18
  const typing = new PolicyTyping(context);
18
- typing.validatePolicies();
19
- validateReadUses(context, typing);
20
- validateTraverseUses(context, typing);
19
+ validatePolicyTyping(context, typing);
20
+ validateClassUses(context, typing);
21
21
  validateCallableUses(context, typing);
22
22
  return Object.freeze(context.diagnostics);
23
23
  }
@@ -1,4 +1,5 @@
1
1
  /** The exact V1 value-schema grammar embedded in DomainSchema declarations. */
2
+ import type { ValueKind } from '@astrale-os/kernel-dsl/value';
2
3
  import type { Diagnostic } from '../../language/validation/diagnostic.js';
3
4
  import type { JsonSchema } from '../../language/value/model/schema.js';
4
5
  import type { OrderingKind } from '../../language/value/ordering.js';
@@ -9,7 +10,28 @@ export type { BlobOptions, BlobReceipt, BlobRef, BlobSchema, } from '../../langu
9
10
  export type { JsonSchema as Schema, JsonSchemaObject as SchemaObject, PathAnnotation, PropertyObjectSchema as PropertySchema, ValueSchemaContext as Context, } from '../../language/value/model/schema.js';
10
11
  export { instant } from '../../language/value/model/instant.js';
11
12
  export type { OrderingKind } from '../../language/value/ordering.js';
13
+ export { VALUE_KINDS } from '../../language/value/ordering.js';
14
+ export { GRAPH_NODE_PATH_SCHEMA_ID as NODE_PATH } from '../../language/value/syntax/node-path/schema.js';
15
+ export { DECLARED_VALUE_KINDS as DECLARED_KINDS, FORBIDDEN_KEYWORDS, SUBSCHEMA_KEYWORDS, VALUE_KEYWORDS as KEYWORDS, } from '../../language/value/profile/vocabulary.js';
16
+ export type { DeclaredValueKind as DeclaredKind, ValueKeyword as Keyword, } from '../../language/value/profile/vocabulary.js';
17
+ export { VALUE_RULES as RULES } from '../../language/validation/rule.js';
18
+ export type { ValueRule as Rule, ValueRuleStage as RuleStage, } from '../../language/validation/rule.js';
12
19
  /** Validate one complete JSON value under the exact accepted schema that owns the contract. */
13
20
  export declare function validate(owner: DomainSchema, contract: JsonSchema, input: unknown, pointer?: string): readonly Diagnostic[];
14
21
  /** Return the one portable scalar ordering domain admitted by a property schema, if any. */
15
22
  export declare function classifyOrdering(owner: DomainSchema, contract: JsonSchema): OrderingKind | undefined;
23
+ /**
24
+ * The value kind of a property schema: what a graph language may test on the property (Y4). It is
25
+ * the one kind of every non-null value the schema admits: `text` for strings, `number` for numbers
26
+ * and integers, `instant` for strings declared `x-astrale-value-kind: instant`, `enum` for a finite
27
+ * set of strings (`const` or `enum`), `boolean`, and `set` for arrays of `uniqueItems`. An
28
+ * ambiguous union, an object, an array with repetitions, a blob or a schema that admits no value is
29
+ * `json`. `$ref`, `allOf`, `anyOf` and `oneOf` are followed; `null` is a point of every kind.
30
+ */
31
+ export declare function classifyValueKind(owner: DomainSchema, contract: JsonSchema): ValueKind;
32
+ /**
33
+ * A warning for each class property whose value kind is `json` (an ambiguous union, an object, an
34
+ * array with repetitions): a Query filters it by equality only. Nothing refuses such a property;
35
+ * the CLI shows the warning to its author.
36
+ */
37
+ export declare function valueKindWarnings(owner: DomainSchema): readonly Diagnostic<'VS_VALUE_KIND_JSON'>[];
@@ -1,11 +1,17 @@
1
1
  /** The exact V1 value-schema grammar embedded in DomainSchema declarations. */
2
+ import { diagnostic } from '../../language/validation/diagnostic.js';
2
3
  import { validateJsonInstance } from '../../language/value/evaluate/validate.js';
3
- import { classifyOrdering as classifyOrderingWithRegistry } from '../../language/value/ordering.js';
4
+ import { classifyOrdering as classifyOrderingWithRegistry, classifyValueKind as classifyValueKindWithRegistry, } from '../../language/value/ordering.js';
5
+ import { escapePointerToken } from '../../language/value/syntax/pointer.js';
4
6
  import { createDomainValueSchemaRegistry } from '../resolution/value.registry.js';
5
7
  const registries = new WeakMap();
6
8
  export { VALUE_SCHEMA_DIALECT as DIALECT, VALUE_SCHEMA_VOCABULARY as VOCABULARY, } from '../../language/value/model/schema.js';
7
9
  export { blob, isBlobValueSchema as isBlob } from '../../language/value/model/blob.js';
8
10
  export { instant } from '../../language/value/model/instant.js';
11
+ export { VALUE_KINDS } from '../../language/value/ordering.js';
12
+ export { GRAPH_NODE_PATH_SCHEMA_ID as NODE_PATH } from '../../language/value/syntax/node-path/schema.js';
13
+ export { DECLARED_VALUE_KINDS as DECLARED_KINDS, FORBIDDEN_KEYWORDS, SUBSCHEMA_KEYWORDS, VALUE_KEYWORDS as KEYWORDS, } from '../../language/value/profile/vocabulary.js';
14
+ export { VALUE_RULES as RULES } from '../../language/validation/rule.js';
9
15
  /** Validate one complete JSON value under the exact accepted schema that owns the contract. */
10
16
  export function validate(owner, contract, input, pointer = '') {
11
17
  return validateJsonInstance(contract, input, registryFor(owner), pointer);
@@ -14,6 +20,33 @@ export function validate(owner, contract, input, pointer = '') {
14
20
  export function classifyOrdering(owner, contract) {
15
21
  return classifyOrderingWithRegistry(contract, registryFor(owner));
16
22
  }
23
+ /**
24
+ * The value kind of a property schema: what a graph language may test on the property (Y4). It is
25
+ * the one kind of every non-null value the schema admits: `text` for strings, `number` for numbers
26
+ * and integers, `instant` for strings declared `x-astrale-value-kind: instant`, `enum` for a finite
27
+ * set of strings (`const` or `enum`), `boolean`, and `set` for arrays of `uniqueItems`. An
28
+ * ambiguous union, an object, an array with repetitions, a blob or a schema that admits no value is
29
+ * `json`. `$ref`, `allOf`, `anyOf` and `oneOf` are followed; `null` is a point of every kind.
30
+ */
31
+ export function classifyValueKind(owner, contract) {
32
+ return classifyValueKindWithRegistry(contract, registryFor(owner));
33
+ }
34
+ /**
35
+ * A warning for each class property whose value kind is `json` (an ambiguous union, an object, an
36
+ * array with repetitions): a Query filters it by equality only. Nothing refuses such a property;
37
+ * the CLI shows the warning to its author.
38
+ */
39
+ export function valueKindWarnings(owner) {
40
+ const warnings = [];
41
+ for (const [className, definition] of Object.entries(owner.classes)) {
42
+ for (const [name, property] of Object.entries(definition.properties)) {
43
+ if (classifyValueKind(owner, property.schema) !== 'json')
44
+ continue;
45
+ warnings.push(diagnostic('VS_VALUE_KIND_JSON', `/classes/${escapePointerToken(className)}/properties/${escapePointerToken(name)}`, `The value kind of ${className}.${name} is json: a Query filters it by equality only.`));
46
+ }
47
+ }
48
+ return warnings;
49
+ }
17
50
  function registryFor(owner) {
18
51
  let registry = registries.get(owner);
19
52
  if (registry === undefined) {
@@ -1,4 +1,7 @@
1
+ import type { CallableDefinition } from '../../language/callable/model/callable.js';
1
2
  import type { ValueSchemaRegistry } from '../../language/value/reference/registry.js';
2
3
  import type { SchemaDiagnostic } from '../diagnostic.js';
3
4
  import type { DomainSchemaIR } from '../model/schema.js';
4
5
  export declare function validateEmbeddedValueSchemas(schema: DomainSchemaIR, registry: ValueSchemaRegistry): readonly SchemaDiagnostic[];
6
+ /** Validate the value schemas of one callable contract at `pointer`. */
7
+ export declare function validateCallable(declaration: CallableDefinition, pointer: string, registry: ValueSchemaRegistry, diagnostics: SchemaDiagnostic[]): void;
@@ -1,27 +1,22 @@
1
1
  import { isBinaryInput } from '../../language/callable/model/callable.js';
2
2
  import { validateValueSchema } from '../../language/value/profile/validate.js';
3
- import { diagnostic } from '../diagnostic.js';
3
+ import { escapePointerToken } from '../../language/value/syntax/pointer.js';
4
+ import { valueDiagnostic } from '../diagnostic.js';
4
5
  export function validateEmbeddedValueSchemas(schema, registry) {
5
6
  const diagnostics = [];
6
7
  for (const [name, declaration] of Object.entries(schema.classes)) {
7
- validateDefinition(declaration, `/classes/${escapePointer(name)}`, registry, diagnostics);
8
- }
9
- for (const [name, declaration] of Object.entries(schema.functions)) {
10
- validateCallable(declaration, `/functions/${escapePointer(name)}`, registry, diagnostics);
8
+ validateDefinition(declaration, `/classes/${escapePointerToken(name)}`, registry, diagnostics);
11
9
  }
10
+ // Callable contracts are validated at their site, as one contract (`validateContracts`).
12
11
  return Object.freeze(diagnostics);
13
12
  }
14
13
  function validateDefinition(declaration, pointer, registry, diagnostics) {
15
14
  for (const [name, property] of Object.entries(declaration.properties)) {
16
- validate(property.schema, 'property-facet', `${pointer}/properties/${escapePointer(name)}/schema`, registry, diagnostics);
17
- }
18
- if ('methods' in declaration) {
19
- for (const [name, method] of Object.entries(declaration.methods)) {
20
- validateCallable(method, `${pointer}/methods/${escapePointer(name)}`, registry, diagnostics);
21
- }
15
+ validate(property.schema, 'property-facet', `${pointer}/properties/${escapePointerToken(name)}/schema`, registry, diagnostics);
22
16
  }
23
17
  }
24
- function validateCallable(declaration, pointer, registry, diagnostics) {
18
+ /** Validate the value schemas of one callable contract at `pointer`. */
19
+ export function validateCallable(declaration, pointer, registry, diagnostics) {
25
20
  if (isBinaryInput(declaration.input)) {
26
21
  validate(declaration.input.metadata, 'callable-input', `${pointer}/input/metadata`, registry, diagnostics);
27
22
  }
@@ -36,10 +31,7 @@ function validateCallable(declaration, pointer, registry, diagnostics) {
36
31
  }
37
32
  }
38
33
  function validate(schema, context, pointer, registry, diagnostics) {
39
- for (const failure of validateValueSchema(schema, context, registry, pointer)) {
40
- diagnostics.push(diagnostic('DV_VALUE_SCHEMA', failure.pointer, `[${failure.code}] ${failure.message}`, failure.ref));
34
+ for (const refusal of validateValueSchema(schema, context, registry, pointer)) {
35
+ diagnostics.push(valueDiagnostic('DV_VALUE_SCHEMA', refusal));
41
36
  }
42
37
  }
43
- function escapePointer(value) {
44
- return value.replaceAll('~', '~0').replaceAll('/', '~1');
45
- }
@@ -0,0 +1,49 @@
1
+ import { type JsonSchema } from './json.json-schema.js';
2
+ /**
3
+ * The checks on value schemas JSON Schema cannot state, which the published document names with
4
+ * the positions it constrains. The Kernel reports each as `DV_VALUE_SCHEMA`, with its value code.
5
+ */
6
+ export declare const valueSchemaRules: {
7
+ readonly 'value-blob': {
8
+ readonly code: 'DV_VALUE_SCHEMA';
9
+ readonly valueCode: 'VS_VALUE_KIND';
10
+ readonly statement: 'A blob is declared only by the whole schema of a Property, exactly as values.blob writes it.';
11
+ };
12
+ readonly 'value-path': {
13
+ readonly code: 'DV_VALUE_SCHEMA';
14
+ readonly valueCode: 'VS_PATH_EXTENSION';
15
+ readonly statement: 'x-astrale-path annotates only a direct Property of a callable input object, beside exactly the $ref of the graph NodePath schema.';
16
+ };
17
+ readonly 'value-recursion': {
18
+ readonly code: 'DV_VALUE_SCHEMA';
19
+ readonly valueCode: 'VS_RECURSION_PRODUCTIVE';
20
+ readonly statement: string;
21
+ };
22
+ readonly 'value-reference-form': {
23
+ readonly code: 'DV_VALUE_SCHEMA';
24
+ readonly valueCode: 'VS_REFERENCE_FORM';
25
+ readonly statement: string;
26
+ };
27
+ readonly 'value-reference-resolution': {
28
+ readonly code: 'DV_VALUE_SCHEMA';
29
+ readonly valueCode: 'VS_REFERENCE_RESOLUTION';
30
+ readonly statement: 'A $ref resolves to a location of its own value schema, and x-astrale-path accepts Node Classes of the Domain or of a direct dependency.';
31
+ };
32
+ readonly 'value-regexp': {
33
+ readonly code: 'DV_VALUE_SCHEMA';
34
+ readonly valueCode: 'VS_REGEX_PORTABLE';
35
+ readonly statement: string;
36
+ };
37
+ };
38
+ export type ValueSchemaRule = keyof typeof valueSchemaRules;
39
+ /**
40
+ * The value language in JSON Schema, for the document that embeds value schemas: `root` constrains
41
+ * the `value-schema` definition with the published dialect and what the profile adds to it,
42
+ * `definitions` holds the locations it reaches and the members of the Path annotation, and
43
+ * `nodeProperty` constrains a Node Property definition. A named check leaves `x-astrale-rule` at the positions it constrains.
44
+ */
45
+ export declare function valueSchemaJsonSchema(): {
46
+ readonly root: readonly JsonSchema[];
47
+ readonly definitions: Readonly<Record<string, JsonSchema>>;
48
+ readonly nodeProperty: JsonSchema;
49
+ };
@@ -0,0 +1,137 @@
1
+ import { VALUE_RULES } from '../../language/validation/rule.js';
2
+ import { VALUE_SCHEMA_DIALECT } from '../../language/value/model/schema.js';
3
+ import { FORBIDDEN_KEYWORDS, SUBSCHEMA_KEYWORDS, VALUE_KEYWORDS, } from '../../language/value/profile/vocabulary.js';
4
+ import { named } from './json.json-schema.js';
5
+ /**
6
+ * The checks on value schemas JSON Schema cannot state, which the published document names with
7
+ * the positions it constrains. The Kernel reports each as `DV_VALUE_SCHEMA`, with its value code.
8
+ */
9
+ export const valueSchemaRules = {
10
+ 'value-blob': {
11
+ code: 'DV_VALUE_SCHEMA',
12
+ valueCode: 'VS_VALUE_KIND',
13
+ statement: 'A blob is declared only by the whole schema of a Property, exactly as values.blob writes it.',
14
+ },
15
+ // Its members are stated (`path-annotation`); where it stands is named.
16
+ 'value-path': {
17
+ code: 'DV_VALUE_SCHEMA',
18
+ valueCode: 'VS_PATH_EXTENSION',
19
+ statement: 'x-astrale-path annotates only a direct Property of a callable input object, beside exactly the $ref of the graph NodePath schema.',
20
+ },
21
+ 'value-recursion': {
22
+ code: 'DV_VALUE_SCHEMA',
23
+ valueCode: 'VS_RECURSION_PRODUCTIVE',
24
+ statement: VALUE_RULES.VS_RECURSION_PRODUCTIVE.statement,
25
+ },
26
+ 'value-reference-form': {
27
+ code: 'DV_VALUE_SCHEMA',
28
+ valueCode: 'VS_REFERENCE_FORM',
29
+ statement: VALUE_RULES.VS_REFERENCE_FORM.statement,
30
+ },
31
+ 'value-reference-resolution': {
32
+ code: 'DV_VALUE_SCHEMA',
33
+ valueCode: 'VS_REFERENCE_RESOLUTION',
34
+ statement: 'A $ref resolves to a location of its own value schema, and x-astrale-path accepts Node Classes of the Domain or of a direct dependency.',
35
+ },
36
+ 'value-regexp': {
37
+ code: 'DV_VALUE_SCHEMA',
38
+ valueCode: 'VS_REGEX_PORTABLE',
39
+ statement: VALUE_RULES.VS_REGEX_PORTABLE.statement,
40
+ },
41
+ };
42
+ const KIND = 'x-astrale-value-kind';
43
+ const LOCATION = '#/$defs/value-location';
44
+ const SUBSCHEMA = '#/$defs/value-subschema';
45
+ const PATH = '#/$defs/path-annotation';
46
+ /**
47
+ * The value language in JSON Schema, for the document that embeds value schemas: `root` constrains
48
+ * the `value-schema` definition with the published dialect and what the profile adds to it,
49
+ * `definitions` holds the locations it reaches and the members of the Path annotation, and
50
+ * `nodeProperty` constrains a Node Property definition. A named check leaves `x-astrale-rule` at the positions it constrains.
51
+ */
52
+ export function valueSchemaJsonSchema() {
53
+ return {
54
+ root: [
55
+ { $ref: VALUE_SCHEMA_DIALECT },
56
+ { $ref: LOCATION },
57
+ objectOrBoolean({
58
+ properties: {
59
+ $schema: { const: VALUE_SCHEMA_DIALECT },
60
+ [KIND]: named({ enum: ['instant', 'blob'] }, 'value-blob'),
61
+ },
62
+ }),
63
+ ],
64
+ definitions: {
65
+ // Every location, the root included: the closed vocabulary and the subschemas it holds.
66
+ 'value-location': objectOrBoolean({
67
+ propertyNames: {
68
+ enum: VALUE_KEYWORDS.filter((keyword) => !FORBIDDEN_KEYWORDS.includes(keyword)),
69
+ },
70
+ properties: {
71
+ $id: false,
72
+ $ref: named({ type: 'string' }, 'value-recursion', 'value-reference-form', 'value-reference-resolution'),
73
+ enum: { type: 'array', uniqueItems: true },
74
+ fullMatch: named({ type: 'string' }, 'value-regexp'),
75
+ pattern: named({ type: 'string' }, 'value-regexp'),
76
+ 'x-astrale-path': named({ $ref: PATH }, 'value-path'),
77
+ ...Object.fromEntries(SUBSCHEMA_KEYWORDS.single.map((keyword) => [keyword, { $ref: SUBSCHEMA }])),
78
+ ...Object.fromEntries(SUBSCHEMA_KEYWORDS.array.map((keyword) => [
79
+ keyword,
80
+ { type: 'array', items: { $ref: SUBSCHEMA } },
81
+ ])),
82
+ ...Object.fromEntries(SUBSCHEMA_KEYWORDS.map.map((keyword) => {
83
+ const members = {
84
+ type: 'object',
85
+ additionalProperties: { $ref: SUBSCHEMA },
86
+ };
87
+ if (keyword !== 'patternProperties')
88
+ return [keyword, members];
89
+ return [keyword, named(members, 'value-regexp')];
90
+ })),
91
+ },
92
+ // An instant is a string.
93
+ if: { required: [KIND], properties: { [KIND]: { const: 'instant' } } },
94
+ // oxlint-disable-next-line unicorn/no-thenable -- the JSON Schema keyword
95
+ then: { required: ['type'], properties: { type: { const: 'string' } } },
96
+ }),
97
+ // The Path annotation: the one Node a Path field resolves, of a Node Class it accepts.
98
+ 'path-annotation': {
99
+ type: 'object',
100
+ properties: {
101
+ target: { type: 'string', const: 'node' },
102
+ cardinality: { type: 'string', const: 'one' },
103
+ accepts: {
104
+ type: 'array',
105
+ minItems: 1,
106
+ uniqueItems: true,
107
+ items: named({ $ref: '#/$defs/class-ref' }, 'value-reference-resolution'),
108
+ },
109
+ },
110
+ required: ['target', 'cardinality', 'accepts'],
111
+ additionalProperties: false,
112
+ },
113
+ // A location below the root: no $schema, and no blob.
114
+ 'value-subschema': {
115
+ allOf: [
116
+ { $ref: LOCATION },
117
+ objectOrBoolean({ properties: { $schema: false, [KIND]: { const: 'instant' } } }),
118
+ ],
119
+ },
120
+ },
121
+ // An automatic or State Property holds no blob.
122
+ nodeProperty: {
123
+ if: { anyOf: [{ required: ['auto'] }, { required: ['state'] }] },
124
+ // oxlint-disable-next-line unicorn/no-thenable -- the JSON Schema keyword
125
+ then: {
126
+ properties: {
127
+ schema: {
128
+ not: { type: 'object', required: [KIND], properties: { [KIND]: { const: 'blob' } } },
129
+ },
130
+ },
131
+ },
132
+ },
133
+ };
134
+ }
135
+ function objectOrBoolean(object) {
136
+ return { anyOf: [{ type: 'boolean' }, { type: 'object', ...object }] };
137
+ }
@@ -1,12 +1,14 @@
1
+ import { equalDefinitionRefs } from '../../addressing/definition-ref.js';
1
2
  import { Key } from '../../addressing/key.js';
3
+ import { escapePointerToken } from '../../language/value/syntax/pointer.js';
2
4
  import { diagnostic } from '../diagnostic.js';
3
5
  const formatDefinitionRef = Key.of;
4
6
  export function validateViews(environment) {
5
7
  const diagnostics = [];
6
8
  for (const [name, view] of Object.entries(environment.candidate.views)) {
7
- const pointer = `/views/${escapePointer(name)}`;
9
+ const pointer = `/views/${escapePointerToken(name)}`;
8
10
  const ref = { origin: environment.candidate.origin, kind: 'view', name };
9
- if (!sameRef(view.ref, ref)) {
11
+ if (!equalDefinitionRefs(view.ref, ref)) {
10
12
  diagnostics.push(diagnostic('DV_REF_RESOLVES', `${pointer}/ref`, `View ref must be exactly ${formatDefinitionRef(ref)}.`, formatDefinitionRef(view.ref)));
11
13
  }
12
14
  }
@@ -26,9 +28,3 @@ function validateEntrypoint(environment, diagnostics) {
26
28
  diagnostics.push(diagnostic('DV_ENTRYPOINT', '/entrypoint', `Entrypoint ${formatDefinitionRef(entrypoint)} is not a Domain-targeted View of ${origin}.`, formatDefinitionRef(entrypoint)));
27
29
  }
28
30
  }
29
- function sameRef(left, right) {
30
- return left.origin === right.origin && left.kind === right.kind && left.name === right.name;
31
- }
32
- function escapePointer(value) {
33
- return value.replaceAll('~', '~0').replaceAll('/', '~1');
34
- }
@@ -5,3 +5,9 @@ export declare function serialize(input: unknown, options?: Options): string;
5
5
  /** Serialize a trusted portable value whose default structural admission proof is still valid. */
6
6
  export declare function serializeAdmitted(input: Value): string;
7
7
  export declare function encode(input: unknown, options?: Options): Uint8Array;
8
+ /**
9
+ * The UTF-8 byte length of a trusted Value's canonical JSON, `encode(input).byteLength`, without
10
+ * serializing it: an admission-owned immutable root counted its bytes when it was admitted, and any
11
+ * other container is counted member by member.
12
+ */
13
+ export declare function byteLength(input: Value): number;