@astrale-os/kernel-dsl 1.0.0-beta.1 → 1.0.0-beta.3
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.
|
@@ -57,8 +57,6 @@ export function validatePolicyParity(context, entry, entryIndex, policies, origi
|
|
|
57
57
|
const path = `/closure/${entryIndex}/definitions/classes/${classIndex}/policies/${operation}`;
|
|
58
58
|
if (isClassRuleChecks(policy)) {
|
|
59
59
|
// The wire admits rules only on a Node Class and only over `self` and `ref` objects.
|
|
60
|
-
if (!checksNameTheCaller(policy))
|
|
61
|
-
fail(path, 'Every branch of a Class rule must check a Policy: sameNode alone names no caller.');
|
|
62
60
|
validatePolicyChecks(context, typing, entry, policy, -1, definition.ref, path, 'class');
|
|
63
61
|
continue;
|
|
64
62
|
}
|
|
@@ -102,6 +100,9 @@ const SITE = {
|
|
|
102
100
|
class: { checks: 'Class rule checks', objects: 'the Class rule object contract' },
|
|
103
101
|
};
|
|
104
102
|
function validatePolicyChecks(context, typing, entry, expression, input, receiver, path, site) {
|
|
103
|
+
if (!checksNameTheCaller(expression)) {
|
|
104
|
+
fail(path, `${SITE[site].checks} must check a Policy on every branch: sameNode alone names no caller.`);
|
|
105
|
+
}
|
|
105
106
|
const measure = measureChecks(expression);
|
|
106
107
|
if (measure.depth > MAX_CHECK_DEPTH ||
|
|
107
108
|
measure.branches > MAX_BRANCHES ||
|
|
@@ -5,12 +5,12 @@ import type { DataFacet } from './data.js';
|
|
|
5
5
|
import type { EdgeContract } from './edge.js';
|
|
6
6
|
import type { PropertyFacet } from './property.js';
|
|
7
7
|
export type ClassKind = 'node' | 'edge';
|
|
8
|
-
/** An absent observation
|
|
8
|
+
/** An absent observation rule admits every caller; a delegation is still scoped by its ceiling. */
|
|
9
9
|
export interface NodeClassPolicies {
|
|
10
10
|
readonly read?: NodeClassPolicy;
|
|
11
11
|
readonly traverse?: NodeClassPolicy;
|
|
12
12
|
}
|
|
13
|
-
/** An absent observation
|
|
13
|
+
/** An absent observation rule admits every caller; a delegation is still scoped by its ceiling. */
|
|
14
14
|
export interface EdgeClassPolicies {
|
|
15
15
|
readonly read?: ClassPolicy;
|
|
16
16
|
readonly traverse?: ClassPolicy;
|
|
@@ -28,11 +28,6 @@ function validateClassPolicyUses(context, typing, operation) {
|
|
|
28
28
|
continue;
|
|
29
29
|
const pointer = `/classes/${escapePointer(name)}/policies/${operation}`;
|
|
30
30
|
if (isClassRuleChecks(ref)) {
|
|
31
|
-
// A rule lifts the Class ceiling the way a named Policy does, so, as a Policy connects its
|
|
32
|
-
// subject, each way the rule holds must pass through a check of the caller.
|
|
33
|
-
if (!checksNameTheCaller(ref)) {
|
|
34
|
-
context.add('PL_CONNECTIVITY', pointer, `Every branch of the ${operation} rule of Node Class ${name} must check a Policy: sameNode alone names no caller.`);
|
|
35
|
-
}
|
|
36
31
|
// Structure admits Policy checks only on a Node Class: `self` is the observed exact Class.
|
|
37
32
|
validateChecks(context, typing, ref, {
|
|
38
33
|
site: 'class',
|
|
@@ -107,6 +102,11 @@ function validateDeclaredMethods(context, typing, namespace, name, methods, rece
|
|
|
107
102
|
}
|
|
108
103
|
}
|
|
109
104
|
function validateChecks(validation, typing, expression, context) {
|
|
105
|
+
// Checks decide the caller the way a named Policy does, so, as a Policy connects its subject,
|
|
106
|
+
// each way they hold must pass through a check of the caller.
|
|
107
|
+
if (!checksNameTheCaller(expression)) {
|
|
108
|
+
validation.add('PL_CONNECTIVITY', context.pointer, `${SITE[context.site].checks} must check a Policy on every branch: sameNode alone names no caller.`);
|
|
109
|
+
}
|
|
110
110
|
const normalized = normalizePolicyChecks(expression);
|
|
111
111
|
const measure = measureChecks(normalized);
|
|
112
112
|
if (measure.depth > MAX_CHECK_DEPTH ||
|