@astrale-os/kernel-dsl 1.0.0-beta.12 → 1.0.0-beta.14

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 (152) hide show
  1. package/dist/v1/addressing/definition-ref.js +21 -37
  2. package/dist/v1/addressing/key.js +2 -1
  3. package/dist/v1/addressing/ordering.d.ts +2 -0
  4. package/dist/v1/addressing/ordering.js +4 -0
  5. package/dist/v1/addressing/patterns.d.ts +1 -1
  6. package/dist/v1/addressing/patterns.js +2 -6
  7. package/dist/v1/builder/class/authoring.js +5 -28
  8. package/dist/v1/builder/class/property.d.ts +3 -9
  9. package/dist/v1/builder/class/property.js +1 -0
  10. package/dist/v1/builder/lowering/class.js +5 -1
  11. package/dist/v1/builder/lowering/policy.js +1 -0
  12. package/dist/v1/builder/lowering/schema/context.js +2 -4
  13. package/dist/v1/builder/lowering/value/path.js +2 -4
  14. package/dist/v1/builder/lowering/value/zod.js +1 -3
  15. package/dist/v1/builder/policy/authoring.js +3 -2
  16. package/dist/v1/builder/schema/define.d.ts +0 -1
  17. package/dist/v1/builder/schema/diagnostic.d.ts +2 -1
  18. package/dist/v1/builder/schema/diagnostic.js +5 -10
  19. package/dist/v1/builder/schema/projection.d.ts +1 -1
  20. package/dist/v1/builder/value/full-match.d.ts +0 -1
  21. package/dist/v1/builder/value/full-match.js +0 -1
  22. package/dist/v1/bundle/codec.js +4 -6
  23. package/dist/v1/bundle/diagnostic.d.ts +2 -0
  24. package/dist/v1/bundle/diagnostic.js +9 -7
  25. package/dist/v1/bundle/structure.js +4 -6
  26. package/dist/v1/compiled/admission/diagnostic.d.ts +1 -1
  27. package/dist/v1/compiled/admission/diagnostic.js +1 -3
  28. package/dist/v1/compiled/admission/revision.d.ts +9 -1
  29. package/dist/v1/compiled/admission/revision.js +6 -3
  30. package/dist/v1/compiled/admission/semantics/class.d.ts +4 -1
  31. package/dist/v1/compiled/admission/semantics/class.js +4 -8
  32. package/dist/v1/compiled/admission/semantics/core.d.ts +1 -24
  33. package/dist/v1/compiled/admission/semantics/core.js +54 -34
  34. package/dist/v1/compiled/admission/semantics/edge.d.ts +2 -4
  35. package/dist/v1/compiled/admission/semantics/edge.js +6 -65
  36. package/dist/v1/compiled/admission/semantics/policy/callable.js +0 -2
  37. package/dist/v1/compiled/admission/semantics/policy/contracts.d.ts +5 -20
  38. package/dist/v1/compiled/admission/semantics/policy/contracts.js +8 -21
  39. package/dist/v1/compiled/admission/semantics/policy/parity.js +13 -22
  40. package/dist/v1/compiled/admission/semantics/policy/pattern.d.ts +4 -1
  41. package/dist/v1/compiled/admission/semantics/policy/pattern.js +4 -16
  42. package/dist/v1/compiled/admission/semantics/policy/typing.d.ts +2 -24
  43. package/dist/v1/compiled/admission/semantics/policy/typing.js +19 -201
  44. package/dist/v1/compiled/compiler/compile.js +6 -8
  45. package/dist/v1/compiled/diagnostic.js +2 -3
  46. package/dist/v1/compiled/loader/load.d.ts +3 -2
  47. package/dist/v1/compiled/loader/load.js +10 -44
  48. package/dist/v1/domain/create.js +3 -5
  49. package/dist/v1/domain/namespace/member-collection.js +4 -6
  50. package/dist/v1/domain/validation/create.d.ts +4 -2
  51. package/dist/v1/domain/validation/create.js +21 -69
  52. package/dist/v1/language/.spec/schemas/value-schema.schema.json +22 -0
  53. package/dist/v1/language/class/inheritance.d.ts +18 -0
  54. package/dist/v1/language/class/inheritance.js +73 -0
  55. package/dist/v1/language/class/model/class.d.ts +4 -4
  56. package/dist/v1/language/class/model/edge.d.ts +2 -2
  57. package/dist/v1/language/class/model/property.d.ts +16 -7
  58. package/dist/v1/language/class/property-values.js +2 -4
  59. package/dist/v1/language/core/facts.d.ts +72 -0
  60. package/dist/v1/language/core/facts.js +95 -0
  61. package/dist/v1/language/definition/metadata.d.ts +5 -0
  62. package/dist/v1/language/definition/metadata.js +7 -0
  63. package/dist/v1/language/policy/analysis/branches.d.ts +8 -0
  64. package/dist/v1/language/policy/analysis/branches.js +2 -1
  65. package/dist/v1/language/policy/analysis/budgets.d.ts +13 -1
  66. package/dist/v1/language/policy/analysis/budgets.js +104 -0
  67. package/dist/v1/language/policy/analysis/typing.d.ts +48 -0
  68. package/dist/v1/language/policy/analysis/typing.js +338 -0
  69. package/dist/v1/language/policy/model/policy.d.ts +5 -5
  70. package/dist/v1/language/policy/normalization/normalize.js +17 -16
  71. package/dist/v1/language/validation/diagnostic.d.ts +15 -1
  72. package/dist/v1/language/validation/diagnostic.js +21 -0
  73. package/dist/v1/language/validation/rule.d.ts +26 -0
  74. package/dist/v1/language/validation/rule.js +116 -0
  75. package/dist/v1/language/value/compile/fields.js +4 -8
  76. package/dist/v1/language/value/profile/meta-schema.compiled.js +4 -1
  77. package/dist/v1/language/value/profile/rules.js +17 -43
  78. package/dist/v1/language/value/profile/validate.js +1 -10
  79. package/dist/v1/language/value/profile/vocabulary.d.ts +35 -2
  80. package/dist/v1/language/value/profile/vocabulary.js +52 -5
  81. package/dist/v1/language/value/reference/recursion.js +2 -22
  82. package/dist/v1/language/value/reference/registry.index.js +2 -1
  83. package/dist/v1/language/value/syntax/keywords.d.ts +3 -3
  84. package/dist/v1/language/value/syntax/keywords.js +4 -20
  85. package/dist/v1/language/value/syntax/node-path/validate.js +2 -3
  86. package/dist/v1/language/value/syntax/pointer.d.ts +2 -0
  87. package/dist/v1/language/value/syntax/pointer.js +5 -2
  88. package/dist/v1/language/value/syntax/walk.d.ts +2 -0
  89. package/dist/v1/language/value/syntax/walk.js +19 -20
  90. package/dist/v1/schema/.spec/schemas/domain-schema.schema.json +2336 -0
  91. package/dist/v1/schema/analysis/class.js +33 -15
  92. package/dist/v1/schema/compatibility/api.d.ts +1 -1
  93. package/dist/v1/schema/compatibility/coordinate.js +3 -3
  94. package/dist/v1/schema/compatibility/diff.js +2 -4
  95. package/dist/v1/schema/compatibility/meaning/footprint.js +16 -50
  96. package/dist/v1/schema/compatibility/model.d.ts +5 -0
  97. package/dist/v1/schema/compatibility/structure/requirements.js +26 -58
  98. package/dist/v1/schema/compatibility/walk.d.ts +17 -0
  99. package/dist/v1/schema/compatibility/walk.js +41 -0
  100. package/dist/v1/schema/diagnostic.d.ts +17 -3
  101. package/dist/v1/schema/diagnostic.js +14 -11
  102. package/dist/v1/schema/index.d.ts +3 -1
  103. package/dist/v1/schema/index.js +1 -0
  104. package/dist/v1/schema/model/schema.d.ts +19 -1
  105. package/dist/v1/schema/normalization/domain.js +1 -0
  106. package/dist/v1/schema/resolution/closure.js +2 -1
  107. package/dist/v1/schema/resolution/context.js +6 -6
  108. package/dist/v1/schema/rule.d.ts +29 -0
  109. package/dist/v1/schema/rule.js +415 -0
  110. package/dist/v1/schema/validation/callable.d.ts +4 -1
  111. package/dist/v1/schema/validation/callable.js +13 -6
  112. package/dist/v1/schema/validation/class.js +46 -96
  113. package/dist/v1/schema/validation/core.js +68 -202
  114. package/dist/v1/schema/validation/domain.js +1 -10
  115. package/dist/v1/schema/validation/domain.json-schema.d.ts +15 -0
  116. package/dist/v1/schema/validation/domain.json-schema.js +183 -0
  117. package/dist/v1/schema/validation/domain.structure.d.ts +4018 -0
  118. package/dist/v1/schema/validation/domain.structure.js +343 -155
  119. package/dist/v1/schema/validation/json.json-schema.d.ts +24 -0
  120. package/dist/v1/schema/validation/json.json-schema.js +36 -0
  121. package/dist/v1/schema/validation/policy/budgets.js +5 -112
  122. package/dist/v1/schema/validation/policy/context.d.ts +5 -3
  123. package/dist/v1/schema/validation/policy/context.js +5 -3
  124. package/dist/v1/schema/validation/policy/objects.d.ts +1 -1
  125. package/dist/v1/schema/validation/policy/objects.js +6 -14
  126. package/dist/v1/schema/validation/policy/references.js +10 -27
  127. package/dist/v1/schema/validation/policy/typing.d.ts +3 -18
  128. package/dist/v1/schema/validation/policy/typing.js +22 -356
  129. package/dist/v1/schema/validation/policy/uses.d.ts +1 -1
  130. package/dist/v1/schema/validation/policy/uses.js +9 -25
  131. package/dist/v1/schema/validation/policy/validate.js +3 -2
  132. package/dist/v1/schema/validation/value-api.d.ts +12 -1
  133. package/dist/v1/schema/validation/value-api.js +12 -3
  134. package/dist/v1/schema/validation/value.js +8 -10
  135. package/dist/v1/schema/validation/value.json-schema.d.ts +51 -0
  136. package/dist/v1/schema/validation/value.json-schema.js +126 -0
  137. package/dist/v1/schema/validation/view.js +4 -8
  138. package/package.json +3 -1
  139. package/dist/v1/compiled/admission/semantics/cardinality.d.ts +0 -5
  140. package/dist/v1/compiled/admission/semantics/cardinality.js +0 -128
  141. package/dist/v1/compiled/admission/semantics/policy/equality.d.ts +0 -8
  142. package/dist/v1/compiled/admission/semantics/policy/equality.js +0 -27
  143. package/dist/v1/compiled/admission/semantics/policy/measure.d.ts +0 -9
  144. package/dist/v1/compiled/admission/semantics/policy/measure.js +0 -81
  145. package/dist/v1/compiled/admission/semantics/policy/variants.d.ts +0 -10
  146. package/dist/v1/compiled/admission/semantics/policy/variants.js +0 -65
  147. package/dist/v1/language/class/index.d.ts +0 -8
  148. package/dist/v1/language/class/index.js +0 -1
  149. package/dist/v1/language/core/index.d.ts +0 -2
  150. package/dist/v1/language/core/index.js +0 -1
  151. package/dist/v1/language/value/index.d.ts +0 -11
  152. package/dist/v1/language/value/index.js +0 -8
@@ -0,0 +1,51 @@
1
+ import type { core as zodCore } from 'zod';
2
+ type JsonSchema = zodCore.JSONSchema.JSONSchema;
3
+ /**
4
+ * The checks on value schemas JSON Schema cannot state, which the published document names with
5
+ * the positions it constrains. The Kernel reports each as `DV_VALUE_SCHEMA`, with its value code.
6
+ */
7
+ export declare const valueSchemaRules: {
8
+ readonly 'value-blob': {
9
+ readonly code: 'DV_VALUE_SCHEMA';
10
+ readonly valueCode: 'VS_VALUE_KIND';
11
+ readonly statement: 'A blob is declared only by the whole schema of a Property, exactly as values.blob writes it.';
12
+ };
13
+ readonly 'value-path': {
14
+ readonly code: 'DV_VALUE_SCHEMA';
15
+ readonly valueCode: 'VS_PATH_EXTENSION';
16
+ readonly statement: 'x-astrale-path annotates only a direct Property of a callable input object, beside exactly the $ref of the graph NodePath schema, and reads target node, cardinality one and a non-empty set of Node Class refs it accepts.';
17
+ };
18
+ readonly 'value-recursion': {
19
+ readonly code: 'DV_VALUE_SCHEMA';
20
+ readonly valueCode: 'VS_RECURSION_PRODUCTIVE';
21
+ readonly statement: 'Every reference cycle of a value schema crosses a keyword that steps into the value: to a member, a member name or an item.';
22
+ };
23
+ readonly 'value-reference-form': {
24
+ readonly code: 'DV_VALUE_SCHEMA';
25
+ readonly valueCode: 'VS_REFERENCE_FORM';
26
+ readonly statement: 'A $ref is a JSON Pointer fragment into its own value schema, or the id of the graph NodePath schema beside x-astrale-path.';
27
+ };
28
+ readonly 'value-reference-resolution': {
29
+ readonly code: 'DV_VALUE_SCHEMA';
30
+ readonly valueCode: 'VS_REFERENCE_RESOLUTION';
31
+ readonly statement: 'A $ref resolves to a location of its own value schema, and x-astrale-path accepts Node Classes of the Domain or of a direct dependency.';
32
+ };
33
+ readonly 'value-regexp': {
34
+ readonly code: 'DV_VALUE_SCHEMA';
35
+ readonly valueCode: 'VS_REGEX_PORTABLE';
36
+ readonly statement: 'Every pattern, fullMatch and patternProperties name is an RFC 9485 I-Regexp within the regular-expression limits.';
37
+ };
38
+ };
39
+ export type ValueSchemaRule = keyof typeof valueSchemaRules;
40
+ /**
41
+ * The value language in JSON Schema, for the document that embeds value schemas: `root` constrains
42
+ * the `value-schema` definition with the published dialect and what the profile adds to it,
43
+ * `definitions` holds the locations it reaches, and `nodeProperty` constrains a Node Property
44
+ * definition. A named check leaves `x-astrale-rule` at the positions it constrains.
45
+ */
46
+ export declare function valueSchemaJsonSchema(): {
47
+ readonly root: readonly JsonSchema[];
48
+ readonly definitions: Readonly<Record<string, JsonSchema>>;
49
+ readonly nodeProperty: JsonSchema;
50
+ };
51
+ export {};
@@ -0,0 +1,126 @@
1
+ import { VALUE_SCHEMA_DIALECT } from '../../language/value/model/schema.js';
2
+ import { FORBIDDEN_KEYWORDS, SUBSCHEMA_KEYWORDS, VALUE_KEYWORDS, } from '../../language/value/profile/vocabulary.js';
3
+ /**
4
+ * The checks on value schemas JSON Schema cannot state, which the published document names with
5
+ * the positions it constrains. The Kernel reports each as `DV_VALUE_SCHEMA`, with its value code.
6
+ */
7
+ export const valueSchemaRules = {
8
+ 'value-blob': {
9
+ code: 'DV_VALUE_SCHEMA',
10
+ valueCode: 'VS_VALUE_KIND',
11
+ statement: 'A blob is declared only by the whole schema of a Property, exactly as values.blob writes it.',
12
+ },
13
+ 'value-path': {
14
+ code: 'DV_VALUE_SCHEMA',
15
+ valueCode: 'VS_PATH_EXTENSION',
16
+ statement: 'x-astrale-path annotates only a direct Property of a callable input object, beside exactly the $ref of the graph NodePath schema, and reads target node, cardinality one and a non-empty set of Node Class refs it accepts.',
17
+ },
18
+ 'value-recursion': {
19
+ code: 'DV_VALUE_SCHEMA',
20
+ valueCode: 'VS_RECURSION_PRODUCTIVE',
21
+ statement: 'Every reference cycle of a value schema crosses a keyword that steps into the value: to a member, a member name or an item.',
22
+ },
23
+ 'value-reference-form': {
24
+ code: 'DV_VALUE_SCHEMA',
25
+ valueCode: 'VS_REFERENCE_FORM',
26
+ statement: 'A $ref is a JSON Pointer fragment into its own value schema, or the id of the graph NodePath schema beside x-astrale-path.',
27
+ },
28
+ 'value-reference-resolution': {
29
+ code: 'DV_VALUE_SCHEMA',
30
+ valueCode: 'VS_REFERENCE_RESOLUTION',
31
+ statement: 'A $ref resolves to a location of its own value schema, and x-astrale-path accepts Node Classes of the Domain or of a direct dependency.',
32
+ },
33
+ 'value-regexp': {
34
+ code: 'DV_VALUE_SCHEMA',
35
+ valueCode: 'VS_REGEX_PORTABLE',
36
+ statement: 'Every pattern, fullMatch and patternProperties name is an RFC 9485 I-Regexp within the regular-expression limits.',
37
+ },
38
+ };
39
+ const KIND = 'x-astrale-value-kind';
40
+ const LOCATION = '#/$defs/value-location';
41
+ const SUBSCHEMA = '#/$defs/value-subschema';
42
+ /**
43
+ * The value language in JSON Schema, for the document that embeds value schemas: `root` constrains
44
+ * the `value-schema` definition with the published dialect and what the profile adds to it,
45
+ * `definitions` holds the locations it reaches, and `nodeProperty` constrains a Node Property
46
+ * definition. A named check leaves `x-astrale-rule` at the positions it constrains.
47
+ */
48
+ export function valueSchemaJsonSchema() {
49
+ return {
50
+ root: [
51
+ { $ref: VALUE_SCHEMA_DIALECT },
52
+ { $ref: LOCATION },
53
+ objectOrBoolean({
54
+ properties: {
55
+ $schema: { const: VALUE_SCHEMA_DIALECT },
56
+ [KIND]: {
57
+ enum: ['instant', 'blob'],
58
+ 'x-astrale-rule': 'value-blob',
59
+ },
60
+ },
61
+ }),
62
+ ],
63
+ definitions: {
64
+ // Every location, the root included: the closed vocabulary and the subschemas it holds.
65
+ 'value-location': objectOrBoolean({
66
+ propertyNames: {
67
+ enum: VALUE_KEYWORDS.filter((keyword) => !FORBIDDEN_KEYWORDS.includes(keyword)),
68
+ },
69
+ properties: {
70
+ $id: false,
71
+ $ref: {
72
+ type: 'string',
73
+ 'x-astrale-rule': [
74
+ 'value-recursion',
75
+ 'value-reference-form',
76
+ 'value-reference-resolution',
77
+ ],
78
+ },
79
+ enum: { type: 'array', uniqueItems: true },
80
+ fullMatch: { type: 'string', 'x-astrale-rule': 'value-regexp' },
81
+ pattern: { type: 'string', 'x-astrale-rule': 'value-regexp' },
82
+ 'x-astrale-path': { type: 'object', 'x-astrale-rule': 'value-path' },
83
+ ...Object.fromEntries(SUBSCHEMA_KEYWORDS.single.map((keyword) => [keyword, { $ref: SUBSCHEMA }])),
84
+ ...Object.fromEntries(SUBSCHEMA_KEYWORDS.array.map((keyword) => [
85
+ keyword,
86
+ { type: 'array', items: { $ref: SUBSCHEMA } },
87
+ ])),
88
+ ...Object.fromEntries(SUBSCHEMA_KEYWORDS.map.map((keyword) => [
89
+ keyword,
90
+ {
91
+ type: 'object',
92
+ additionalProperties: { $ref: SUBSCHEMA },
93
+ ...(keyword === 'patternProperties' ? { 'x-astrale-rule': 'value-regexp' } : {}),
94
+ },
95
+ ])),
96
+ },
97
+ // An instant is a string.
98
+ if: { required: [KIND], properties: { [KIND]: { const: 'instant' } } },
99
+ // oxlint-disable-next-line unicorn/no-thenable -- the JSON Schema keyword
100
+ then: { required: ['type'], properties: { type: { const: 'string' } } },
101
+ }),
102
+ // A location below the root: no $schema, and no blob.
103
+ 'value-subschema': {
104
+ allOf: [
105
+ { $ref: LOCATION },
106
+ objectOrBoolean({ properties: { $schema: false, [KIND]: { const: 'instant' } } }),
107
+ ],
108
+ },
109
+ },
110
+ // An automatic or State Property holds no blob.
111
+ nodeProperty: {
112
+ if: { anyOf: [{ required: ['auto'] }, { required: ['state'] }] },
113
+ // oxlint-disable-next-line unicorn/no-thenable -- the JSON Schema keyword
114
+ then: {
115
+ properties: {
116
+ schema: {
117
+ not: { type: 'object', required: [KIND], properties: { [KIND]: { const: 'blob' } } },
118
+ },
119
+ },
120
+ },
121
+ },
122
+ };
123
+ }
124
+ function objectOrBoolean(object) {
125
+ return { anyOf: [{ type: 'boolean' }, { type: 'object', ...object }] };
126
+ }
@@ -1,12 +1,14 @@
1
+ import { equalDefinitionRefs } from '../../addressing/definition-ref.js';
1
2
  import { Key } from '../../addressing/key.js';
3
+ import { escapePointerToken } from '../../language/value/syntax/pointer.js';
2
4
  import { diagnostic } from '../diagnostic.js';
3
5
  const formatDefinitionRef = Key.of;
4
6
  export function validateViews(environment) {
5
7
  const diagnostics = [];
6
8
  for (const [name, view] of Object.entries(environment.candidate.views)) {
7
- const pointer = `/views/${escapePointer(name)}`;
9
+ const pointer = `/views/${escapePointerToken(name)}`;
8
10
  const ref = { origin: environment.candidate.origin, kind: 'view', name };
9
- if (!sameRef(view.ref, ref)) {
11
+ if (!equalDefinitionRefs(view.ref, ref)) {
10
12
  diagnostics.push(diagnostic('DV_REF_RESOLVES', `${pointer}/ref`, `View ref must be exactly ${formatDefinitionRef(ref)}.`, formatDefinitionRef(view.ref)));
11
13
  }
12
14
  }
@@ -26,9 +28,3 @@ function validateEntrypoint(environment, diagnostics) {
26
28
  diagnostics.push(diagnostic('DV_ENTRYPOINT', '/entrypoint', `Entrypoint ${formatDefinitionRef(entrypoint)} is not a Domain-targeted View of ${origin}.`, formatDefinitionRef(entrypoint)));
27
29
  }
28
30
  }
29
- function sameRef(left, right) {
30
- return left.origin === right.origin && left.kind === right.kind && left.name === right.name;
31
- }
32
- function escapePointer(value) {
33
- return value.replaceAll('~', '~0').replaceAll('/', '~1');
34
- }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrale-os/kernel-dsl",
3
- "version": "1.0.0-beta.12",
3
+ "version": "1.0.0-beta.14",
4
4
  "description": "Astrale Kernel DSL - Schema authoring, inference, and IR serialization",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -79,6 +79,8 @@
79
79
  "types": "./dist/v1/schema/revision.d.ts",
80
80
  "import": "./dist/v1/schema/revision.js"
81
81
  },
82
+ "./v1/schema/domain-schema.schema.json": "./dist/v1/schema/.spec/schemas/domain-schema.schema.json",
83
+ "./v1/schema/value-schema.schema.json": "./dist/v1/language/.spec/schemas/value-schema.schema.json",
82
84
  "./v1/value/full-match": {
83
85
  "types": "./dist/v1/value/full-match.d.ts",
84
86
  "import": "./dist/v1/value/full-match.js"
@@ -1,5 +0,0 @@
1
- import { type CompiledSchemaEntry } from '../../model/schema.js';
2
- import { type SemanticIndex } from './context.js';
3
- import { type CoreNode, type CoreEdgeValue } from './core.js';
4
- /** Check normalized Edge identity, keys, noSelf, cycles and complete Core degrees. */
5
- export declare function validateCoreEdgeSet(context: SemanticIndex, entry: CompiledSchemaEntry, entryIndex: number, nodes: ReadonlyMap<string, CoreNode>, edges: readonly CoreEdgeValue[]): void;
@@ -1,128 +0,0 @@
1
- import { Key } from '../../../addressing/index.js';
2
- import { compareUnicode } from '../../../addressing/ordering.js';
3
- import {} from '../../../language/class/model/edge.js';
4
- import { coveringEdgeUniqueTuples, edgeUniqueKeys } from '../../../language/class/unique.js';
5
- import {} from '../../model/schema.js';
6
- import { fail } from '../diagnostic.js';
7
- import { isCompiledEdge, classSatisfiesAny, } from './context.js';
8
- import {} from './core.js';
9
- import { sameIncidentEndpoint, countBounds } from './edge.js';
10
- /** Check normalized Edge identity, keys, noSelf, cycles and complete Core degrees. */
11
- export function validateCoreEdgeSet(context, entry, entryIndex, nodes, edges) {
12
- const seen = new Set();
13
- const slices = new Map();
14
- for (const edge of edges) {
15
- const classKey = Key.of(edge.value.class);
16
- const [source, target] = edge.class.value.orientation === 'undirected' &&
17
- compareUnicode(edge.source.key, edge.target.key) > 0
18
- ? [edge.target.key, edge.source.key]
19
- : [edge.source.key, edge.target.key];
20
- const key = `${classKey}\u0000${source}\u0000${target}`;
21
- if (seen.has(key))
22
- fail(edge.pointer, 'Core Edge duplicates an exact normalized Edge identity.');
23
- seen.add(key);
24
- const values = slices.get(classKey) ?? [];
25
- values.push(edge);
26
- slices.set(classKey, values);
27
- if (edge.class.value.constraints.noSelf === true && edge.source.key === edge.target.key)
28
- fail(edge.pointer, 'Core Edge violates noSelf.');
29
- }
30
- // No two Core Edges hold one key under a tuple covering their Classes (DV-EDGE-UNIQUE).
31
- const resolve = (ref) => context.classes.get(Key.of(ref))?.value;
32
- const holders = new Set();
33
- for (const edge of edges) {
34
- const keys = edgeUniqueKeys(coveringEdgeUniqueTuples(edge.class.value, resolve), {
35
- source: edge.source.key,
36
- target: edge.target.key,
37
- props: edge.value.properties,
38
- });
39
- if (keys.some((key) => holders.has(key)))
40
- fail(edge.pointer, 'Core Edge holds a key another Core Edge holds.');
41
- for (const key of keys)
42
- holders.add(key);
43
- }
44
- for (const edgeClass of entry.definitions.classes) {
45
- if (!isCompiledEdge(edgeClass))
46
- continue;
47
- const classEdges = slices.get(Key.of(edgeClass.ref)) ?? [];
48
- if (edgeClass.constraints.acyclic === true && hasCycle(classEdges))
49
- fail(`/closure/${entryIndex}/facts/core`, 'Core Edge set violates exact-Class acyclicity.');
50
- validateCardinality(context, edgeClass, classEdges, nodes);
51
- }
52
- }
53
- function validateCardinality(context, declaration, edges, nodes) {
54
- for (const subject of cardinalitySubjects(edges, nodes)) {
55
- if (declaration.orientation === 'directed') {
56
- if (classSatisfiesAny(context, subject.class, declaration.endpoints.source.accepts))
57
- checkCount(declaration.endpoints.source.outgoing, edges.filter(({ source }) => source.key === subject.key).length, subject.pointer, subject.minimum);
58
- if (classSatisfiesAny(context, subject.class, declaration.endpoints.target.accepts))
59
- checkCount(declaration.endpoints.target.incoming, edges.filter(({ target }) => target.key === subject.key).length, subject.pointer, subject.minimum);
60
- }
61
- else {
62
- const degree = edges.filter(({ source, target }) => source.key === subject.key || target.key === subject.key).length;
63
- const [first, second] = declaration.endpoints;
64
- if (classSatisfiesAny(context, subject.class, first.accepts))
65
- checkCount(first.incident, degree, subject.pointer, subject.minimum);
66
- if (!sameIncidentEndpoint(first, second) &&
67
- classSatisfiesAny(context, subject.class, second.accepts))
68
- checkCount(second.incident, degree, subject.pointer, subject.minimum);
69
- }
70
- }
71
- }
72
- /**
73
- * Every declared Core Node proves its own complete degree, so both bounds hold. A Definition
74
- * endpoint is only named by the Edges that reach it: the Domain may also create ordinary Edges of
75
- * the same Class against it, so a minimum is unprovable here and only the maximum is enforced.
76
- */
77
- function cardinalitySubjects(edges, nodes) {
78
- const subjects = new Map();
79
- for (const node of nodes.values()) {
80
- subjects.set(node.key, {
81
- key: node.key,
82
- class: node.value.class,
83
- pointer: node.pointer,
84
- minimum: true,
85
- });
86
- }
87
- for (const edge of edges) {
88
- for (const endpoint of [edge.source, edge.target]) {
89
- if ('value' in endpoint || !('class' in endpoint) || subjects.has(endpoint.key))
90
- continue;
91
- subjects.set(endpoint.key, {
92
- key: endpoint.key,
93
- class: endpoint.class,
94
- pointer: endpoint.pointer,
95
- minimum: false,
96
- });
97
- }
98
- }
99
- return Object.freeze([...subjects.values()]);
100
- }
101
- function checkCount(count, degree, path, enforceMinimum) {
102
- const [minimum, maximum] = countBounds(count);
103
- if (degree > maximum || (degree < minimum && enforceMinimum))
104
- fail(path, `Core degree ${degree} violates Edge count ${count}.`);
105
- }
106
- function hasCycle(edges) {
107
- const outgoing = new Map();
108
- for (const edge of edges) {
109
- const values = outgoing.get(edge.source.key) ?? [];
110
- values.push(edge.target.key);
111
- outgoing.set(edge.source.key, values);
112
- }
113
- const visiting = new Set();
114
- const visited = new Set();
115
- const visit = (key) => {
116
- if (visiting.has(key))
117
- return true;
118
- if (visited.has(key))
119
- return false;
120
- visiting.add(key);
121
- if ((outgoing.get(key) ?? []).some(visit))
122
- return true;
123
- visiting.delete(key);
124
- visited.add(key);
125
- return false;
126
- };
127
- return [...outgoing.keys()].some(visit);
128
- }
@@ -1,8 +0,0 @@
1
- /** Retain and merge term equalities while typing one Policy branch. */
2
- export declare class CompiledUnionFind {
3
- #private;
4
- constructor(values: Iterable<string>);
5
- add(value: string): void;
6
- find(value: string): string;
7
- join(left: string, right: string): void;
8
- }
@@ -1,27 +0,0 @@
1
- /** Retain and merge term equalities while typing one Policy branch. */
2
- export class CompiledUnionFind {
3
- #parents = new Map();
4
- constructor(values) {
5
- for (const value of values)
6
- this.add(value);
7
- }
8
- add(value) {
9
- if (!this.#parents.has(value))
10
- this.#parents.set(value, value);
11
- }
12
- find(value) {
13
- this.add(value);
14
- const parent = this.#parents.get(value);
15
- if (parent === value)
16
- return value;
17
- const root = this.find(parent);
18
- this.#parents.set(value, root);
19
- return root;
20
- }
21
- join(left, right) {
22
- const a = this.find(left);
23
- const b = this.find(right);
24
- if (a !== b)
25
- this.#parents.set(b, a);
26
- }
27
- }
@@ -1,9 +0,0 @@
1
- import { type PolicyExpression } from '../../../../language/policy/model/policy.js';
2
- interface CompiledPatternMeasure {
3
- readonly depth: number;
4
- readonly edgeCounts: readonly number[];
5
- readonly domains: ReadonlySet<string>;
6
- }
7
- /** Measure expanded Policy branches, depth and referenced Domains. */
8
- export declare function measureCompiledPolicy(origin: string, name: string, normalized: ReadonlyMap<string, PolicyExpression>, visiting: Set<string>): CompiledPatternMeasure | undefined;
9
- export {};
@@ -1,81 +0,0 @@
1
- import { policyObjectOrigin, policyVariableClass } from '../../../../language/index.js';
2
- import { BRANCH_OVERFLOW } from '../../../../language/policy/analysis/budgets.js';
3
- import {} from '../../../../language/policy/model/policy.js';
4
- /** Measure expanded Policy branches, depth and referenced Domains. */
5
- export function measureCompiledPolicy(origin, name, normalized, visiting) {
6
- if (visiting.has(name))
7
- return undefined;
8
- const expression = normalized.get(name);
9
- if (expression === undefined)
10
- return undefined;
11
- if ('match' in expression)
12
- return measureCompiledPattern(expression.match, origin);
13
- const nested = new Set(visiting);
14
- nested.add(name);
15
- const refs = 'allOf' in expression ? expression.allOf : expression.anyOf;
16
- const children = refs.map((ref) => ref.origin === origin ? measureCompiledPolicy(origin, ref.name, normalized, nested) : undefined);
17
- if (children.some((value) => value === undefined))
18
- return undefined;
19
- return combineCompiledMeasures('allOf' in expression ? 'allOf' : 'anyOf', children);
20
- }
21
- function measureCompiledPattern(pattern, origin) {
22
- if ('sameNode' in pattern)
23
- return {
24
- depth: 1,
25
- edgeCounts: [1],
26
- domains: new Set([
27
- origin,
28
- ...[pattern.sameNode.left, pattern.sameNode.right].flatMap((term) => term.kind === 'ref' ? [policyObjectOrigin(term.ref)] : []),
29
- ]),
30
- };
31
- if ('source' in pattern)
32
- return {
33
- depth: 1,
34
- edgeCounts: [1],
35
- domains: new Set([
36
- origin,
37
- pattern.class.origin,
38
- ...[pattern.source, pattern.target].flatMap((term) => term.kind === 'ref' ? [policyObjectOrigin(term.ref)] : []),
39
- ]),
40
- };
41
- if ('exists' in pattern) {
42
- const child = measureCompiledPattern(pattern.exists.where, origin);
43
- return {
44
- depth: child.depth + 1,
45
- edgeCounts: child.edgeCounts,
46
- domains: new Set([
47
- ...child.domains,
48
- ...pattern.exists.nodes.flatMap((node) => {
49
- const ref = policyVariableClass(node);
50
- return ref === undefined ? [] : [ref.origin];
51
- }),
52
- ]),
53
- };
54
- }
55
- return combineCompiledMeasures('allOf' in pattern ? 'allOf' : 'anyOf', ('allOf' in pattern ? pattern.allOf : pattern.anyOf).map((child) => measureCompiledPattern(child, origin)));
56
- }
57
- function combineCompiledMeasures(kind, children) {
58
- const depth = 1 + Math.max(0, ...children.map((child) => child.depth));
59
- const domains = new Set(children.flatMap((child) => [...child.domains]));
60
- if (kind === 'anyOf')
61
- return {
62
- depth,
63
- edgeCounts: children.flatMap((child) => child.edgeCounts).slice(0, BRANCH_OVERFLOW),
64
- domains,
65
- };
66
- let edgeCounts = [0];
67
- for (const child of children) {
68
- const next = [];
69
- for (const left of edgeCounts) {
70
- for (const right of child.edgeCounts) {
71
- next.push(left + right);
72
- if (next.length >= BRANCH_OVERFLOW)
73
- break;
74
- }
75
- if (next.length >= BRANCH_OVERFLOW)
76
- break;
77
- }
78
- edgeCounts = next;
79
- }
80
- return { depth, edgeCounts, domains };
81
- }
@@ -1,10 +0,0 @@
1
- import type { CompiledPolicyTyping } from './typing.js';
2
- import { type ClassRef } from '../../../../addressing/index.js';
3
- import { type PatternEdgeUse } from '../../../../language/policy/analysis/branches.js';
4
- /** One possible combination of endpoint constraints and term equalities. */
5
- export interface CompiledEdgeVariant {
6
- readonly constraints: readonly (readonly [string, readonly ClassRef[]])[];
7
- readonly equalities: readonly (readonly [string, string])[];
8
- }
9
- /** Enumerate satisfiable endpoint variants for a branch’s Edge uses. */
10
- export declare function compiledEdgeAlternatives(edges: readonly PatternEdgeUse[], typing: CompiledPolicyTyping): readonly (readonly CompiledEdgeVariant[])[];
@@ -1,65 +0,0 @@
1
- import { Key } from '../../../../addressing/index.js';
2
- import { compareUnicode } from '../../../../addressing/ordering.js';
3
- import {} from '../../../../language/class/model/edge.js';
4
- import { termKey } from '../../../../language/policy/analysis/branches.js';
5
- import { isCompiledEdge } from '../context.js';
6
- /** Enumerate satisfiable endpoint variants for a branch’s Edge uses. */
7
- export function compiledEdgeAlternatives(edges, typing) {
8
- let result = [[]];
9
- for (const edge of edges) {
10
- const variants = compiledVariantsForEdge(edge, typing);
11
- if (variants.length === 0)
12
- return [];
13
- result = result.flatMap((prefix) => variants.map((variant) => [...prefix, variant]));
14
- }
15
- return result;
16
- }
17
- function compiledVariantsForEdge(use, typing) {
18
- const declaration = typing.context.classes.get(Key.of(use.pattern.class))?.value;
19
- if (declaration === undefined || !isCompiledEdge(declaration))
20
- return [];
21
- const endpoints = declaration.orientation === 'directed'
22
- ? [declaration.endpoints.source, declaration.endpoints.target]
23
- : declaration.endpoints;
24
- const repeat = use.pattern.repeat ?? { min: 1, max: 1 };
25
- const sourceKey = termKey(use.pattern.source, use.namespace);
26
- const targetKey = termKey(use.pattern.target, use.namespace);
27
- const variants = [];
28
- for (let length = repeat.min; length <= repeat.max; length++) {
29
- if (length === 0) {
30
- variants.push({ constraints: [], equalities: [[sourceKey, targetKey]] });
31
- continue;
32
- }
33
- const orientationCount = declaration.orientation === 'undirected' ? 2 ** length : 1;
34
- for (let mask = 0; mask < orientationCount; mask++) {
35
- const reversed = Array.from({ length }, (_, index) => declaration.orientation === 'undirected' && (mask & (1 << index)) !== 0);
36
- let valid = true;
37
- for (let index = 0; index + 1 < length; index++) {
38
- const incoming = reversed[index] ? endpoints[0] : endpoints[1];
39
- const outgoing = reversed[index + 1] ? endpoints[1] : endpoints[0];
40
- if (!typing.endpointsOverlap(incoming.accepts, outgoing.accepts))
41
- valid = false;
42
- }
43
- if (!valid)
44
- continue;
45
- const first = reversed[0] ? endpoints[1] : endpoints[0];
46
- const last = reversed[length - 1] ? endpoints[0] : endpoints[1];
47
- variants.push({
48
- constraints: [
49
- [sourceKey, first.accepts],
50
- [targetKey, last.accepts],
51
- ],
52
- equalities: [],
53
- });
54
- }
55
- }
56
- return uniqueCompiledEdgeVariants(variants);
57
- }
58
- function uniqueCompiledEdgeVariants(values) {
59
- const result = new Map();
60
- for (const value of values) {
61
- const key = `${value.constraints.map(([term, accepts]) => `${term}:${accepts.map(Key.of).sort(compareUnicode).join(',')}`).join('|')}=${value.equalities.map(([left, right]) => `${left}:${right}`).join('|')}`;
62
- result.set(key, value);
63
- }
64
- return [...result.values()];
65
- }
@@ -1,8 +0,0 @@
1
- export type * from './model/class.js';
2
- export type * from './model/data.js';
3
- export type * from './model/edge.js';
4
- export type * from './model/property.js';
5
- export { PropertyValues } from './property-values.js';
6
- export type { PropertyValuesOperations } from './property-values.js';
7
- export type * from './facets.js';
8
- export type * from './resolved.js';
@@ -1 +0,0 @@
1
- export { PropertyValues } from './property-values.js';
@@ -1,2 +0,0 @@
1
- export type * from './model/core.js';
2
- export type * from './resolved.js';
@@ -1 +0,0 @@
1
- export {};
@@ -1,11 +0,0 @@
1
- /** Complete V1 inline value language. Named Type Definitions do not exist. */
2
- export type { JsonSchema as ValueSchema, JsonSchemaObject as ValueSchemaObject, PathAnnotation, PropertyObjectSchema, ValueSchemaContext, } from './model/schema.js';
3
- export { JSON_SCHEMA_DIALECT, VALUE_SCHEMA_DIALECT, VALUE_SCHEMA_VOCABULARY, } from './model/schema.js';
4
- export { instant, isInstantValue } from './model/instant.js';
5
- export { classifyOrdering, classifyValueKind, type OrderingKind } from './ordering.js';
6
- export { canonicalizeValueSchema } from './profile/canonicalize.js';
7
- export { validateValueSchema } from './profile/validate.js';
8
- export { validateJsonInstance } from './evaluate/validate.js';
9
- export { prepareValueSchema, type InstanceSchemaCompilation } from './evaluate/preparation.js';
10
- export type { ValueProgram } from './compile/model.js';
11
- export type { ValueSchemaRegistry, ValueSchemaDomainRegistry } from './reference/registry.js';
@@ -1,8 +0,0 @@
1
- /** Complete V1 inline value language. Named Type Definitions do not exist. */
2
- export { JSON_SCHEMA_DIALECT, VALUE_SCHEMA_DIALECT, VALUE_SCHEMA_VOCABULARY, } from './model/schema.js';
3
- export { instant, isInstantValue } from './model/instant.js';
4
- export { classifyOrdering, classifyValueKind } from './ordering.js';
5
- export { canonicalizeValueSchema } from './profile/canonicalize.js';
6
- export { validateValueSchema } from './profile/validate.js';
7
- export { validateJsonInstance } from './evaluate/validate.js';
8
- export { prepareValueSchema } from './evaluate/preparation.js';