@astrale-os/kernel-dsl 1.0.0-beta.16 → 1.0.0-beta.17
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.
- package/dist/v1/builder/class/authoring.js +3 -2
- package/dist/v1/builder/class/input.d.ts +45 -14
- package/dist/v1/builder/index.d.ts +2 -1
- package/dist/v1/builder/lowering/class.d.ts +8 -0
- package/dist/v1/builder/lowering/class.js +40 -16
- package/dist/v1/builder/lowering/schema/compile.js +3 -3
- package/dist/v1/builder/policy/authoring.js +97 -88
- package/dist/v1/bundle/model.js +1 -1
- package/dist/v1/compiled/admission/accept.js +1 -7
- package/dist/v1/compiled/admission/semantics/class.js +2 -3
- package/dist/v1/compiled/admission/semantics/policy/parity.js +25 -13
- package/dist/v1/compiled/admission/wire/class.js +23 -18
- package/dist/v1/compiled/admission/wire/policy.d.ts +4 -3
- package/dist/v1/compiled/admission/wire/policy.js +8 -7
- package/dist/v1/compiled/loader/load.js +1 -1
- package/dist/v1/domain/create.js +1 -1
- package/dist/v1/domain/model/input.d.ts +2 -1
- package/dist/v1/domain/projection/classes.js +1 -1
- package/dist/v1/domain/validation/create.d.ts +2 -1
- package/dist/v1/domain/validation/create.js +1 -1
- package/dist/v1/index.d.ts +1 -1
- package/dist/v1/language/callable/resolved.d.ts +11 -2
- package/dist/v1/language/class/model/class.d.ts +17 -5
- package/dist/v1/language/freeze.d.ts +5 -0
- package/dist/v1/{schema/canonical → language}/freeze.js +4 -0
- package/dist/v1/language/policy/analysis/typing.d.ts +1 -0
- package/dist/v1/language/policy/analysis/typing.js +74 -79
- package/dist/v1/language/policy/model/policy.d.ts +44 -4
- package/dist/v1/language/policy/model/policy.js +14 -0
- package/dist/v1/language/policy/normalization/normalize.d.ts +6 -6
- package/dist/v1/language/policy/normalization/normalize.js +5 -5
- package/dist/v1/language/validation/rule.d.ts +18 -8
- package/dist/v1/language/validation/rule.js +2 -11
- package/dist/v1/language/value/evaluate/program.d.ts +2 -1
- package/dist/v1/language/value/evaluate/program.js +2 -2
- package/dist/v1/language/value/evaluate/validate.d.ts +2 -2
- package/dist/v1/language/value/evaluate/validate.js +2 -2
- package/dist/v1/language/value/profile/json.validate.d.ts +3 -1
- package/dist/v1/language/value/profile/json.validate.js +3 -2
- package/dist/v1/schema/.spec/schemas/domain-schema.schema.json +180 -25
- package/dist/v1/schema/admission/callable.js +1 -1
- package/dist/v1/schema/canonical/revision.js +4 -4
- package/dist/v1/schema/compatibility/comparators/callables.js +1 -1
- package/dist/v1/schema/compatibility/comparators/classes.js +4 -4
- package/dist/v1/schema/compatibility/comparators/members.js +1 -1
- package/dist/v1/schema/compatibility/comparators/values.js +2 -2
- package/dist/v1/schema/compatibility/report.js +1 -1
- package/dist/v1/schema/compatibility/versioning/index.js +1 -1
- package/dist/v1/schema/model/schema.js +1 -1
- package/dist/v1/schema/normalization/domain.js +9 -8
- package/dist/v1/schema/resolution/domain.js +1 -1
- package/dist/v1/schema/resolution/origins.js +3 -2
- package/dist/v1/schema/rule.d.ts +8 -20
- package/dist/v1/schema/rule.js +1 -1
- package/dist/v1/schema/validation/class.js +2 -3
- package/dist/v1/schema/validation/domain.json-schema.d.ts +2 -2
- package/dist/v1/schema/validation/domain.json-schema.js +20 -6
- package/dist/v1/schema/validation/domain.structure.d.ts +4765 -1005
- package/dist/v1/schema/validation/domain.structure.js +21 -9
- package/dist/v1/schema/validation/json.json-schema.d.ts +18 -2
- package/dist/v1/schema/validation/json.json-schema.js +14 -4
- package/dist/v1/schema/validation/policy/budgets.d.ts +1 -1
- package/dist/v1/schema/validation/policy/budgets.js +4 -4
- package/dist/v1/schema/validation/policy/uses.d.ts +10 -2
- package/dist/v1/schema/validation/policy/uses.js +26 -13
- package/dist/v1/schema/validation/policy/validate.js +2 -3
- package/dist/v1/schema/validation/value.json-schema.d.ts +4 -6
- package/dist/v1/schema/validation/value.json-schema.js +18 -25
- package/package.json +1 -1
- package/dist/v1/schema/canonical/domain.d.ts +0 -3
- package/dist/v1/schema/canonical/domain.digest.d.ts +0 -3
- package/dist/v1/schema/canonical/domain.digest.js +0 -5
- package/dist/v1/schema/canonical/domain.js +0 -5
- package/dist/v1/schema/canonical/freeze.d.ts +0 -1
|
@@ -33,6 +33,20 @@ export function projectedMemberClass(ref) {
|
|
|
33
33
|
function kernelClassRef(name) {
|
|
34
34
|
return Object.freeze({ origin: 'kernel.astrale.ai', kind: 'class', name });
|
|
35
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* Every Class slot: the observations, which admit every caller when absent, then the writes, which
|
|
38
|
+
* admit only the Domain that declares the Class when absent.
|
|
39
|
+
*/
|
|
40
|
+
export const CLASS_OPERATIONS = Object.freeze([
|
|
41
|
+
'read',
|
|
42
|
+
'traverse',
|
|
43
|
+
'create',
|
|
44
|
+
'update',
|
|
45
|
+
'delete',
|
|
46
|
+
]);
|
|
47
|
+
export function isClassObservation(operation) {
|
|
48
|
+
return operation === 'read' || operation === 'traverse';
|
|
49
|
+
}
|
|
36
50
|
export function isClassRuleChecks(value) {
|
|
37
51
|
return (typeof value === 'object' &&
|
|
38
52
|
('check' in value || 'sameNode' in value || 'allOf' in value || 'anyOf' in value));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ClassSlotPolicy, PolicyCheckExpression, PolicyExpression, PolicyPatternExpression } from '../model/policy.js';
|
|
2
2
|
export declare function normalizePolicyExpression(value: PolicyExpression): PolicyExpression;
|
|
3
3
|
/**
|
|
4
4
|
* The fixed point of the single pass: a Pattern the single pass reproduces is returned unchanged,
|
|
@@ -6,10 +6,10 @@ export declare function normalizePolicyExpression(value: PolicyExpression): Poli
|
|
|
6
6
|
*/
|
|
7
7
|
export declare function normalizePolicyPattern(value: PolicyPatternExpression): PolicyPatternExpression;
|
|
8
8
|
/**
|
|
9
|
-
* The one spelling of a
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
9
|
+
* The one spelling of a Class rule: normalized Policy checks without a composition of one operand,
|
|
10
|
+
* or the Policy that a lone check of `self` names, which is how a Class has always declared one.
|
|
11
|
+
* Callable checks keep their compositions of one operand: their revisions predate this rule. A
|
|
12
|
+
* create rule checks no `self`, so it keeps its checks.
|
|
13
13
|
*/
|
|
14
|
-
export declare function normalizeClassRule(value:
|
|
14
|
+
export declare function normalizeClassRule<Slot extends ClassSlotPolicy>(value: Slot): Slot;
|
|
15
15
|
export declare function normalizePolicyChecks(value: PolicyCheckExpression): PolicyCheckExpression;
|
|
@@ -40,16 +40,16 @@ function normalizePatternOnce(value) {
|
|
|
40
40
|
return normalizePatternNode(rewritten);
|
|
41
41
|
}
|
|
42
42
|
/**
|
|
43
|
-
* The one spelling of a
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
43
|
+
* The one spelling of a Class rule: normalized Policy checks without a composition of one operand,
|
|
44
|
+
* or the Policy that a lone check of `self` names, which is how a Class has always declared one.
|
|
45
|
+
* Callable checks keep their compositions of one operand: their revisions predate this rule. A
|
|
46
|
+
* create rule checks no `self`, so it keeps its checks.
|
|
47
47
|
*/
|
|
48
48
|
export function normalizeClassRule(value) {
|
|
49
49
|
if (!isClassRuleChecks(value))
|
|
50
50
|
return value;
|
|
51
51
|
const checks = unwrapSingleOperands(normalizePolicyChecks(value));
|
|
52
|
-
return 'check' in checks && checks.object.kind === 'self' ? checks.check : checks;
|
|
52
|
+
return ('check' in checks && checks.object.kind === 'self' ? checks.check : checks);
|
|
53
53
|
}
|
|
54
54
|
/** Replace each composition of one operand by that operand, merging what it then nests. */
|
|
55
55
|
function unwrapSingleOperands(value) {
|
|
@@ -8,13 +8,15 @@ import type { DiagnosticCode } from './diagnostic.js';
|
|
|
8
8
|
* `warning`: a value schema, which the rule reports without refusing it.
|
|
9
9
|
*/
|
|
10
10
|
export type ValueRuleStage = 'schema' | 'context' | 'value' | 'warning';
|
|
11
|
-
/**
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
/**
|
|
12
|
+
* The rule one diagnostic code reports, whatever it checks: what `schema.RULES` and `VALUE_RULES`
|
|
13
|
+
* say of every code, each with the stages of its own checks.
|
|
14
|
+
*/
|
|
15
|
+
export interface DiagnosticRule {
|
|
14
16
|
/**
|
|
15
|
-
* The positions the rule constrains, which its diagnostics point at
|
|
16
|
-
*
|
|
17
|
-
*
|
|
17
|
+
* The positions the rule constrains, which its diagnostics point at: JSON Pointer templates in
|
|
18
|
+
* which a `{name}` token stands for one token of the kind it names and `{/path*}` for any number
|
|
19
|
+
* of tokens.
|
|
18
20
|
*/
|
|
19
21
|
readonly positions: readonly [string, ...string[]];
|
|
20
22
|
/** The rule, in one plain sentence. */
|
|
@@ -23,11 +25,19 @@ export interface ValueRule {
|
|
|
23
25
|
readonly limits?: readonly [LimitKey, ...LimitKey[]];
|
|
24
26
|
/**
|
|
25
27
|
* The conditions of the published JSON Schema of the document that state the rule, where some
|
|
26
|
-
* do: the URI fragment of each `if` or `not` subschema whose failure refuses
|
|
27
|
-
*
|
|
28
|
+
* do: the URI fragment of each `if` or `not` subschema whose failure refuses the document with
|
|
29
|
+
* this rule's code.
|
|
28
30
|
*/
|
|
29
31
|
readonly conditions?: readonly [string, ...string[]];
|
|
30
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* The rule one value diagnostic code reports. Its positions are relative to the value schema, the
|
|
35
|
+
* value or the Domain input it checks. A condition refuses a value schema of the document with
|
|
36
|
+
* `DV_VALUE_SCHEMA` and this rule's code as its `valueCode`.
|
|
37
|
+
*/
|
|
38
|
+
export interface ValueRule extends DiagnosticRule {
|
|
39
|
+
readonly stage: ValueRuleStage;
|
|
40
|
+
}
|
|
31
41
|
/**
|
|
32
42
|
* Every value diagnostic code with the rule it reports. A code added to the language does not
|
|
33
43
|
* compile until it is described here.
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { deepFreeze } from '../freeze.js';
|
|
1
2
|
/**
|
|
2
3
|
* Every value diagnostic code with the rule it reports. A code added to the language does not
|
|
3
4
|
* compile until it is described here.
|
|
4
5
|
*/
|
|
5
|
-
export const VALUE_RULES =
|
|
6
|
+
export const VALUE_RULES = deepFreeze({
|
|
6
7
|
CALLABLE_INPUT_FIELD_UNKNOWN: {
|
|
7
8
|
stage: 'value',
|
|
8
9
|
positions: [''],
|
|
@@ -106,13 +107,3 @@ export const VALUE_RULES = frozen({
|
|
|
106
107
|
statement: 'A Property of value kind json is filtered by equality only, so its author is warned.',
|
|
107
108
|
},
|
|
108
109
|
});
|
|
109
|
-
function frozen(rules) {
|
|
110
|
-
for (const rule of Object.values(rules)) {
|
|
111
|
-
Object.freeze(Object.freeze(rule).positions);
|
|
112
|
-
if (rule.limits !== undefined)
|
|
113
|
-
Object.freeze(rule.limits);
|
|
114
|
-
if (rule.conditions !== undefined)
|
|
115
|
-
Object.freeze(rule.conditions);
|
|
116
|
-
}
|
|
117
|
-
return Object.freeze(rules);
|
|
118
|
-
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Options } from '@astrale-os/kernel-dsl/value';
|
|
1
2
|
import type { Diagnostic } from '../../validation/diagnostic.js';
|
|
2
3
|
import type { ValueProgram } from '../compile/model.js';
|
|
3
|
-
export declare function validateValueProgram(program: ValueProgram, input: unknown, roots?: readonly number[]): readonly Diagnostic[];
|
|
4
|
+
export declare function validateValueProgram(program: ValueProgram, input: unknown, roots?: readonly number[], options?: Options): readonly Diagnostic[];
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { loadValueProgram } from '../compile/load.js';
|
|
2
2
|
import { validateCanonicalJsonDomain } from '../profile/json.validate.js';
|
|
3
3
|
import { evaluateInstance } from './evaluator.js';
|
|
4
|
-
export function validateValueProgram(program, input, roots = [program.root]) {
|
|
5
|
-
const canonical = validateCanonicalJsonDomain(input, '');
|
|
4
|
+
export function validateValueProgram(program, input, roots = [program.root], options) {
|
|
5
|
+
const canonical = validateCanonicalJsonDomain(input, '', options);
|
|
6
6
|
if (canonical.length > 0)
|
|
7
7
|
return canonical;
|
|
8
8
|
return roots.flatMap((root) => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Value as JsonValue } from '@astrale-os/kernel-dsl/value';
|
|
1
|
+
import type { Value as JsonValue, Options } from '@astrale-os/kernel-dsl/value';
|
|
2
2
|
import type { Diagnostic } from '../../validation/diagnostic.js';
|
|
3
3
|
import type { JsonSchema } from '../model/schema.js';
|
|
4
4
|
import type { ValueSchemaRegistry } from '../reference/registry.js';
|
|
@@ -13,4 +13,4 @@ import { type PatternPool } from './preparation.js';
|
|
|
13
13
|
*/
|
|
14
14
|
export declare function validateJsonInstance(schema: JsonSchema, value: JsonValue, registry: ValueSchemaRegistry, pointer?: string, patterns?: PatternPool): Diagnostic[];
|
|
15
15
|
/** Validate with the exact preparation already retained by a source-resolved Property or Callable. */
|
|
16
|
-
export declare function validatePreparedInstance(compiled: CompiledInstanceSchema, value: unknown): Diagnostic[];
|
|
16
|
+
export declare function validatePreparedInstance(compiled: CompiledInstanceSchema, value: unknown, options?: Options): Diagnostic[];
|
|
@@ -24,8 +24,8 @@ export function validateJsonInstance(schema, value, registry, pointer = '', patt
|
|
|
24
24
|
return instanceDiagnostics(prepared.value, value, pointer);
|
|
25
25
|
}
|
|
26
26
|
/** Validate with the exact preparation already retained by a source-resolved Property or Callable. */
|
|
27
|
-
export function validatePreparedInstance(compiled, value) {
|
|
28
|
-
const diagnostics = [...validateCanonicalJsonDomain(value, '')];
|
|
27
|
+
export function validatePreparedInstance(compiled, value, options) {
|
|
28
|
+
const diagnostics = [...validateCanonicalJsonDomain(value, '', options)];
|
|
29
29
|
return diagnostics.length > 0
|
|
30
30
|
? diagnostics
|
|
31
31
|
: instanceDiagnostics(compiled, value, '');
|
|
@@ -1,2 +1,4 @@
|
|
|
1
|
+
import { type Options } from '@astrale-os/kernel-dsl/value';
|
|
1
2
|
import type { Diagnostic } from '../../validation/diagnostic.js';
|
|
2
|
-
|
|
3
|
+
/** Whether `value` is a portable JSON Value, within the portable limits `options` overrides. */
|
|
4
|
+
export declare function validateCanonicalJsonDomain(value: unknown, pointer: string, options?: Options): readonly Diagnostic[];
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { acceptForRead as acceptJsonValue, BoundaryError as JsonBoundaryError, } from '@astrale-os/kernel-dsl/value';
|
|
2
2
|
import { diagnostic } from '../../validation/diagnostic.js';
|
|
3
|
-
|
|
3
|
+
/** Whether `value` is a portable JSON Value, within the portable limits `options` overrides. */
|
|
4
|
+
export function validateCanonicalJsonDomain(value, pointer, options) {
|
|
4
5
|
try {
|
|
5
|
-
acceptJsonValue(value);
|
|
6
|
+
acceptJsonValue(value, options);
|
|
6
7
|
return [];
|
|
7
8
|
}
|
|
8
9
|
catch (error) {
|
|
@@ -323,17 +323,6 @@
|
|
|
323
323
|
}
|
|
324
324
|
]
|
|
325
325
|
},
|
|
326
|
-
"class-policy": {
|
|
327
|
-
"anyOf": [
|
|
328
|
-
{
|
|
329
|
-
"type": "boolean",
|
|
330
|
-
"const": false
|
|
331
|
-
},
|
|
332
|
-
{
|
|
333
|
-
"$ref": "#/$defs/policy-ref"
|
|
334
|
-
}
|
|
335
|
-
]
|
|
336
|
-
},
|
|
337
326
|
"class-ref": {
|
|
338
327
|
"type": "object",
|
|
339
328
|
"properties": {
|
|
@@ -587,6 +576,136 @@
|
|
|
587
576
|
"maxLength": 100,
|
|
588
577
|
"pattern": "^(?=.{1,100}$)[a-z][a-z0-9-]*(?:\\.[a-z][a-z0-9-]*)*$"
|
|
589
578
|
},
|
|
579
|
+
"create-policy": {
|
|
580
|
+
"anyOf": [
|
|
581
|
+
{
|
|
582
|
+
"type": "boolean",
|
|
583
|
+
"const": true
|
|
584
|
+
},
|
|
585
|
+
{
|
|
586
|
+
"$ref": "#/$defs/create-rule-check-expr"
|
|
587
|
+
}
|
|
588
|
+
]
|
|
589
|
+
},
|
|
590
|
+
"create-rule-check-expr": {
|
|
591
|
+
"anyOf": [
|
|
592
|
+
{
|
|
593
|
+
"type": "object",
|
|
594
|
+
"properties": {
|
|
595
|
+
"sameNode": {
|
|
596
|
+
"type": "object",
|
|
597
|
+
"properties": {
|
|
598
|
+
"left": {
|
|
599
|
+
"type": "object",
|
|
600
|
+
"properties": {
|
|
601
|
+
"kind": {
|
|
602
|
+
"type": "string",
|
|
603
|
+
"const": "ref"
|
|
604
|
+
},
|
|
605
|
+
"ref": {
|
|
606
|
+
"$ref": "#/$defs/projected-member-ref"
|
|
607
|
+
}
|
|
608
|
+
},
|
|
609
|
+
"required": [
|
|
610
|
+
"kind",
|
|
611
|
+
"ref"
|
|
612
|
+
],
|
|
613
|
+
"additionalProperties": false
|
|
614
|
+
},
|
|
615
|
+
"right": {
|
|
616
|
+
"type": "object",
|
|
617
|
+
"properties": {
|
|
618
|
+
"kind": {
|
|
619
|
+
"type": "string",
|
|
620
|
+
"const": "ref"
|
|
621
|
+
},
|
|
622
|
+
"ref": {
|
|
623
|
+
"$ref": "#/$defs/projected-member-ref"
|
|
624
|
+
}
|
|
625
|
+
},
|
|
626
|
+
"required": [
|
|
627
|
+
"kind",
|
|
628
|
+
"ref"
|
|
629
|
+
],
|
|
630
|
+
"additionalProperties": false
|
|
631
|
+
}
|
|
632
|
+
},
|
|
633
|
+
"required": [
|
|
634
|
+
"left",
|
|
635
|
+
"right"
|
|
636
|
+
],
|
|
637
|
+
"additionalProperties": false
|
|
638
|
+
}
|
|
639
|
+
},
|
|
640
|
+
"required": [
|
|
641
|
+
"sameNode"
|
|
642
|
+
],
|
|
643
|
+
"additionalProperties": false
|
|
644
|
+
},
|
|
645
|
+
{
|
|
646
|
+
"type": "object",
|
|
647
|
+
"properties": {
|
|
648
|
+
"check": {
|
|
649
|
+
"$ref": "#/$defs/policy-ref"
|
|
650
|
+
},
|
|
651
|
+
"object": {
|
|
652
|
+
"type": "object",
|
|
653
|
+
"properties": {
|
|
654
|
+
"kind": {
|
|
655
|
+
"type": "string",
|
|
656
|
+
"const": "ref"
|
|
657
|
+
},
|
|
658
|
+
"ref": {
|
|
659
|
+
"$ref": "#/$defs/projected-member-ref"
|
|
660
|
+
}
|
|
661
|
+
},
|
|
662
|
+
"required": [
|
|
663
|
+
"kind",
|
|
664
|
+
"ref"
|
|
665
|
+
],
|
|
666
|
+
"additionalProperties": false
|
|
667
|
+
}
|
|
668
|
+
},
|
|
669
|
+
"required": [
|
|
670
|
+
"check",
|
|
671
|
+
"object"
|
|
672
|
+
],
|
|
673
|
+
"additionalProperties": false
|
|
674
|
+
},
|
|
675
|
+
{
|
|
676
|
+
"type": "object",
|
|
677
|
+
"properties": {
|
|
678
|
+
"allOf": {
|
|
679
|
+
"minItems": 1,
|
|
680
|
+
"type": "array",
|
|
681
|
+
"items": {
|
|
682
|
+
"$ref": "#/$defs/create-rule-check-expr"
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
},
|
|
686
|
+
"required": [
|
|
687
|
+
"allOf"
|
|
688
|
+
],
|
|
689
|
+
"additionalProperties": false
|
|
690
|
+
},
|
|
691
|
+
{
|
|
692
|
+
"type": "object",
|
|
693
|
+
"properties": {
|
|
694
|
+
"anyOf": {
|
|
695
|
+
"minItems": 1,
|
|
696
|
+
"type": "array",
|
|
697
|
+
"items": {
|
|
698
|
+
"$ref": "#/$defs/create-rule-check-expr"
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
},
|
|
702
|
+
"required": [
|
|
703
|
+
"anyOf"
|
|
704
|
+
],
|
|
705
|
+
"additionalProperties": false
|
|
706
|
+
}
|
|
707
|
+
]
|
|
708
|
+
},
|
|
590
709
|
"dependency": {
|
|
591
710
|
"type": "object",
|
|
592
711
|
"properties": {
|
|
@@ -780,10 +899,19 @@
|
|
|
780
899
|
"type": "object",
|
|
781
900
|
"properties": {
|
|
782
901
|
"read": {
|
|
783
|
-
"$ref": "#/$defs/
|
|
902
|
+
"$ref": "#/$defs/observation-policy"
|
|
784
903
|
},
|
|
785
904
|
"traverse": {
|
|
786
|
-
"$ref": "#/$defs/
|
|
905
|
+
"$ref": "#/$defs/observation-policy"
|
|
906
|
+
},
|
|
907
|
+
"create": {
|
|
908
|
+
"$ref": "#/$defs/write-policy"
|
|
909
|
+
},
|
|
910
|
+
"update": {
|
|
911
|
+
"$ref": "#/$defs/write-policy"
|
|
912
|
+
},
|
|
913
|
+
"delete": {
|
|
914
|
+
"$ref": "#/$defs/write-policy"
|
|
787
915
|
}
|
|
788
916
|
},
|
|
789
917
|
"additionalProperties": false
|
|
@@ -1260,10 +1388,19 @@
|
|
|
1260
1388
|
"type": "object",
|
|
1261
1389
|
"properties": {
|
|
1262
1390
|
"read": {
|
|
1263
|
-
"$ref": "#/$defs/
|
|
1391
|
+
"$ref": "#/$defs/observation-policy"
|
|
1264
1392
|
},
|
|
1265
1393
|
"traverse": {
|
|
1266
|
-
"$ref": "#/$defs/
|
|
1394
|
+
"$ref": "#/$defs/observation-policy"
|
|
1395
|
+
},
|
|
1396
|
+
"create": {
|
|
1397
|
+
"$ref": "#/$defs/create-policy"
|
|
1398
|
+
},
|
|
1399
|
+
"update": {
|
|
1400
|
+
"$ref": "#/$defs/write-policy"
|
|
1401
|
+
},
|
|
1402
|
+
"delete": {
|
|
1403
|
+
"$ref": "#/$defs/write-policy"
|
|
1267
1404
|
}
|
|
1268
1405
|
},
|
|
1269
1406
|
"additionalProperties": false
|
|
@@ -1293,16 +1430,6 @@
|
|
|
1293
1430
|
],
|
|
1294
1431
|
"additionalProperties": false
|
|
1295
1432
|
},
|
|
1296
|
-
"node-class-policy": {
|
|
1297
|
-
"anyOf": [
|
|
1298
|
-
{
|
|
1299
|
-
"$ref": "#/$defs/class-policy"
|
|
1300
|
-
},
|
|
1301
|
-
{
|
|
1302
|
-
"$ref": "#/$defs/class-rule-check-expr"
|
|
1303
|
-
}
|
|
1304
|
-
]
|
|
1305
|
-
},
|
|
1306
1433
|
"node-property-definition": {
|
|
1307
1434
|
"type": "object",
|
|
1308
1435
|
"properties": {
|
|
@@ -1379,6 +1506,20 @@
|
|
|
1379
1506
|
"$ref": "#/$defs/node-property-definition"
|
|
1380
1507
|
}
|
|
1381
1508
|
},
|
|
1509
|
+
"observation-policy": {
|
|
1510
|
+
"anyOf": [
|
|
1511
|
+
{
|
|
1512
|
+
"type": "boolean",
|
|
1513
|
+
"const": false
|
|
1514
|
+
},
|
|
1515
|
+
{
|
|
1516
|
+
"$ref": "#/$defs/policy-ref"
|
|
1517
|
+
},
|
|
1518
|
+
{
|
|
1519
|
+
"$ref": "#/$defs/class-rule-check-expr"
|
|
1520
|
+
}
|
|
1521
|
+
]
|
|
1522
|
+
},
|
|
1382
1523
|
"origin": {
|
|
1383
1524
|
"type": "string",
|
|
1384
1525
|
"minLength": 3,
|
|
@@ -2359,6 +2500,20 @@
|
|
|
2359
2500
|
],
|
|
2360
2501
|
"additionalProperties": false,
|
|
2361
2502
|
"description": "Every View targets its owning Domain."
|
|
2503
|
+
},
|
|
2504
|
+
"write-policy": {
|
|
2505
|
+
"anyOf": [
|
|
2506
|
+
{
|
|
2507
|
+
"type": "boolean",
|
|
2508
|
+
"const": true
|
|
2509
|
+
},
|
|
2510
|
+
{
|
|
2511
|
+
"$ref": "#/$defs/policy-ref"
|
|
2512
|
+
},
|
|
2513
|
+
{
|
|
2514
|
+
"$ref": "#/$defs/class-rule-check-expr"
|
|
2515
|
+
}
|
|
2516
|
+
]
|
|
2362
2517
|
}
|
|
2363
2518
|
}
|
|
2364
2519
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { accept as acceptJsonValue, BoundaryError as JsonBoundaryError, } from '@astrale-os/kernel-dsl/value';
|
|
2
2
|
import { definitionRefIndex } from '../../addressing/ordering.js';
|
|
3
3
|
import { isBinaryInput } from '../../language/callable/model/callable.js';
|
|
4
|
+
import { deepFreeze } from '../../language/freeze.js';
|
|
4
5
|
import { measureChecks } from '../../language/policy/analysis/budgets.js';
|
|
5
6
|
import { PolicyTyping } from '../../language/policy/analysis/typing.js';
|
|
6
7
|
import { normalizePolicyChecks } from '../../language/policy/normalization/normalize.js';
|
|
7
8
|
import {} from '../../language/value/evaluate/preparation.js';
|
|
8
9
|
import { analyzeDefinitions } from '../analysis/class.js';
|
|
9
|
-
import { deepFreeze } from '../canonical/freeze.js';
|
|
10
10
|
import { SchemaError, diagnostic } from '../diagnostic.js';
|
|
11
11
|
import { canonicalizeCallable } from '../normalization/domain.js';
|
|
12
12
|
import { lookupForDomainClosure } from '../resolution/closure.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { json } from '@astrale-os/kernel-dsl/value';
|
|
2
|
+
import { digestRevisionBytes } from '../../addressing/revision.js';
|
|
2
3
|
import { asDomainSchema } from '../model/schema.js';
|
|
3
|
-
import {
|
|
4
|
-
import { canonicalizeDomainSchema } from './domain.js';
|
|
4
|
+
import { normalizeDomainSchema } from '../normalization/domain.js';
|
|
5
5
|
// Only canonical schemas created here own a retained revision, never caller-owned input.
|
|
6
6
|
const revisions = new WeakMap();
|
|
7
7
|
export function canonicalDomainSchema(value) {
|
|
@@ -9,9 +9,9 @@ export function canonicalDomainSchema(value) {
|
|
|
9
9
|
}
|
|
10
10
|
/** Internal acceptance seam. The caller must establish whole-Domain validity first. */
|
|
11
11
|
export function canonicalDomainSchemaAfterValidation(value) {
|
|
12
|
-
const schema = asDomainSchema(
|
|
12
|
+
const schema = asDomainSchema(normalizeDomainSchema(value));
|
|
13
13
|
const bytes = json.encode(schema);
|
|
14
|
-
const revision =
|
|
14
|
+
const revision = digestRevisionBytes(bytes);
|
|
15
15
|
revisions.set(schema, revision);
|
|
16
16
|
return Object.freeze({ schema, bytes, revision });
|
|
17
17
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isMethodExecutable } from '../../../language/callable/executable.js';
|
|
2
2
|
import { isBinaryInput } from '../../../language/callable/model/callable.js';
|
|
3
|
+
import { deepFreeze } from '../../../language/freeze.js';
|
|
3
4
|
import { methodSignature as inheritedSignature } from '../../analysis/class.js';
|
|
4
|
-
import { deepFreeze } from '../../canonical/freeze.js';
|
|
5
5
|
import { keyForDefinitionRef } from '../coordinate.js';
|
|
6
6
|
import { CALLABLE_FIELDS, fieldsOf } from '../fields.js';
|
|
7
7
|
import { fingerprintMeaning, semanticValueSchema } from './values.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { compareUnicode } from '../../../addressing/ordering.js';
|
|
2
2
|
import { compareEdgeUniqueTuples, coveringEdgeUniqueTuples, } from '../../../language/class/unique.js';
|
|
3
|
+
import { deepFreeze } from '../../../language/freeze.js';
|
|
3
4
|
import { isClassRuleChecks } from '../../../language/policy/model/policy.js';
|
|
4
|
-
import { deepFreeze } from '../../canonical/freeze.js';
|
|
5
5
|
import { effectiveDefinition } from '../context.js';
|
|
6
6
|
import { propertyCoordinate } from '../coordinate.js';
|
|
7
7
|
import { keyForDefinitionRef } from '../coordinate.js';
|
|
@@ -56,12 +56,12 @@ export function classMeaning(context, coordinate, level, onto) {
|
|
|
56
56
|
return { meaning: deepFreeze(meaning), requirement };
|
|
57
57
|
}
|
|
58
58
|
/**
|
|
59
|
-
* A named Policy compares by its key;
|
|
59
|
+
* A named Policy compares by its key; a constant or Policy checks by their value, as a callable's
|
|
60
60
|
* Policy does.
|
|
61
61
|
*/
|
|
62
62
|
function classPolicyMeaning(policy) {
|
|
63
|
-
if (policy ===
|
|
64
|
-
return
|
|
63
|
+
if (typeof policy === 'boolean')
|
|
64
|
+
return policy;
|
|
65
65
|
return isClassRuleChecks(policy) ? policy : keyForDefinitionRef(policy);
|
|
66
66
|
}
|
|
67
67
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { deepFreeze } from '
|
|
1
|
+
import { deepFreeze } from '../../../language/freeze.js';
|
|
2
2
|
import { CORE_FIELDS, POLICY_FIELDS, VIEW_FIELDS, fieldsOf } from '../fields.js';
|
|
3
3
|
import { functionSignature } from './callables.js';
|
|
4
4
|
export function memberMeaning(owner, ref) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { json } from '@astrale-os/kernel-dsl/value';
|
|
2
|
+
import { digestRevisionBytes } from '../../../addressing/revision.js';
|
|
2
3
|
import { isValueObject as isJsonObject } from '../../../language/value/model/object.js';
|
|
3
4
|
import { SCHEMA_ARRAY_KEYWORDS, SCHEMA_MAP_KEYWORDS, SCHEMA_SINGLE_KEYWORDS, } from '../../../language/value/syntax/keywords.js';
|
|
4
|
-
import { digestDomainSchemaBytes } from '../../canonical/domain.digest.js';
|
|
5
5
|
import { ANNOTATION_KEYWORDS } from '../fields.js';
|
|
6
6
|
/** Drop annotation keywords wherever a schema keyword nests a schema; never inside data. */
|
|
7
7
|
export function semanticValueSchema(value) {
|
|
@@ -30,7 +30,7 @@ export function semanticValueSchema(value) {
|
|
|
30
30
|
return semantic;
|
|
31
31
|
}
|
|
32
32
|
export function fingerprintMeaning(value) {
|
|
33
|
-
return
|
|
33
|
+
return digestRevisionBytes(json.encode(value));
|
|
34
34
|
}
|
|
35
35
|
function isJsonSchema(value) {
|
|
36
36
|
return typeof value === 'boolean' || isJsonObject(value);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { json } from '@astrale-os/kernel-dsl/value';
|
|
2
2
|
import { compareUnicode } from '../../addressing/ordering.js';
|
|
3
|
-
import { deepFreeze } from '
|
|
3
|
+
import { deepFreeze } from '../../language/freeze.js';
|
|
4
4
|
import { fingerprintMeaning } from './comparators/values.js';
|
|
5
5
|
import { differences } from './diff.js';
|
|
6
6
|
import { schemaIdentity } from './references.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { deepFreeze } from '
|
|
1
|
+
import { deepFreeze } from '../../../language/freeze.js';
|
|
2
2
|
import { SchemaError, diagnostic } from '../../diagnostic.js';
|
|
3
3
|
import { compareFootprint } from '../meaning/footprint.js';
|
|
4
4
|
import { schemaIdentity } from '../references.js';
|
|
@@ -2,6 +2,7 @@ import { json } from '@astrale-os/kernel-dsl/value';
|
|
|
2
2
|
import { compareDefinitionRefs, compareUnicode } from '../../addressing/ordering.js';
|
|
3
3
|
import { isBinaryInput } from '../../language/callable/model/callable.js';
|
|
4
4
|
import { compareEdgeUniqueFields, compareEdgeUniqueTuples, compareNodeUniqueTuples, } from '../../language/class/unique.js';
|
|
5
|
+
import { CLASS_OPERATIONS } from '../../language/policy/model/policy.js';
|
|
5
6
|
import { normalizeClassRule, normalizePolicyChecks, normalizePolicyExpression, } from '../../language/policy/normalization/normalize.js';
|
|
6
7
|
import { admitStateTopology } from '../../language/state/topology.js';
|
|
7
8
|
import { canonicalizeValueSchema } from '../../language/value/profile/canonicalize.js';
|
|
@@ -72,7 +73,7 @@ function canonicalizeClass(value) {
|
|
|
72
73
|
methods: mapRecord(value.methods, canonicalizeMethod),
|
|
73
74
|
...(value.data === undefined ? {} : { data: { mediaType: value.data.mediaType } }),
|
|
74
75
|
...(value.icon === undefined ? {} : { icon: value.icon }),
|
|
75
|
-
policies:
|
|
76
|
+
policies: canonicalizeClassPolicies(value.policies),
|
|
76
77
|
...(value.unique === undefined ? {} : { unique: canonicalizeNodeUnique(value.unique) }),
|
|
77
78
|
};
|
|
78
79
|
}
|
|
@@ -81,7 +82,7 @@ function canonicalizeClass(value) {
|
|
|
81
82
|
...base,
|
|
82
83
|
orientation: 'directed',
|
|
83
84
|
endpoints: canonicalizeDirectedEndpoints(value.endpoints),
|
|
84
|
-
policies: value.policies,
|
|
85
|
+
policies: canonicalizeClassPolicies(value.policies),
|
|
85
86
|
constraints: value.constraints,
|
|
86
87
|
...(value.unique === undefined ? {} : { unique: canonicalizeUnique(value.unique) }),
|
|
87
88
|
}
|
|
@@ -89,7 +90,7 @@ function canonicalizeClass(value) {
|
|
|
89
90
|
...base,
|
|
90
91
|
orientation: 'undirected',
|
|
91
92
|
endpoints: canonicalizeIncidentEndpoints(value.endpoints),
|
|
92
|
-
policies: value.policies,
|
|
93
|
+
policies: canonicalizeClassPolicies(value.policies),
|
|
93
94
|
constraints: value.constraints,
|
|
94
95
|
};
|
|
95
96
|
}
|
|
@@ -106,11 +107,11 @@ function canonicalizeUnique(tuples) {
|
|
|
106
107
|
.sort(compareEdgeUniqueTuples);
|
|
107
108
|
}
|
|
108
109
|
/** A rule keeps one spelling: normalized checks, or the Policy a lone `self` check names. */
|
|
109
|
-
function
|
|
110
|
-
return {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
};
|
|
110
|
+
function canonicalizeClassPolicies(value) {
|
|
111
|
+
return Object.fromEntries(CLASS_OPERATIONS.flatMap((operation) => {
|
|
112
|
+
const policy = value[operation];
|
|
113
|
+
return policy === undefined ? [] : [[operation, normalizeClassRule(policy)]];
|
|
114
|
+
}));
|
|
114
115
|
}
|
|
115
116
|
function canonicalizeFunction(value) {
|
|
116
117
|
return {
|
|
@@ -97,7 +97,7 @@ export function callableValidation(input, output, registry, patterns) {
|
|
|
97
97
|
const fields = inputFieldNodes(inputProgram);
|
|
98
98
|
return Object.freeze({
|
|
99
99
|
...(fields === undefined ? {} : { fields: Object.freeze(Object.keys(fields)) }),
|
|
100
|
-
validateInput: (value) => validatePreparedInstance(prepared.value, value),
|
|
100
|
+
validateInput: (value, options) => validatePreparedInstance(prepared.value, value, options),
|
|
101
101
|
validateInputField(field, value) {
|
|
102
102
|
const nodes = fields?.[field];
|
|
103
103
|
return nodes === undefined
|