@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,40 @@
1
+ import type { core as zodCore } from 'zod';
2
+ import type { DiagnosticCode as ValueDiagnosticCode } from '../../language/validation/diagnostic.js';
3
+ import type { SchemaDiagnosticCode } from '../diagnostic.js';
4
+ /** A JSON Schema of the published document, or a part of one. */
5
+ export type JsonSchema = zodCore.JSONSchema.JSONSchema;
6
+ /**
7
+ * A check JSON Schema cannot state, which the published document names: the code the Kernel
8
+ * reports, with its value code for a check on value schemas, and the rule in one plain sentence.
9
+ */
10
+ export interface NamedRuleEntry {
11
+ readonly code: SchemaDiagnosticCode;
12
+ readonly valueCode?: ValueDiagnosticCode;
13
+ readonly statement: string;
14
+ }
15
+ /**
16
+ * `schema` with the `x-astrale-rule` marker naming the checks of `Rule` it leaves to the Kernel.
17
+ * `Rule` is given at each call, so that a name outside it does not compile.
18
+ */
19
+ export declare function named<Rule extends string = never>(schema: JsonSchema, ...rules: [NoInfer<Rule>, ...NoInfer<Rule>[]]): JsonSchema;
20
+ /**
21
+ * The check that a document is portable JSON, which `schema.decode` and `schema.accept` make first.
22
+ * JSON Schema reads a parsed value and compares numbers by their value: it states that no string or
23
+ * member name holds U+0000, and cannot state negative zero, a lone surrogate, a UTF-8 size, a
24
+ * nesting depth without one definition per level, a count of members, or what the text was.
25
+ */
26
+ export declare const jsonValueRules: {
27
+ readonly 'portable-json': {
28
+ readonly code: 'DV_JSON_VALUE';
29
+ readonly statement: string;
30
+ };
31
+ };
32
+ export type JsonValueRule = keyof typeof jsonValueRules;
33
+ /**
34
+ * Portable JSON in JSON Schema: `root` constrains the whole document, and `definitions` holds every
35
+ * value it reaches and every string. The named check leaves `x-astrale-rule` on `portable-json`.
36
+ */
37
+ export declare function jsonValueJsonSchema(): {
38
+ readonly root: JsonSchema;
39
+ readonly definitions: Readonly<Record<string, JsonSchema>>;
40
+ };
@@ -0,0 +1,46 @@
1
+ import { RULES } from '../rule.js';
2
+ /**
3
+ * `schema` with the `x-astrale-rule` marker naming the checks of `Rule` it leaves to the Kernel.
4
+ * `Rule` is given at each call, so that a name outside it does not compile.
5
+ */
6
+ export function named(schema, ...rules) {
7
+ return { ...schema, 'x-astrale-rule': rules };
8
+ }
9
+ /**
10
+ * The check that a document is portable JSON, which `schema.decode` and `schema.accept` make first.
11
+ * JSON Schema reads a parsed value and compares numbers by their value: it states that no string or
12
+ * member name holds U+0000, and cannot state negative zero, a lone surrogate, a UTF-8 size, a
13
+ * nesting depth without one definition per level, a count of members, or what the text was.
14
+ */
15
+ export const jsonValueRules = {
16
+ 'portable-json': { code: 'DV_JSON_VALUE', statement: RULES.DV_JSON_VALUE.statement },
17
+ };
18
+ const VALUE = '#/$defs/portable-json';
19
+ const TEXT = '#/$defs/portable-string';
20
+ /**
21
+ * Portable JSON in JSON Schema: `root` constrains the whole document, and `definitions` holds every
22
+ * value it reaches and every string. The named check leaves `x-astrale-rule` on `portable-json`.
23
+ */
24
+ export function jsonValueJsonSchema() {
25
+ return {
26
+ root: { $ref: VALUE },
27
+ definitions: {
28
+ 'portable-json': named({
29
+ anyOf: [
30
+ { type: 'null' },
31
+ { type: 'boolean' },
32
+ { type: 'number' },
33
+ { $ref: TEXT },
34
+ { type: 'array', items: { $ref: VALUE } },
35
+ {
36
+ type: 'object',
37
+ propertyNames: { $ref: TEXT },
38
+ additionalProperties: { $ref: VALUE },
39
+ },
40
+ ],
41
+ }, 'portable-json'),
42
+ // The pattern is the character itself, which every regular-expression dialect reads.
43
+ 'portable-string': { type: 'string', not: { pattern: '\u0000' } },
44
+ },
45
+ };
46
+ }
@@ -1,4 +1,35 @@
1
+ import type { PolicyExpression } from '../../../language/policy/model/policy.js';
2
+ import type { DomainSchemaIR } from '../../model/schema.js';
1
3
  import type { PolicyValidationContext } from './context.js';
2
- import { BRANCH_OVERFLOW, MAX_BRANCHES, MAX_CHECK_DEPTH, MAX_CHECK_LEAVES, MAX_DOMAINS, MAX_EDGES, MAX_PATTERN_DEPTH, MAX_REPEAT, MAX_VARIABLES, measureChecks } from '../../../language/policy/analysis/budgets.js';
3
- export { BRANCH_OVERFLOW, MAX_BRANCHES, MAX_CHECK_DEPTH, MAX_CHECK_LEAVES, MAX_DOMAINS, MAX_EDGES, MAX_PATTERN_DEPTH, MAX_REPEAT, MAX_VARIABLES, measureChecks, };
4
+ import { type CheckMeasure, type PolicyMeasure } from '../../../language/policy/analysis/budgets.js';
5
+ /** What `PL_BUDGET` compares with `limits.policy` in one document, frozen. */
6
+ export interface PolicyMeasures {
7
+ /** Each named Policy the DSL can measure, by name. */
8
+ readonly policies: Readonly<Record<string, PolicyMeasure>>;
9
+ /**
10
+ * The named Policies the DSL cannot measure, in document order: a composition that reaches
11
+ * itself, or that names a Policy the document does not declare or one it cannot measure.
12
+ */
13
+ readonly unmeasured: readonly string[];
14
+ /**
15
+ * Each check tree by the JSON Pointer of its position: the Policy of a Function or a Method, or
16
+ * the rule of a Class slot.
17
+ */
18
+ readonly checks: Readonly<Record<string, CheckMeasure>>;
19
+ }
20
+ /**
21
+ * Measure the Policies of a document as `PL_BUDGET` does: it reads the document's structure alone,
22
+ * so a document the structure admits is measured whatever its other rules decide. Throws
23
+ * `SchemaError` with the diagnostics of a document that is not portable JSON or that its
24
+ * structure refuses.
25
+ */
26
+ export declare function measurePolicies(input: unknown): PolicyMeasures;
27
+ /** The measures of one structured document, from its Policies once normalized. */
28
+ export declare function measureDomainPolicies(schema: DomainSchemaIR, normalized?: ReadonlyMap<string, PolicyExpression>): PolicyMeasures;
29
+ /** `PL_BUDGET`: every measure of the document within `limits.policy`. */
4
30
  export declare function validatePolicyBudgets(context: PolicyValidationContext): void;
31
+ /**
32
+ * `PL_BUDGET` for one check tree at `pointer`, from its measure: the document's trees, and the
33
+ * checks of a contract a Node carries, which no document holds.
34
+ */
35
+ export declare function validateCheckBudget(context: PolicyValidationContext, pointer: string, measure: CheckMeasure): void;
@@ -1,132 +1,98 @@
1
- import { policyObjectOrigin, policyVariableClass } from '../../../language/index.js';
2
- import { BRANCH_OVERFLOW, MAX_BRANCHES, MAX_CHECK_DEPTH, MAX_CHECK_LEAVES, MAX_DOMAINS, MAX_EDGES, MAX_PATTERN_DEPTH, MAX_REPEAT, MAX_VARIABLES, measureChecks, } from '../../../language/policy/analysis/budgets.js';
3
- import { escapePointer } from './context.js';
4
- export { BRANCH_OVERFLOW, MAX_BRANCHES, MAX_CHECK_DEPTH, MAX_CHECK_LEAVES, MAX_DOMAINS, MAX_EDGES, MAX_PATTERN_DEPTH, MAX_REPEAT, MAX_VARIABLES, measureChecks, };
5
- export function validatePolicyBudgets(context) {
6
- // Measure every distinct composition node once. A node's expanded measure is independent of the
7
- // path that reaches it (the only path-sensitive outcome, the back-edge `undefined`, already holds
8
- // for every node on or reaching a composition cycle, regardless of entry), so caching the
9
- // completed result by node identity turns path enumeration over the composition DAG into work
10
- // linear in the number of nodes while preserving the exact measure and PL_BUDGET decision.
11
- const measures = new Map();
12
- for (const name of Object.keys(context.environment.candidate.policies)) {
13
- const measure = measurePolicy(context, name, new Set(), measures);
1
+ import { deepFreeze } from '../../../language/freeze.js';
2
+ import { limits } from '../../../language/limits.js';
3
+ import { exceededLimits, measureChecks, policyMeasurer, } from '../../../language/policy/analysis/budgets.js';
4
+ import { CLASS_OPERATIONS, isClassRuleChecks } from '../../../language/policy/model/policy.js';
5
+ import { normalizePolicyChecks, normalizePolicyExpression, } from '../../../language/policy/normalization/normalize.js';
6
+ import { escapePointerToken } from '../../../language/value/syntax/pointer.js';
7
+ import { structureDomainSchema } from '../domain.route.js';
8
+ import { SITE } from './uses.js';
9
+ /**
10
+ * Measure the Policies of a document as `PL_BUDGET` does: it reads the document's structure alone,
11
+ * so a document the structure admits is measured whatever its other rules decide. Throws
12
+ * `SchemaError` with the diagnostics of a document that is not portable JSON or that its
13
+ * structure refuses.
14
+ */
15
+ export function measurePolicies(input) {
16
+ return measureDomainPolicies(structureDomainSchema(input));
17
+ }
18
+ /** The measures of one structured document, from its Policies once normalized. */
19
+ export function measureDomainPolicies(schema, normalized = normalizedPolicies(schema)) {
20
+ const measurePolicy = policyMeasurer(schema.origin, normalized, (ref) => ref.origin === schema.origin &&
21
+ ref.kind === 'policy' &&
22
+ Object.hasOwn(schema.policies, ref.name));
23
+ const policies = {};
24
+ const unmeasured = [];
25
+ for (const name of Object.keys(schema.policies)) {
26
+ const measure = measurePolicy(name);
14
27
  if (measure === undefined)
15
- continue;
16
- const pointer = `/policies/${escapePointer(name)}`;
17
- if (measure.depth > MAX_PATTERN_DEPTH) {
18
- context.add('PL_BUDGET', pointer, `Expanded Pattern depth ${measure.depth} exceeds ${MAX_PATTERN_DEPTH}.`);
19
- }
20
- if (measure.edgeCounts.length > MAX_BRANCHES) {
21
- context.add('PL_BUDGET', pointer, `Expanded Pattern has more than ${MAX_BRANCHES} normalized branches.`);
22
- }
23
- const edgeMaximum = Math.max(0, ...measure.edgeCounts);
24
- if (edgeMaximum > MAX_EDGES) {
25
- context.add('PL_BUDGET', pointer, `A normalized branch contains ${edgeMaximum} graph predicates; the maximum is ${MAX_EDGES}.`);
26
- }
27
- if (measure.domains.size > MAX_DOMAINS) {
28
- context.add('PL_BUDGET', pointer, `Expanded Pattern references ${measure.domains.size} Domains; the maximum is ${MAX_DOMAINS}.`);
29
- }
28
+ unmeasured.push(name);
29
+ else
30
+ policies[name] = measure;
30
31
  }
31
- }
32
- function measurePolicy(context, name, visiting, measures) {
33
- if (visiting.has(name))
34
- return undefined;
35
- if (measures.has(name))
36
- return measures.get(name);
37
- const declaration = context.normalized.get(name);
38
- if (declaration === undefined)
39
- return undefined;
40
- const nested = new Set(visiting);
41
- nested.add(name);
42
- const measure = measureDeclaration(context, declaration, nested, measures);
43
- measures.set(name, measure);
44
- return measure;
45
- }
46
- function measureDeclaration(context, declaration, nested, measures) {
47
- if ('match' in declaration) {
48
- return measurePattern(declaration.match, context.environment.candidate.origin);
32
+ const checks = {};
33
+ for (const [pointer, expression] of checkTrees(schema)) {
34
+ checks[pointer] = measureChecks(normalizePolicyChecks(expression));
49
35
  }
50
- const refs = 'allOf' in declaration ? declaration.allOf : declaration.anyOf;
51
- const children = refs.flatMap((ref) => {
52
- if (!context.isLocalPolicy(ref))
53
- return [];
54
- const value = measurePolicy(context, ref.name, nested, measures);
55
- return value === undefined ? [] : [value];
56
- });
57
- if (children.length !== refs.length || children.length === 0)
58
- return undefined;
59
- return combineMeasures('allOf' in declaration ? 'allOf' : 'anyOf', children);
36
+ return deepFreeze({ policies, unmeasured, checks });
60
37
  }
61
- function measurePattern(pattern, ownOrigin) {
62
- if ('sameNode' in pattern)
63
- return {
64
- depth: 1,
65
- edgeCounts: [1],
66
- domains: new Set([
67
- ownOrigin,
68
- ...[pattern.sameNode.left, pattern.sameNode.right].flatMap((term) => term.kind === 'ref' ? [policyObjectOrigin(term.ref)] : []),
69
- ]),
70
- };
71
- if (isEdge(pattern)) {
72
- return {
73
- depth: 1,
74
- edgeCounts: [1],
75
- domains: new Set([
76
- ownOrigin,
77
- pattern.class.origin,
78
- ...[pattern.source, pattern.target].flatMap((term) => term.kind === 'ref' ? [policyObjectOrigin(term.ref)] : []),
79
- ]),
80
- };
38
+ /** `PL_BUDGET`: every measure of the document within `limits.policy`. */
39
+ export function validatePolicyBudgets(context) {
40
+ const measures = measureDomainPolicies(context.environment.candidate, context.normalized);
41
+ for (const [name, measure] of Object.entries(measures.policies)) {
42
+ for (const limit of exceededLimits(measure)) {
43
+ context.add('PL_BUDGET', `/policies/${escapePointerToken(name)}`, REFUSAL[limit](measure));
44
+ }
81
45
  }
82
- if ('exists' in pattern) {
83
- const child = measurePattern(pattern.exists.where, ownOrigin);
84
- return {
85
- depth: child.depth + 1,
86
- edgeCounts: child.edgeCounts,
87
- domains: new Set([
88
- ...child.domains,
89
- ...pattern.exists.nodes.flatMap((node) => {
90
- const ref = policyVariableClass(node);
91
- return ref === undefined ? [] : [ref.origin];
92
- }),
93
- ]),
94
- };
46
+ for (const [pointer, measure] of Object.entries(measures.checks)) {
47
+ validateCheckBudget(context, pointer, measure);
95
48
  }
96
- const { key, values } = patternOperands(pattern);
97
- return combineMeasures(key, values.map((child) => measurePattern(child, ownOrigin)));
98
49
  }
99
- function combineMeasures(key, children) {
100
- const depth = 1 + Math.max(0, ...children.map((child) => child.depth));
101
- const domains = new Set(children.flatMap((child) => [...child.domains]));
102
- if (key === 'anyOf') {
103
- return {
104
- depth,
105
- edgeCounts: children.flatMap((child) => child.edgeCounts).slice(0, BRANCH_OVERFLOW),
106
- domains,
107
- };
108
- }
109
- let edgeCounts = [0];
110
- for (const child of children) {
111
- const next = [];
112
- for (const left of edgeCounts) {
113
- for (const right of child.edgeCounts) {
114
- next.push(left + right);
115
- if (next.length >= BRANCH_OVERFLOW)
116
- break;
50
+ /**
51
+ * `PL_BUDGET` for one check tree at `pointer`, from its measure: the document's trees, and the
52
+ * checks of a contract a Node carries, which no document holds.
53
+ */
54
+ export function validateCheckBudget(context, pointer, measure) {
55
+ if (exceededLimits(measure).length === 0)
56
+ return;
57
+ const { checkDepth, checkBranches, checkLeaves } = limits.policy;
58
+ // A callable holds its checks at `policy`; a Class rule at `policies/{operation}`.
59
+ const site = SITE[pointer.endsWith('/policy') ? 'callable' : 'class'];
60
+ context.add('PL_BUDGET', pointer, `${site.checks} require depth <= ${checkDepth}, branches <= ${checkBranches}, and leaves <= ${checkLeaves}; got ${measure.checkDepth}, ${measure.checkBranches}, ${measure.checkLeaves}.`);
61
+ }
62
+ /** How `PL_BUDGET` explains each limit a named Policy exceeds. */
63
+ const REFUSAL = {
64
+ patternDepth: (measure) => `Expanded Pattern depth ${measure.patternDepth} exceeds ${limits.policy.patternDepth}.`,
65
+ normalizedBranches: () => `Expanded Pattern has more than ${limits.policy.normalizedBranches} normalized branches.`,
66
+ edgePredicates: (measure) => `A normalized branch contains ${measure.edgePredicates} graph predicates; the maximum is ${limits.policy.edgePredicates}.`,
67
+ referencedDomains: (measure) => `Expanded Pattern references ${measure.referencedDomains} Domains; the maximum is ${limits.policy.referencedDomains}.`,
68
+ };
69
+ function normalizedPolicies(schema) {
70
+ return new Map(Object.entries(schema.policies).map(([name, declaration]) => [
71
+ name,
72
+ normalizePolicyExpression(declaration.expression),
73
+ ]));
74
+ }
75
+ /** Every check tree of a document with the pointer of its position, in document order. */
76
+ function* checkTrees(schema) {
77
+ for (const [name, declaration] of Object.entries(schema.classes)) {
78
+ const owner = `/classes/${escapePointerToken(name)}`;
79
+ for (const operation of CLASS_OPERATIONS) {
80
+ const rule = declaration.policies[operation];
81
+ if (typeof rule === 'object' && isClassRuleChecks(rule)) {
82
+ yield [`${owner}/policies/${operation}`, rule];
83
+ }
84
+ }
85
+ if (declaration.kind !== 'node')
86
+ continue;
87
+ for (const [method, value] of Object.entries(declaration.methods)) {
88
+ if (typeof value.policy === 'object') {
89
+ yield [`${owner}/methods/${escapePointerToken(method)}/policy`, value.policy];
117
90
  }
118
- if (next.length >= BRANCH_OVERFLOW)
119
- break;
120
91
  }
121
- edgeCounts = next;
122
92
  }
123
- return { depth, edgeCounts, domains };
124
- }
125
- function patternOperands(value) {
126
- return 'allOf' in value
127
- ? { key: 'allOf', values: value.allOf }
128
- : { key: 'anyOf', values: value.anyOf };
129
- }
130
- function isEdge(value) {
131
- return 'source' in value;
93
+ for (const [name, declaration] of Object.entries(schema.functions)) {
94
+ if (typeof declaration.policy === 'object') {
95
+ yield [`/functions/${escapePointerToken(name)}/policy`, declaration.policy];
96
+ }
97
+ }
132
98
  }
@@ -1,11 +1,12 @@
1
1
  import type { ClassDefinition } from '../../../language/class/model/class.js';
2
- import type { PolicyExpression } from '../../../language/policy/model/policy.js';
2
+ import type { ObjectContract, PolicyTypingScope } from '../../../language/policy/analysis/typing.js';
3
+ import type { PolicyExpression, PolicyObjectRef } from '../../../language/policy/model/policy.js';
3
4
  import type { DefinitionAnalysisResult } from '../../analysis/class.js';
4
5
  import type { SchemaDiagnostic, SchemaDiagnosticCode } from '../../diagnostic.js';
5
6
  import type { DomainResolutionContext } from '../../resolution/context.js';
6
7
  import type { IndexedClassDefinition } from '../../resolution/definition.index.js';
7
8
  import { type ClassRef, type PolicyRef } from '../../../addressing/index.js';
8
- export declare class PolicyValidationContext {
9
+ export declare class PolicyValidationContext implements PolicyTypingScope {
9
10
  #private;
10
11
  readonly environment: DomainResolutionContext;
11
12
  readonly analysis: DefinitionAnalysisResult;
@@ -21,8 +22,8 @@ export declare class PolicyValidationContext {
21
22
  edgeDeclaration(ref: ClassRef): Extract<ClassDefinition, {
22
23
  readonly kind: 'edge';
23
24
  }> | undefined;
24
- /** Return true when candidate is the required Class or a same-kind descendant. */
25
- classExtends(candidate: ClassRef, required: ClassRef): boolean;
25
+ resolveClass(ref: ClassRef): ClassDefinition | undefined;
26
+ /** The contract a Policy pattern reference types, reporting an invalid one under `/policies`. */
27
+ referenceContract(ref: PolicyObjectRef): ObjectContract | undefined;
26
28
  add(code: SchemaDiagnosticCode, pointer: string, message: string, ref?: string): void;
27
29
  }
28
- export declare function escapePointer(value: string): string;
@@ -1,7 +1,7 @@
1
1
  import { Key } from '../../../addressing/index.js';
2
2
  import { definitionRefIndex } from '../../../addressing/ordering.js';
3
- import { classSatisfies } from '../../../language/class/inheritance.js';
4
3
  import { diagnostic } from '../../diagnostic.js';
4
+ import { referenceContracts } from './objects.js';
5
5
  const formatDefinitionRef = Key.of;
6
6
  export class PolicyValidationContext {
7
7
  environment;
@@ -62,17 +62,14 @@ export class PolicyValidationContext {
62
62
  }
63
63
  return resolved.declaration;
64
64
  }
65
- /** Return true when candidate is the required Class or a same-kind descendant. */
66
- classExtends(candidate, required) {
67
- const resolve = (ref) => this.environment.resolveAny(ref)?.declaration;
68
- const actual = resolve(candidate);
69
- const target = resolve(required);
70
- return actual !== undefined && target !== undefined && classSatisfies(actual, target, resolve);
65
+ resolveClass(ref) {
66
+ return this.environment.resolveAny(ref)?.declaration;
67
+ }
68
+ /** The contract a Policy pattern reference types, reporting an invalid one under `/policies`. */
69
+ referenceContract(ref) {
70
+ return referenceContracts(this, ref, '/policies')?.[0];
71
71
  }
72
72
  add(code, pointer, message, ref) {
73
73
  this.diagnostics.push(diagnostic(code, pointer, message, ref));
74
74
  }
75
75
  }
76
- export function escapePointer(value) {
77
- return value.replaceAll('~', '~0').replaceAll('/', '~1');
78
- }
@@ -1,4 +1,4 @@
1
1
  import type { PolicyObjectRef } from '../../../language/index.js';
2
+ import type { ObjectContract } from '../../../language/policy/analysis/typing.js';
2
3
  import type { PolicyValidationContext } from './context.js';
3
- import type { ObjectContract } from './typing.js';
4
4
  export declare function referenceContracts(validation: PolicyValidationContext, ref: PolicyObjectRef, pointer: string): readonly ObjectContract[] | undefined;
@@ -1,11 +1,6 @@
1
1
  import { definitionRefIndex } from '../../../addressing/ordering.js';
2
2
  import { isMethodExecutable } from '../../../language/callable/executable.js';
3
- import { policyObjectKey, policyObjectOrigin } from '../../../language/index.js';
4
- const KERNEL_ORIGIN = 'kernel.astrale.ai';
5
- const PROJECTION_CLASS = nodeClassRef('Class');
6
- const PROJECTION_FUNCTION = nodeClassRef('Function');
7
- const PROJECTION_POLICY = nodeClassRef('Policy');
8
- const PROJECTION_VIEW = nodeClassRef('View');
3
+ import { policyObjectKey, policyObjectOrigin, projectedMemberClass, } from '../../../language/index.js';
9
4
  export function referenceContracts(validation, ref, pointer) {
10
5
  const candidate = validation.environment.candidate;
11
6
  const local = policyObjectOrigin(ref) === candidate.origin;
@@ -21,7 +16,7 @@ export function referenceContracts(validation, ref, pointer) {
21
16
  case 'class': {
22
17
  const resolved = validation.environment.resolve(ref);
23
18
  return resolved?.ref.kind === ref.kind
24
- ? [{ kind: 'exact', ref: PROJECTION_CLASS }]
19
+ ? [{ kind: 'exact', ref: projectedMemberClass(ref) }]
25
20
  : invalidPolicyObjectRef(validation, ref, pointer);
26
21
  }
27
22
  case 'method': {
@@ -29,20 +24,20 @@ export function referenceContracts(validation, ref, pointer) {
29
24
  const method = declaringClass?.kind === 'node' ? declaringClass.methods[ref.name] : undefined;
30
25
  return method === undefined || !isMethodExecutable(declaringClass, method)
31
26
  ? invalidPolicyObjectRef(validation, ref, pointer)
32
- : [{ kind: 'exact', ref: PROJECTION_FUNCTION }];
27
+ : [{ kind: 'exact', ref: projectedMemberClass(ref) }];
33
28
  }
34
29
  case 'function':
35
30
  return owner.functions[ref.name] === undefined
36
31
  ? invalidPolicyObjectRef(validation, ref, pointer)
37
- : [{ kind: 'exact', ref: PROJECTION_FUNCTION }];
32
+ : [{ kind: 'exact', ref: projectedMemberClass(ref) }];
38
33
  case 'policy':
39
34
  return owner.policies[ref.name] === undefined
40
35
  ? invalidPolicyObjectRef(validation, ref, pointer)
41
- : [{ kind: 'exact', ref: PROJECTION_POLICY }];
36
+ : [{ kind: 'exact', ref: projectedMemberClass(ref) }];
42
37
  case 'view':
43
38
  return owner.views[ref.name] === undefined
44
39
  ? invalidPolicyObjectRef(validation, ref, pointer)
45
- : [{ kind: 'exact', ref: PROJECTION_VIEW }];
40
+ : [{ kind: 'exact', ref: projectedMemberClass(ref) }];
46
41
  case 'core': {
47
42
  const node = owner.core.nodes[ref.name];
48
43
  if (node === undefined)
@@ -66,6 +61,3 @@ function invalidPolicyObjectRef(validation, ref, pointer) {
66
61
  validation.add('PL_REF', `${pointer}/ref`, `${policyObjectKey(ref)} is not an exact local or direct-dependency projected Policy object.`, policyObjectKey(ref));
67
62
  return undefined;
68
63
  }
69
- function nodeClassRef(name) {
70
- return { origin: KERNEL_ORIGIN, kind: 'class', name };
71
- }
@@ -1,24 +1,22 @@
1
+ import { equalDefinitionRefs } from '../../../addressing/definition-ref.js';
1
2
  import { branchesOf, isConnected, targetMode } from '../../../language/policy/analysis/branches.js';
2
3
  import { policyVariableClass } from '../../../language/policy/model/policy.js';
3
4
  import { normalizePolicyExpression, normalizePolicyPattern, } from '../../../language/policy/normalization/normalize.js';
4
- import { MAX_REPEAT, MAX_VARIABLES } from './budgets.js';
5
- import { escapePointer } from './context.js';
5
+ import { escapePointerToken } from '../../../language/value/syntax/pointer.js';
6
6
  import { referenceContracts } from './objects.js';
7
7
  export function validatePolicyReferences(context) {
8
8
  for (const [name, declaration] of Object.entries(context.environment.candidate.policies)) {
9
- const pointer = `/policies/${escapePointer(name)}`;
9
+ const pointer = `/policies/${escapePointerToken(name)}`;
10
10
  const expected = { origin: context.environment.candidate.origin, kind: 'policy', name };
11
- if (declaration.ref.origin !== expected.origin ||
12
- declaration.ref.kind !== expected.kind ||
13
- declaration.ref.name !== expected.name) {
11
+ if (!equalDefinitionRefs(declaration.ref, expected)) {
14
12
  context.add('DV_REF_RESOLVES', `${pointer}/ref`, `Policy ref must be exactly ${expected.origin}:policy.${expected.name}.`);
15
13
  }
16
14
  const expression = declaration.expression;
17
15
  context.normalized.set(name, normalizePolicyExpression(expression));
18
16
  if ('match' in expression)
19
- validateMatch(context, name, expression.match, pointer);
17
+ validateMatch(context, name, expression.match, `${pointer}/expression`);
20
18
  else
21
- validateComposition(context, expression, pointer);
19
+ validateComposition(context, expression, `${pointer}/expression`);
22
20
  }
23
21
  validateCycles(context);
24
22
  }
@@ -54,22 +52,14 @@ function validatePatternNode(context, pattern, pointer, scope, declarations, use
54
52
  context.resolveEdge(pattern.class, `${pointer}/class`);
55
53
  validateTerm(context, pattern.source, `${pointer}/source`, scope, uses);
56
54
  validateTerm(context, pattern.target, `${pointer}/target`, scope, uses);
57
- if (pattern.repeat !== undefined) {
58
- const { min, max } = pattern.repeat;
59
- if (!Number.isInteger(min) ||
60
- !Number.isInteger(max) ||
61
- min < 0 ||
62
- max < min ||
63
- max > MAX_REPEAT) {
64
- context.add('PL_REPEAT', `${pointer}/repeat`, `Repeat requires integral bounds 0 <= min <= max <= ${MAX_REPEAT}.`);
65
- }
55
+ // The structure bounds each to an integer from 0 to `limits.policy.repetition`; only their
56
+ // order is left.
57
+ if (pattern.repeat !== undefined && pattern.repeat.max < pattern.repeat.min) {
58
+ context.add('PL_REPEAT', `${pointer}/repeat`, 'Repeat requires min <= max.');
66
59
  }
67
60
  return;
68
61
  }
69
62
  if ('exists' in pattern) {
70
- if (pattern.exists.nodes.length > MAX_VARIABLES) {
71
- context.add('PL_BUDGET', `${pointer}/exists/nodes`, `An exists expression declares ${pattern.exists.nodes.length} variables; the maximum is ${MAX_VARIABLES}.`);
72
- }
73
63
  const nested = new Set(scope);
74
64
  for (const [index, node] of pattern.exists.nodes.entries()) {
75
65
  const id = node.variable.id;
@@ -93,9 +83,6 @@ function validatePatternNode(context, pattern, pointer, scope, declarations, use
93
83
  return;
94
84
  }
95
85
  const { key, values } = patternOperands(pattern);
96
- if (values.length === 0) {
97
- context.add('PL_COMPOSITION', `${pointer}/${key}`, `${key} must be non-empty.`);
98
- }
99
86
  values.forEach((child, index) => validatePatternNode(context, child, `${pointer}/${key}/${index}`, scope, declarations, uses));
100
87
  }
101
88
  function validateTerm(context, term, pointer, scope, uses) {
@@ -113,9 +100,6 @@ function validateTerm(context, term, pointer, scope, uses) {
113
100
  function validateComposition(context, declaration, pointer) {
114
101
  const key = 'allOf' in declaration ? 'allOf' : 'anyOf';
115
102
  const refs = 'allOf' in declaration ? declaration.allOf : declaration.anyOf;
116
- if (refs.length === 0) {
117
- context.add('PL_COMPOSITION', `${pointer}/${key}`, `${key} must be non-empty.`);
118
- }
119
103
  refs.forEach((ref, index) => context.resolvePolicy(ref, `${pointer}/${key}/${index}`));
120
104
  }
121
105
  function validateCycles(context) {
@@ -123,7 +107,7 @@ function validateCycles(context) {
123
107
  const visited = new Set();
124
108
  const visit = (name, stack) => {
125
109
  if (visiting.has(name)) {
126
- context.add('PL_COMPOSITION', `/policies/${escapePointer(name)}`, `Named Policy composition cycle: ${[...stack, name].join(' -> ')}.`);
110
+ context.add('PL_COMPOSITION', `/policies/${escapePointerToken(name)}`, `Named Policy composition cycle: ${[...stack, name].join(' -> ')}.`);
127
111
  return;
128
112
  }
129
113
  if (visited.has(name))
@@ -1,21 +1,6 @@
1
1
  import type { ClassRef } from '../../../addressing/index.js';
2
+ import type { ObjectContract, PolicyTyping } from '../../../language/policy/analysis/typing.js';
2
3
  import type { PolicyValidationContext } from './context.js';
3
- export type ObjectContract = {
4
- readonly kind: 'default';
5
- } | {
6
- readonly kind: 'exact';
7
- readonly ref: ClassRef;
8
- };
9
- export declare class PolicyTyping {
10
- #private;
11
- readonly context: PolicyValidationContext;
12
- constructor(context: PolicyValidationContext);
13
- validatePolicies(): void;
14
- policyAccepts(name: string, object: ObjectContract): boolean;
15
- /** Whether each normalized branch of the Policy is typed for an object of this contract. */
16
- policyBranchTyping(name: string, object: ObjectContract): readonly boolean[] | undefined;
17
- policyAcceptsEdge(name: string, source: ObjectContract, target: ObjectContract): boolean;
18
- concreteEndpointClasses(accepts: readonly ClassRef[]): readonly ClassRef[];
19
- endpointsOverlap(left: readonly ClassRef[], right: readonly ClassRef[]): boolean;
20
- }
4
+ /** Type every expanded branch of each named Policy at its own default use. */
5
+ export declare function validatePolicyTyping(context: PolicyValidationContext, typing: PolicyTyping): void;
21
6
  export declare function contractOfNodeDefinition(ref: ClassRef): ObjectContract;