@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
@@ -0,0 +1,440 @@
1
+ import { defaultLimits } from '@astrale-os/kernel-dsl/value';
2
+ import { deepFreeze } from '../language/freeze.js';
3
+ import { limits } from '../language/limits.js';
4
+ const ANY = ['{/path*}'];
5
+ const CHECKS = [
6
+ '/classes/{class}/policies/{operation}{/path*}',
7
+ '/functions/{function}/policy{/path*}',
8
+ '/classes/{class}/methods/{method}/policy{/path*}',
9
+ ];
10
+ const DEPENDENCIES = ['/dependencies/{alias}', '/dependencies'];
11
+ const count = (value) => value.toLocaleString('en-US');
12
+ const { dependency, policy } = limits;
13
+ const at = (field) => [
14
+ `/functions/{function}${field}`,
15
+ `/classes/{class}/methods/{method}${field}`,
16
+ ];
17
+ /**
18
+ * Every Schema diagnostic code with the rule it reports. A code added to the DSL does not compile
19
+ * until it is described here.
20
+ */
21
+ export const RULES = deepFreeze({
22
+ DV_ACCEPTANCE_CONTEXT: {
23
+ stage: 'context',
24
+ positions: ['/dependencies'],
25
+ statement: 'A Schema is resolved, compiled or bundled only with the exact dependency closure its acceptance retained in this process.',
26
+ },
27
+ DV_CALLABLE_ADMISSION: {
28
+ stage: 'rule',
29
+ positions: at('/admission/maxAge'),
30
+ statement: 'An admission age is an integer number of seconds from 1 to 300.',
31
+ enforces: 'A destination decides a call only under an admission at most that many seconds old.',
32
+ },
33
+ DV_CALLABLE_AUTH: {
34
+ stage: 'rule',
35
+ positions: at('/auth'),
36
+ statement: 'A durable Function or Method is authenticated or authorized, never anonymous.',
37
+ enforces: 'A durable call runs as an Execution that records its caller and its admitted input, is resubmitted from them, and settles one value outcome.',
38
+ },
39
+ DV_CALLABLE_IO: {
40
+ stage: 'rule',
41
+ // A Method takes a value input only: its input has no mode.
42
+ positions: ['/functions/{function}/input/mode', ...at('/output/mode')],
43
+ statement: 'A durable Function or Method takes a value input and returns a value output.',
44
+ },
45
+ DV_CLASS_ABSTRACT: {
46
+ stage: 'rule',
47
+ positions: ['/classes/{class}/policies'],
48
+ statement: 'An abstract Class declares no read or traverse Policy.',
49
+ enforces: 'No Node or Edge is of an abstract Class exactly: only its concrete descendants are.',
50
+ },
51
+ DV_CLASS_ACYCLIC: {
52
+ stage: 'rule',
53
+ positions: ['/classes/{class}/extends/{index}'],
54
+ statement: 'No Class extends itself, directly or through its ancestors.',
55
+ },
56
+ DV_CLASS_INHERITANCE: {
57
+ stage: 'context',
58
+ positions: ['/classes/{class}/extends/{index}'],
59
+ statement: 'No Class extends a final Class, of its own Domain or of a dependency.',
60
+ },
61
+ DV_CLASS_KIND: {
62
+ stage: 'context',
63
+ positions: ['/classes/{class}/extends/{index}'],
64
+ statement: 'A Class extends only Classes of its own kind: a Node Class Node Classes, an Edge Class Edge Classes.',
65
+ },
66
+ DV_CORE_EDGE_CLASS: {
67
+ stage: 'context',
68
+ positions: ['/core/edges/{index}/class', '/core/edges/{index}'],
69
+ statement: 'A Core Edge is of a concrete Edge Class of its Domain whose endpoints accept the Classes of its source and target.',
70
+ },
71
+ DV_CORE_EDGE_CONSTRAINTS: {
72
+ stage: 'context',
73
+ positions: ['/core/edges', '/core/edges/{index}', '/core/nodes/{slug}'],
74
+ statement: 'The Core Edges of a Schema hold the noSelf and acyclic constraints of their Classes, and every Core Node, and every Definition a Core Edge names, the Edge counts of the concrete Edge Classes whose endpoints accept it, each over its own Edges, a Definition its maximum only.',
75
+ },
76
+ DV_CORE_EDGE_KEY: {
77
+ stage: 'rule',
78
+ positions: ['/core/edges/{index}'],
79
+ statement: 'No two Core Edges share their Edge Class, source and target.',
80
+ },
81
+ DV_CORE_EDGE_PROPERTIES: {
82
+ stage: 'context',
83
+ positions: ['/core/edges/{index}/properties{/path*}'],
84
+ statement: 'The Properties of a Core Edge satisfy its Class: every required Property that no automatic program writes is present, every automatic one is absent, and each value fits its schema.',
85
+ },
86
+ DV_CORE_EDGE_UNIQUE: {
87
+ stage: 'context',
88
+ positions: ['/core/edges/{index}'],
89
+ statement: 'No two Core Edges hold one key under a unique tuple that covers their Classes.',
90
+ },
91
+ DV_CORE_NODE_CLASS: {
92
+ stage: 'rule',
93
+ positions: ['/core/nodes/{slug}/class'],
94
+ statement: 'A Core Node is of a concrete Node Class of its Domain.',
95
+ },
96
+ DV_CORE_NODE_PROPERTIES: {
97
+ stage: 'context',
98
+ positions: ['/core/nodes/{slug}/properties{/path*}'],
99
+ statement: 'The Properties of a Core Node satisfy its Class: every required Property that no automatic program writes is present, every automatic one is absent, and each value fits its schema.',
100
+ },
101
+ DV_CORE_NODE_UNIQUE: {
102
+ stage: 'context',
103
+ positions: ['/core/nodes/{slug}'],
104
+ statement: 'No two Core Nodes hold one key under a unique tuple that covers their Classes.',
105
+ },
106
+ DV_CORE_REF: {
107
+ stage: 'rule',
108
+ positions: ['/core/edges/{index}/source', '/core/edges/{index}/target'],
109
+ statement: 'A Core Edge endpoint names its Domain or a Definition its Domain declares and projects: a Class, Function, executable Method, Policy, View or Core Node.',
110
+ },
111
+ DV_DATA_COMPOSITION: {
112
+ stage: 'context',
113
+ positions: ['/classes/{class}/extends/{index}', '/classes/{class}/data'],
114
+ statement: 'A Node Class has at most one data declaration, its own or inherited from one declaring Class, and declares none of its own when it inherits one.',
115
+ },
116
+ DV_DEPENDENCY_ACYCLIC: {
117
+ stage: 'context',
118
+ positions: [...DEPENDENCIES],
119
+ statement: 'The dependency closure of a Domain has no cycle and never reaches its own origin.',
120
+ },
121
+ DV_DEPENDENCY_DIRECT: {
122
+ stage: 'rule',
123
+ positions: ['/dependencies'],
124
+ statement: 'Every origin a reference names, other than the Domain’s own, is a direct dependency.',
125
+ },
126
+ DV_DEPENDENCY_EXACT: {
127
+ stage: 'context',
128
+ positions: [...DEPENDENCIES],
129
+ statement: 'The lookup serves every dependency of the closure exactly: the Schema of its origin whose revision is the one pinned.',
130
+ },
131
+ DV_DEPENDENCY_LIMITS: {
132
+ stage: 'context',
133
+ positions: ['/dependencies', '/dependencies/{alias}'],
134
+ statement: `A Domain has at most ${dependency.direct} direct dependencies, a closure of at most ${dependency.closure} Domains and a dependency depth of at most ${dependency.depth}.`,
135
+ limits: ['dependency.direct', 'dependency.closure', 'dependency.depth'],
136
+ },
137
+ DV_DEPENDENCY_REVISION_COHERENCE: {
138
+ stage: 'context',
139
+ positions: [...DEPENDENCIES],
140
+ statement: 'The dependency closure holds at most one revision of each origin.',
141
+ },
142
+ DV_DEPENDENCY_UNIQUE: {
143
+ stage: 'rule',
144
+ positions: ['/dependencies/{alias}/origin'],
145
+ statement: 'A Domain depends on each origin through one alias, and never on its own origin.',
146
+ },
147
+ DV_EDGE_ACCEPTS: {
148
+ stage: 'context',
149
+ positions: ['/classes/{class}/endpoints/{endpoint}/accepts/{index}'],
150
+ statement: 'An Edge endpoint accepts only Node Classes of its Domain or of a direct dependency.',
151
+ },
152
+ DV_EDGE_CLASS_COMPOSITION: {
153
+ stage: 'context',
154
+ positions: ['/classes/{class}/extends/{index}'],
155
+ statement: 'An Edge Class refines each Edge Class it extends: the same orientation, endpoints whose accepted Classes and counts fit within its parent’s, its parent’s constraints and Property contract.',
156
+ },
157
+ DV_EDGE_FOREIGN_MINIMUM: {
158
+ stage: 'rule',
159
+ positions: ['/classes/{class}/endpoints/{endpoint}/{count}'],
160
+ statement: 'An Edge endpoint that accepts a Class another Domain owns requires no minimum count: neither 1 nor 1..*.',
161
+ enforces: 'Every Node an endpoint accepts holds a number of Edges of the Class within its count: at least one for 1 and 1..*, at most one for 0..1 and 1.',
162
+ },
163
+ DV_EDGE_LIFETIME: {
164
+ stage: 'rule',
165
+ positions: ['/classes/{class}/endpoints/{endpoint}/onDelete'],
166
+ statement: 'An endpoint that can hold a Node of another Domain does not declare restrict, and no endpoint declares detach in an Edge Class with an endpoint that requires an Edge.',
167
+ enforces: 'Deleting a Node at a restrict endpoint is refused unless the same transition deletes the Edge; at a detach endpoint the Edge is deleted with the Node.',
168
+ },
169
+ DV_EDGE_ROLE: {
170
+ stage: 'rule',
171
+ positions: ['/classes/{class}/endpoints/{endpoint}/role'],
172
+ statement: 'The two endpoints of an Edge Class have distinct roles.',
173
+ },
174
+ DV_EDGE_UNIQUE: {
175
+ stage: 'context',
176
+ positions: ['/classes/{class}/unique/{index}/{index}/property'],
177
+ statement: 'Each Property a unique tuple of an Edge Class names is a Property of the Class, own or inherited, that is keyable: a string, number, boolean or instant that no automatic program writes.',
178
+ enforces: 'No two Edges of the Class and of its concrete descendants share the values of a tuple’s fields while each of those fields is present.',
179
+ },
180
+ DV_ENTRYPOINT: {
181
+ stage: 'rule',
182
+ positions: ['/entrypoint'],
183
+ statement: 'The entrypoint names a View its Domain declares.',
184
+ },
185
+ DV_JSON_VALUE: {
186
+ stage: 'structure',
187
+ positions: ANY,
188
+ statement: `The document is portable JSON: as text, UTF-8 that parses, within ${count(defaultLimits.maxBytes)} bytes, with no byte-order mark and no repeated member name; as a value, null, booleans, finite numbers other than negative zero, strings, arrays and plain objects, with no string or member name that holds U+0000 or a lone surrogate or exceeds ${count(defaultLimits.maxStringBytes)} bytes of UTF-8, at most ${count(defaultLimits.maxDepth)} nested arrays and objects, and at most ${count(defaultLimits.maxMembers)} members and items in all.`,
189
+ conditions: ['#/$defs/portable-string/not'],
190
+ },
191
+ DV_METHOD_ABSTRACT: {
192
+ stage: 'rule',
193
+ positions: [
194
+ '/classes/{class}/methods/{method}/policy',
195
+ '/classes/{class}/methods/{method}/admission',
196
+ ],
197
+ statement: 'An abstract Method of an abstract Class has no executable declaration, so it declares neither a Policy nor an admission age.',
198
+ },
199
+ DV_METHOD_COMPOSITION: {
200
+ stage: 'context',
201
+ positions: ['/classes/{class}/methods', '/classes/{class}/methods/{method}'],
202
+ statement: 'A Class keeps the exact signature of every abstract Method it inherits, declares locally a Method it inherits ambiguously, and, when concrete, declares locally every abstract Method it inherits.',
203
+ },
204
+ DV_NODE_UNIQUE: {
205
+ stage: 'context',
206
+ positions: ['/classes/{class}/unique/{index}/{index}'],
207
+ statement: 'Each Property a unique tuple of a Node Class names is a Property of the Class, own or inherited, that is keyable: a string, number, boolean or instant that no automatic program writes.',
208
+ enforces: 'No two Nodes of the Class and of its concrete descendants share the values of a tuple while every Property of the tuple has a value; a Node missing one holds no key.',
209
+ },
210
+ DV_PROPERTY_AUTO: {
211
+ stage: 'context',
212
+ positions: [
213
+ '/classes/{class}/properties/{property}/auto/on',
214
+ '/classes/{class}/properties/{property}/auto/set',
215
+ ],
216
+ statement: 'A required automatic Property is written on create, and the instant setter writes only a Property whose schema is an instant.',
217
+ enforces: 'The Kernel sets the Property to the instant of each transition of its events, and refuses a transition that writes it.',
218
+ },
219
+ DV_PROPERTY_IMMUTABLE: {
220
+ stage: 'rule',
221
+ positions: ['/classes/{class}/properties/{property}/immutable'],
222
+ statement: 'An immutable Property is neither automatic nor a State Property, and a required one is immutable from create, not once.',
223
+ enforces: 'A create Property is written only when its Node or Edge is created; a once Property is written only while it is absent, and never unset.',
224
+ },
225
+ DV_PROPERTY_STATE: {
226
+ stage: 'rule',
227
+ positions: ['/classes/{class}/properties/{property}/state'],
228
+ statement: 'A State Property is required and not automatic, has the string enumeration of exactly its states as schema, and a topology whose initial state and transition targets are its states.',
229
+ enforces: 'Its value is always one of its states; the Kernel does not hold changes to its transitions.',
230
+ },
231
+ DV_REF_RESOLVES: {
232
+ stage: 'context',
233
+ positions: [
234
+ '/classes/{class}/ref',
235
+ '/classes/{class}/extends/{index}',
236
+ '/functions/{function}/ref',
237
+ '/policies/{policy}/ref',
238
+ '/views/{view}/ref',
239
+ '/core/nodes/{slug}/ref',
240
+ ],
241
+ statement: 'A declaration’s ref is its own key, and every Class a Class extends exists in its Domain or in a direct dependency.',
242
+ },
243
+ DV_VALUE_SCHEMA: {
244
+ stage: 'context',
245
+ positions: [
246
+ '/classes/{class}/properties/{property}/schema{/path*}',
247
+ ...at('/input{/path*}'),
248
+ ...at('/output/schema{/path*}'),
249
+ ...at('/output/item{/path*}'),
250
+ ],
251
+ statement: 'Every embedded value schema is in the value language: its diagnostic names the refusal in `valueCode`, and the schema of an automatic or State Property is not a blob.',
252
+ conditions: ['#/$defs/node-property-definition/allOf/0/if'],
253
+ },
254
+ PL_BUDGET: {
255
+ stage: 'rule',
256
+ positions: ['/policies/{policy}', ...CHECKS],
257
+ statement: `A Policy stays within its budgets once expanded: pattern depth ${policy.patternDepth}, ${policy.normalizedBranches} normalized branches, ${policy.edgePredicates} Edge predicates a branch and ${policy.referencedDomains} referenced Domains; and checks within depth ${policy.checkDepth}, ${policy.checkBranches} branches and ${policy.checkLeaves} leaves.`,
258
+ limits: [
259
+ 'policy.patternDepth',
260
+ 'policy.normalizedBranches',
261
+ 'policy.edgePredicates',
262
+ 'policy.referencedDomains',
263
+ 'policy.checkDepth',
264
+ 'policy.checkBranches',
265
+ 'policy.checkLeaves',
266
+ ],
267
+ },
268
+ PL_COMPOSITION: {
269
+ stage: 'rule',
270
+ positions: ['/policies/{policy}'],
271
+ statement: 'Named Policies compose without a cycle.',
272
+ },
273
+ PL_CONNECTIVITY: {
274
+ stage: 'rule',
275
+ positions: ['/policies/{policy}/expression/match', ...CHECKS],
276
+ statement: 'Every normalized branch of a Policy pattern connects its subject with each object, endpoint and variable it names, and every branch of a check tree checks a Policy.',
277
+ },
278
+ PL_REF: {
279
+ stage: 'context',
280
+ positions: ['/policies/{policy}/expression{/path*}', ...CHECKS],
281
+ statement: 'Every reference in a Policy resolves: a named Policy to one its Domain declares, a Class to a Node or Edge Class of its Domain or of a direct dependency, an object to a projected Definition.',
282
+ },
283
+ PL_REPEAT: {
284
+ stage: 'rule',
285
+ positions: ['/policies/{policy}/expression{/path*}'],
286
+ statement: 'The minimum of a repeated Edge pattern is at most its maximum.',
287
+ },
288
+ PL_TARGET: {
289
+ stage: 'rule',
290
+ positions: ['/policies/{policy}', '/policies/{policy}/expression/match'],
291
+ statement: 'Every normalized branch of a Policy targets either its object or its source and target endpoints, without mixing the two.',
292
+ },
293
+ PL_TYPING: {
294
+ stage: 'context',
295
+ positions: ['/policies/{policy}'],
296
+ statement: 'Every expanded branch of a named Policy is typed at its own use: its endpoint and repeat contracts do not contradict.',
297
+ },
298
+ PL_USE: {
299
+ stage: 'context',
300
+ positions: [...CHECKS],
301
+ statement: 'A Policy holds where it is used: a Class Policy for every Node or source and target pair of its Class, each check for the objects it admits, and each check tree can admit every Class its object accepts.',
302
+ enforces: 'A read Policy decides which callers observe the values of a Class’s Nodes or Edges, a traverse Policy which callers use them structurally; an absent one admits every caller.',
303
+ },
304
+ PL_VARIABLE_SCOPE: {
305
+ stage: 'rule',
306
+ positions: ['/policies/{policy}/expression{/path*}'],
307
+ statement: 'Every Policy variable is declared once, by one exists, is used only inside it, shadows no enclosing variable, and is used at least once.',
308
+ },
309
+ STRUCTURE_BINARY_INPUT: {
310
+ stage: 'structure',
311
+ positions: ['/functions/{function}/input'],
312
+ statement: 'A Function input in binary mode is a binary input: it declares its metadata and maximumBytes.',
313
+ conditions: ['#/$defs/function-definition/properties/input/anyOf/1/not'],
314
+ },
315
+ STRUCTURE_CALLABLE_POLICY_AUTH: {
316
+ stage: 'structure',
317
+ positions: at('/policy'),
318
+ statement: 'Only an authorized Function or Method declares a Policy.',
319
+ conditions: ['#/$defs/function-definition/if', '#/$defs/method-definition/if'],
320
+ },
321
+ STRUCTURE_DEPENDENCY_ALIAS: {
322
+ stage: 'structure',
323
+ positions: ['/dependencies/{alias}'],
324
+ statement: 'A dependency alias is neither prototype nor constructor.',
325
+ conditions: ['#/$defs/dependency-alias/not'],
326
+ },
327
+ STRUCTURE_DOMAIN_NAME: {
328
+ stage: 'structure',
329
+ positions: ['/name'],
330
+ statement: 'The Domain name is one line of text, without control characters or surrounding spaces.',
331
+ },
332
+ STRUCTURE_DUPLICATE_ITEM: {
333
+ stage: 'structure',
334
+ positions: [
335
+ '/classes/{class}/extends/{index}',
336
+ '/classes/{class}/endpoints/{endpoint}/accepts/{index}',
337
+ '/classes/{class}/properties/{property}/auto/on/{index}',
338
+ '/classes/{class}/unique/{index}',
339
+ '/classes/{class}/unique/{index}/{index}',
340
+ ],
341
+ statement: 'A set holds no item twice: extends, accepts, auto.on, unique and each unique tuple, where two tuples of the same fields are one.',
342
+ },
343
+ STRUCTURE_EDGE_BLOB: {
344
+ stage: 'structure',
345
+ positions: ['/classes/{class}/properties/{property}/schema/x-astrale-value-kind'],
346
+ statement: 'The schema of an Edge Property is not a blob: only a Node holds Blob contents.',
347
+ conditions: ['#/$defs/edge-property-definition/properties/schema/not'],
348
+ },
349
+ STRUCTURE_EDGE_ORIENTATION: {
350
+ stage: 'structure',
351
+ positions: [
352
+ '/classes/{class}/endpoints',
353
+ '/classes/{class}/unique',
354
+ '/classes/{class}/constraints/acyclic',
355
+ ],
356
+ statement: 'A directed Edge Class has source and target endpoints and an undirected one two incident endpoints, and only a directed one declares unique tuples or is acyclic.',
357
+ enforces: 'No Edges of an acyclic Class form a directed cycle.',
358
+ conditions: ['#/$defs/edge-class/if'],
359
+ },
360
+ STRUCTURE_FORMAT: {
361
+ stage: 'structure',
362
+ positions: ANY,
363
+ statement: 'A string matches the pattern of its position: an origin, a member name, a revision, a media type, a dependency alias or a Core slug.',
364
+ },
365
+ STRUCTURE_KEY: {
366
+ stage: 'structure',
367
+ positions: ANY,
368
+ statement: 'Every key of a record matches the pattern of the names it holds.',
369
+ },
370
+ STRUCTURE_MAXIMUM: {
371
+ stage: 'structure',
372
+ positions: ANY,
373
+ statement: 'A string, list or number is no greater than the bound of its position.',
374
+ limits: ['policy.variablesPerExists', 'policy.repetition'],
375
+ },
376
+ STRUCTURE_MINIMUM: {
377
+ stage: 'structure',
378
+ positions: ANY,
379
+ statement: 'A string, list or number is no less than the bound of its position.',
380
+ },
381
+ STRUCTURE_PROPERTY_KEY: {
382
+ stage: 'structure',
383
+ positions: [
384
+ '/classes/{class}/unique/{index}/{index}',
385
+ '/classes/{class}/unique/{index}/{index}/property',
386
+ '/core/nodes/{slug}/properties/{key}',
387
+ '/core/edges/{index}/properties/{key}',
388
+ ],
389
+ statement: 'A Property is named by its canonical key, <origin>:class.<Class>.property.<name>.',
390
+ },
391
+ STRUCTURE_PROTO_KEY: {
392
+ stage: 'structure',
393
+ positions: ANY,
394
+ statement: 'No object of the document has a member named __proto__, except the transitions of a State.',
395
+ conditions: [
396
+ '#/$defs/json-value/anyOf/5/propertyNames/not',
397
+ '#/$defs/value-schema/anyOf/1/propertyNames/not',
398
+ ],
399
+ },
400
+ STRUCTURE_REQUIRED: {
401
+ stage: 'structure',
402
+ positions: ANY,
403
+ statement: 'Every required field is present.',
404
+ },
405
+ STRUCTURE_STATE_TRANSITIONS: {
406
+ stage: 'structure',
407
+ positions: ['/classes/{class}/properties/{property}/state/transitions'],
408
+ statement: 'State transitions map each non-empty state name to a map from non-empty event names to non-empty state names.',
409
+ },
410
+ STRUCTURE_TYPE: {
411
+ stage: 'structure',
412
+ positions: ANY,
413
+ statement: 'Every value has the JSON type of its position.',
414
+ },
415
+ STRUCTURE_UNION: {
416
+ stage: 'structure',
417
+ positions: ANY,
418
+ statement: 'A value matches one of the variants of its position.',
419
+ },
420
+ STRUCTURE_UNKNOWN_FIELD: {
421
+ stage: 'structure',
422
+ positions: ANY,
423
+ statement: 'An object has only the fields of its position.',
424
+ },
425
+ STRUCTURE_VALUE: {
426
+ stage: 'structure',
427
+ positions: ANY,
428
+ statement: 'A literal or enumerated position holds one of its values.',
429
+ },
430
+ UNSUPPORTED_DOCUMENT_FORMAT: {
431
+ stage: 'structure',
432
+ positions: ['/format'],
433
+ statement: 'The document format is astrale.dsl.',
434
+ },
435
+ UNSUPPORTED_DSL_VERSION: {
436
+ stage: 'structure',
437
+ positions: ['/version'],
438
+ statement: 'The document version is one this DSL reads: v1.',
439
+ },
440
+ });
@@ -1,4 +1,37 @@
1
+ import type { ClassRef } from '../../addressing/index.js';
2
+ import type { CallableDefinition } from '../../language/callable/model/callable.js';
3
+ import type { ValueSchemaRegistry } from '../../language/value/reference/registry.js';
1
4
  import type { SchemaDiagnostic } from '../diagnostic.js';
2
5
  import type { DomainSchemaIR } from '../model/schema.js';
3
- /** Validate the execution modifier of every local Function and Node Method. */
4
- export declare function validateCallables(schema: DomainSchemaIR): readonly SchemaDiagnostic[];
6
+ /**
7
+ * One callable contract a Domain schema declares: where it is written, and the Node Class that
8
+ * receives its call, which its Policy names `self`. A contract is validated by the same rules
9
+ * wherever it is: in a Domain schema, at its declaration, or on the Node of a Function instance,
10
+ * which carries it (`acceptCallable`).
11
+ */
12
+ export interface DeclaredContract {
13
+ readonly contract: CallableDefinition;
14
+ /** Its declaration's JSON Pointer, which its diagnostics point within. */
15
+ readonly pointer: string;
16
+ /** The owner of an instance Method; a Function and a static Method have none. */
17
+ readonly receiver?: ClassRef;
18
+ /** The Node Class and name of a Method; absent for a Function. */
19
+ readonly method?: {
20
+ readonly owner: ClassRef;
21
+ readonly name: string;
22
+ };
23
+ }
24
+ /** Every callable contract one Domain schema declares: each Function, then each Node Method. */
25
+ export declare function declaredContracts(schema: DomainSchemaIR): readonly DeclaredContract[];
26
+ /**
27
+ * Validate the ref of every Function declaration, then the value schemas, execution modifier and
28
+ * admission age of every declared contract.
29
+ */
30
+ export declare function validateContracts(schema: DomainSchemaIR, registry: ValueSchemaRegistry): readonly SchemaDiagnostic[];
31
+ /**
32
+ * Validate one callable contract written at `pointer`, except its Policy (`validateContractPolicy`):
33
+ * its value schemas against the owner registry, its execution modifier and its admission age.
34
+ */
35
+ export declare function validateContract(contract: CallableDefinition, pointer: string, registry: ValueSchemaRegistry, diagnostics: SchemaDiagnostic[]): void;
36
+ /** Validate the execution modifier and admission age of one callable contract at `pointer`. */
37
+ export declare function validateCallableModifiers(declaration: CallableDefinition, pointer: string, diagnostics: SchemaDiagnostic[]): void;
@@ -1,21 +1,80 @@
1
+ import { equalDefinitionRefs } from '../../addressing/definition-ref.js';
2
+ import { Key } from '../../addressing/key.js';
3
+ import { isAdmissionMaxAge, MAXIMUM_ADMISSION_AGE_SECONDS, } from '../../language/callable/admission.js';
1
4
  import { isBinaryInput } from '../../language/callable/model/callable.js';
5
+ import { escapePointerToken } from '../../language/value/syntax/pointer.js';
2
6
  import { diagnostic } from '../diagnostic.js';
3
- /** Validate the execution modifier of every local Function and Node Method. */
4
- export function validateCallables(schema) {
5
- const diagnostics = [];
7
+ import { validateCallable } from './value.js';
8
+ /** Every callable contract one Domain schema declares: each Function, then each Node Method. */
9
+ export function declaredContracts(schema) {
10
+ const contracts = [];
6
11
  for (const [name, declaration] of Object.entries(schema.functions)) {
7
- validateExecution(declaration, `/functions/${escapePointer(name)}`, diagnostics);
12
+ contracts.push({ contract: declaration, pointer: `/functions/${escapePointerToken(name)}` });
8
13
  }
9
14
  for (const [name, declaration] of Object.entries(schema.classes)) {
10
15
  if (declaration.kind !== 'node')
11
16
  continue;
17
+ const owner = { origin: schema.origin, kind: 'class', name };
12
18
  for (const [method, value] of Object.entries(declaration.methods)) {
13
- const pointer = `/classes/${escapePointer(name)}/methods/${escapePointer(method)}`;
14
- validateExecution(value, pointer, diagnostics);
19
+ const pointer = `/classes/${escapePointerToken(name)}/methods/${escapePointerToken(method)}`;
20
+ contracts.push({
21
+ contract: value,
22
+ pointer,
23
+ ...(value.static ? {} : { receiver: owner }),
24
+ method: { owner, name: method },
25
+ });
15
26
  }
16
27
  }
28
+ return contracts;
29
+ }
30
+ /**
31
+ * Validate the ref of every Function declaration, then the value schemas, execution modifier and
32
+ * admission age of every declared contract.
33
+ */
34
+ export function validateContracts(schema, registry) {
35
+ const diagnostics = [];
36
+ for (const [name, declaration] of Object.entries(schema.functions)) {
37
+ validateFunctionRef(schema.origin, name, declaration.ref, diagnostics);
38
+ }
39
+ for (const { contract, pointer } of declaredContracts(schema)) {
40
+ validateContract(contract, pointer, registry, diagnostics);
41
+ }
17
42
  return Object.freeze(diagnostics);
18
43
  }
44
+ /**
45
+ * A Function declaration names itself by its ref: its own key in its own Domain. The ref belongs to
46
+ * the declaration, not to its contract, which a Node carries without one.
47
+ */
48
+ function validateFunctionRef(origin, name, declared, diagnostics) {
49
+ const ref = { origin, kind: 'function', name };
50
+ if (equalDefinitionRefs(declared, ref))
51
+ return;
52
+ diagnostics.push(diagnostic('DV_REF_RESOLVES', `/functions/${escapePointerToken(name)}/ref`, `Function ref must be exactly ${Key.of(ref)}.`, Key.of(declared)));
53
+ }
54
+ /**
55
+ * Validate one callable contract written at `pointer`, except its Policy (`validateContractPolicy`):
56
+ * its value schemas against the owner registry, its execution modifier and its admission age.
57
+ */
58
+ export function validateContract(contract, pointer, registry, diagnostics) {
59
+ validateCallable(contract, pointer, registry, diagnostics);
60
+ validateCallableModifiers(contract, pointer, diagnostics);
61
+ }
62
+ /** Validate the execution modifier and admission age of one callable contract at `pointer`. */
63
+ export function validateCallableModifiers(declaration, pointer, diagnostics) {
64
+ validateExecution(declaration, pointer, diagnostics);
65
+ validateAdmission(declaration, pointer, diagnostics);
66
+ }
67
+ /**
68
+ * An admission age is a whole number of seconds within the language ceiling. It has no zero
69
+ * spelling: an absent admission age is the one canonical form of a call admitted afresh.
70
+ */
71
+ function validateAdmission(declaration, pointer, diagnostics) {
72
+ if (declaration.admission === undefined)
73
+ return;
74
+ if (isAdmissionMaxAge(declaration.admission.maxAge))
75
+ return;
76
+ diagnostics.push(diagnostic('DV_CALLABLE_ADMISSION', `${pointer}/admission/maxAge`, `An admission age is an integer number of seconds from 1 to ${MAXIMUM_ADMISSION_AGE_SECONDS}; omit it to admit every call afresh.`));
77
+ }
19
78
  /**
20
79
  * An Execution records its initiating caller and its admitted input, from which the run is
21
80
  * resubmitted, and retains one portable outcome. A durable callable therefore needs a known caller,
@@ -34,6 +93,3 @@ function validateExecution(declaration, pointer, diagnostics) {
34
93
  diagnostics.push(diagnostic('DV_CALLABLE_IO', `${pointer}/output/mode`, 'A durable callable requires a value output.'));
35
94
  }
36
95
  }
37
- function escapePointer(value) {
38
- return value.replaceAll('~', '~0').replaceAll('/', '~1');
39
- }
@@ -1,10 +1,14 @@
1
1
  import type { ClassRef } from '../../addressing/index.js';
2
2
  import type { ClassDefinition } from '../../language/class/model/class.js';
3
+ import type { ValueSchemaRegistry } from '../../language/value/reference/registry.js';
3
4
  import type { DefinitionAnalysisResult } from '../analysis/class.js';
4
5
  import type { SchemaDiagnostic } from '../diagnostic.js';
5
6
  import type { DomainResolutionContext } from '../resolution/context.js';
6
- /** Validate the semantic contracts owned by Class declarations. */
7
- export declare function validateDefinitions(environment: DomainResolutionContext, analysis: DefinitionAnalysisResult): readonly SchemaDiagnostic[];
7
+ /**
8
+ * Validate the semantic contracts owned by Class declarations. `registry` is the candidate's value
9
+ * registry; each dependency's is built at most once, so the Classes share them.
10
+ */
11
+ export declare function validateDefinitions(environment: DomainResolutionContext, analysis: DefinitionAnalysisResult, registry: ValueSchemaRegistry): readonly SchemaDiagnostic[];
8
12
  /** Whether `child` safely refines its parent Edge contract `parent`. */
9
13
  export declare function edgeContractRefines(environment: DomainResolutionContext, child: Extract<ClassDefinition, {
10
14
  readonly kind: 'edge';