@astrale-os/kernel-dsl 0.2.0-beta.8 → 0.2.0
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/addressing/class-key.js +5 -4
- package/dist/v1/addressing/method-key.js +3 -2
- package/dist/v1/addressing/patterns.d.ts +0 -5
- package/dist/v1/addressing/patterns.js +5 -5
- package/dist/v1/builder/callable/authoring.d.ts +87 -41
- package/dist/v1/builder/callable/authoring.js +29 -14
- package/dist/v1/builder/class/authoring.d.ts +311 -36
- package/dist/v1/builder/class/authoring.js +3 -4
- package/dist/v1/builder/class/property.d.ts +16 -8
- package/dist/v1/builder/class/property.js +21 -5
- package/dist/v1/builder/core/authoring.d.ts +28 -13
- package/dist/v1/builder/core/authoring.js +22 -2
- package/dist/v1/builder/index.d.ts +9 -8
- package/dist/v1/builder/index.js +2 -2
- package/dist/v1/builder/lowering/callable.d.ts +3 -1
- package/dist/v1/builder/lowering/callable.js +43 -51
- package/dist/v1/builder/lowering/class.d.ts +7 -0
- package/dist/v1/builder/lowering/class.js +79 -29
- package/dist/v1/builder/lowering/core.d.ts +3 -2
- package/dist/v1/builder/lowering/core.js +9 -6
- package/dist/v1/builder/lowering/policy.d.ts +8 -1
- package/dist/v1/builder/lowering/policy.js +35 -0
- package/dist/v1/builder/lowering/schema/capture.js +9 -4
- package/dist/v1/builder/lowering/schema/compile.d.ts +2 -2
- package/dist/v1/builder/lowering/schema/compile.js +15 -2
- package/dist/v1/builder/lowering/schema/context.d.ts +11 -8
- package/dist/v1/builder/lowering/schema/context.js +59 -29
- package/dist/v1/builder/lowering/schema/ownership.d.ts +3 -3
- package/dist/v1/builder/lowering/schema/ownership.js +2 -1
- package/dist/v1/builder/lowering/value/compile.js +14 -4
- package/dist/v1/builder/lowering/value/zod.d.ts +7 -6
- package/dist/v1/builder/lowering/value/zod.js +16 -7
- package/dist/v1/builder/lowering/view.d.ts +4 -3
- package/dist/v1/builder/lowering/view.js +2 -14
- package/dist/v1/builder/policy/authoring.d.ts +23 -6
- package/dist/v1/builder/policy/authoring.js +35 -8
- package/dist/v1/builder/schema/define.d.ts +8 -5
- package/dist/v1/builder/schema/diagnostic.d.ts +1 -1
- package/dist/v1/builder/schema/handle.d.ts +2 -1
- package/dist/v1/builder/schema/input.d.ts +9 -1
- package/dist/v1/builder/schema/projection/callable.d.ts +51 -0
- package/dist/v1/builder/schema/projection/callable.js +1 -0
- package/dist/v1/builder/schema/projection/class.d.ts +89 -0
- package/dist/v1/builder/schema/projection/class.js +1 -0
- package/dist/v1/builder/schema/projection/core-input.d.ts +32 -0
- package/dist/v1/builder/schema/projection/core-input.js +1 -0
- package/dist/v1/builder/schema/projection/domain.d.ts +59 -0
- package/dist/v1/builder/schema/projection/domain.js +1 -0
- package/dist/v1/builder/schema/projection/identity.d.ts +39 -0
- package/dist/v1/builder/schema/projection/identity.js +1 -0
- package/dist/v1/builder/schema/projection/model.d.ts +59 -0
- package/dist/v1/builder/schema/projection/model.js +1 -0
- package/dist/v1/builder/schema/projection/property.d.ts +32 -0
- package/dist/v1/builder/schema/projection/property.js +1 -0
- package/dist/v1/builder/schema/projection/resolved-class.d.ts +76 -0
- package/dist/v1/builder/schema/projection/resolved-class.js +1 -0
- package/dist/v1/builder/schema/projection.d.ts +4 -258
- package/dist/v1/builder/value/full-match.js +6 -3
- package/dist/v1/builder/value/path.d.ts +2 -2
- package/dist/v1/builder/value/path.js +2 -2
- package/dist/v1/builder/view/authoring.d.ts +6 -14
- package/dist/v1/builder/view/authoring.js +13 -5
- package/dist/v1/bundle/structure.d.ts +2 -1
- package/dist/v1/compiled/admission/accept.d.ts +1 -1
- package/dist/v1/compiled/admission/accept.js +11 -814
- package/dist/v1/compiled/admission/closure.d.ts +3 -0
- package/dist/v1/compiled/admission/closure.js +173 -0
- package/dist/v1/compiled/admission/diagnostic.d.ts +7 -0
- package/dist/v1/compiled/admission/diagnostic.js +13 -0
- package/dist/v1/compiled/admission/revision.js +9 -1
- package/dist/v1/compiled/admission/semantics/cardinality.d.ts +5 -0
- package/dist/v1/compiled/admission/semantics/cardinality.js +113 -0
- package/dist/v1/compiled/admission/semantics/class.d.ts +5 -0
- package/dist/v1/compiled/admission/semantics/class.js +125 -0
- package/dist/v1/compiled/admission/semantics/context.d.ts +60 -0
- package/dist/v1/compiled/admission/semantics/context.js +81 -0
- package/dist/v1/compiled/admission/semantics/core.d.ts +35 -0
- package/dist/v1/compiled/admission/semantics/core.js +123 -0
- package/dist/v1/compiled/admission/semantics/edge.d.ts +8 -0
- package/dist/v1/compiled/admission/semantics/edge.js +89 -0
- package/dist/v1/compiled/admission/semantics/policy/admit.d.ts +4 -0
- package/dist/v1/compiled/admission/semantics/policy/admit.js +63 -0
- package/dist/v1/compiled/admission/semantics/policy/callable.d.ts +5 -0
- package/dist/v1/compiled/admission/semantics/policy/callable.js +72 -0
- package/dist/v1/compiled/admission/semantics/policy/contracts.d.ts +24 -0
- package/dist/v1/compiled/admission/semantics/policy/contracts.js +45 -0
- package/dist/v1/compiled/admission/semantics/policy/equality.d.ts +8 -0
- package/dist/v1/compiled/admission/semantics/policy/equality.js +27 -0
- package/dist/v1/compiled/admission/semantics/policy/measure.d.ts +9 -0
- package/dist/v1/compiled/admission/semantics/policy/measure.js +81 -0
- package/dist/v1/compiled/admission/semantics/policy/parity.d.ts +4 -0
- package/dist/v1/compiled/admission/semantics/policy/parity.js +139 -0
- package/dist/v1/compiled/admission/semantics/policy/pattern.d.ts +8 -0
- package/dist/v1/compiled/admission/semantics/policy/pattern.js +78 -0
- package/dist/v1/compiled/admission/semantics/policy/typing.d.ts +28 -0
- package/dist/v1/compiled/admission/semantics/policy/typing.js +206 -0
- package/dist/v1/compiled/admission/semantics/policy/variants.d.ts +10 -0
- package/dist/v1/compiled/admission/semantics/policy/variants.js +65 -0
- package/dist/v1/compiled/admission/semantics.d.ts +1 -1
- package/dist/v1/compiled/admission/semantics.js +8 -1078
- package/dist/v1/compiled/admission/wire/callable.d.ts +6 -0
- package/dist/v1/compiled/admission/wire/callable.js +90 -0
- package/dist/v1/compiled/admission/wire/class.d.ts +4 -0
- package/dist/v1/compiled/admission/wire/class.js +133 -0
- package/dist/v1/compiled/admission/wire/core.d.ts +5 -0
- package/dist/v1/compiled/admission/wire/core.js +32 -0
- package/dist/v1/compiled/admission/wire/dependency.d.ts +14 -0
- package/dist/v1/compiled/admission/wire/dependency.js +43 -0
- package/dist/v1/compiled/admission/wire/entry.d.ts +5 -0
- package/dist/v1/compiled/admission/wire/entry.js +100 -0
- package/dist/v1/compiled/admission/wire/pattern.d.ts +12 -0
- package/dist/v1/compiled/admission/wire/pattern.js +111 -0
- package/dist/v1/compiled/admission/wire/policy.d.ts +10 -0
- package/dist/v1/compiled/admission/wire/policy.js +189 -0
- package/dist/v1/compiled/admission/wire/program.d.ts +4 -0
- package/dist/v1/compiled/admission/wire/program.js +52 -0
- package/dist/v1/compiled/admission/wire/property.d.ts +4 -0
- package/dist/v1/compiled/admission/wire/property.js +74 -0
- package/dist/v1/compiled/admission/wire/reference.d.ts +8 -0
- package/dist/v1/compiled/admission/wire/reference.js +33 -0
- package/dist/v1/compiled/admission/wire/value.d.ts +29 -0
- package/dist/v1/compiled/admission/wire/value.js +98 -0
- package/dist/v1/compiled/admission/wire/view.d.ts +3 -0
- package/dist/v1/compiled/admission/wire/view.js +17 -0
- package/dist/v1/compiled/compiler/compile.js +43 -11
- package/dist/v1/compiled/generated.d.ts +10 -0
- package/dist/v1/compiled/generated.js +15 -0
- package/dist/v1/compiled/loader/load.d.ts +5 -0
- package/dist/v1/compiled/loader/load.js +18 -4
- package/dist/v1/compiled/model/schema.d.ts +16 -7
- package/dist/v1/domain/create.js +18 -28
- package/dist/v1/domain/model/domain.d.ts +0 -1
- package/dist/v1/domain/model/input.d.ts +3 -0
- package/dist/v1/domain/projection/classes.js +13 -41
- package/dist/v1/domain/validation/create.d.ts +2 -0
- package/dist/v1/domain/validation/create.js +12 -0
- package/dist/v1/index.d.ts +5 -2
- package/dist/v1/index.js +3 -1
- package/dist/v1/language/callable/composition.d.ts +27 -0
- package/dist/v1/language/callable/composition.js +52 -0
- package/dist/v1/language/callable/executable.d.ts +6 -0
- package/dist/v1/language/callable/executable.js +4 -0
- package/dist/v1/language/callable/model/callable.d.ts +34 -9
- package/dist/v1/language/callable/model/callable.js +3 -1
- package/dist/v1/language/callable/resolved.d.ts +23 -8
- package/dist/v1/language/class/facets.d.ts +5 -2
- package/dist/v1/language/class/inheritance.d.ts +12 -0
- package/dist/v1/language/class/inheritance.js +25 -0
- package/dist/v1/language/class/lifetime.d.ts +17 -0
- package/dist/v1/language/class/lifetime.js +26 -0
- package/dist/v1/language/class/model/class.d.ts +8 -4
- package/dist/v1/language/class/model/property.d.ts +4 -2
- package/dist/v1/language/class/property-values.js +5 -2
- package/dist/v1/language/class/resolved.d.ts +25 -15
- package/dist/v1/language/core/model/core.d.ts +7 -1
- package/dist/v1/language/core/resolved.d.ts +6 -2
- package/dist/v1/language/definition/metadata.d.ts +8 -0
- package/dist/v1/language/definition/metadata.js +12 -0
- package/dist/v1/language/index.d.ts +9 -0
- package/dist/v1/language/index.js +6 -0
- package/dist/v1/language/policy/analysis/branches.d.ts +4 -3
- package/dist/v1/language/policy/analysis/branches.js +54 -12
- package/dist/v1/language/policy/analysis/budgets.js +1 -1
- package/dist/v1/language/policy/analysis/checks.d.ts +28 -0
- package/dist/v1/language/policy/analysis/checks.js +80 -0
- package/dist/v1/language/policy/index.d.ts +1 -0
- package/dist/v1/language/policy/index.js +1 -0
- package/dist/v1/language/policy/model/policy.d.ts +71 -5
- package/dist/v1/language/policy/model/policy.js +52 -1
- package/dist/v1/language/policy/normalization/normalize.d.ts +12 -1
- package/dist/v1/language/policy/normalization/normalize.js +178 -44
- package/dist/v1/language/state/index.d.ts +3 -0
- package/dist/v1/language/state/index.js +1 -0
- package/dist/v1/language/state/machine.d.ts +28 -0
- package/dist/v1/language/state/machine.js +40 -0
- package/dist/v1/language/state/topology.d.ts +14 -0
- package/dist/v1/language/state/topology.js +69 -0
- package/dist/v1/language/value/compile/fields.d.ts +1 -1
- package/dist/v1/language/value/compile/load.d.ts +4 -2
- package/dist/v1/language/value/compile/load.js +22 -1
- package/dist/v1/language/value/compile/model.d.ts +16 -1
- package/dist/v1/language/value/evaluate/assertions.d.ts +2 -0
- package/dist/v1/language/value/evaluate/assertions.js +13 -0
- package/dist/v1/language/value/evaluate/evaluator.js +111 -28
- package/dist/v1/language/value/evaluate/preparation.d.ts +10 -1
- package/dist/v1/language/value/evaluate/preparation.js +17 -26
- package/dist/v1/language/value/evaluate/program.js +1 -1
- package/dist/v1/language/value/evaluate/validate.d.ts +6 -2
- package/dist/v1/language/value/evaluate/validate.js +18 -11
- package/dist/v1/language/value/inclusion/includes.d.ts +9 -0
- package/dist/v1/language/value/inclusion/includes.js +777 -0
- package/dist/v1/language/value/model/blob.d.ts +31 -0
- package/dist/v1/language/value/model/blob.js +90 -0
- package/dist/v1/language/value/model/instant.d.ts +0 -2
- package/dist/v1/language/value/model/instant.js +1 -1
- package/dist/v1/language/value/model/schema.d.ts +2 -1
- package/dist/v1/language/value/model/schema.js +1 -5
- package/dist/v1/language/value/ordering.d.ts +2 -0
- package/dist/v1/language/value/ordering.js +4 -8
- package/dist/v1/language/value/profile/json.validate.js +1 -1
- package/dist/v1/language/value/profile/rules.js +48 -12
- package/dist/v1/language/value/reference/registry.d.ts +2 -1
- package/dist/v1/language/value/regexp/ast.js +3 -64
- package/dist/v1/language/value/regexp/compile.d.ts +32 -3
- package/dist/v1/language/value/regexp/compile.js +117 -21
- package/dist/v1/language/value/regexp/matcher.d.ts +6 -3
- package/dist/v1/language/value/regexp/matcher.js +185 -28
- package/dist/v1/language/value/regexp/syntax.d.ts +12 -1
- package/dist/v1/language/value/regexp/syntax.js +14 -2
- package/dist/v1/language/value/regexp/unicode.d.ts +32 -0
- package/dist/v1/language/value/regexp/unicode.js +139 -0
- package/dist/v1/language/value/syntax/full-match.js +8 -5
- package/dist/v1/language/value/syntax/node-path/validate.js +4 -6
- package/dist/v1/language/view/model/view.d.ts +2 -4
- package/dist/v1/language/view/resolved.d.ts +2 -2
- package/dist/v1/schema/analysis/class.d.ts +36 -6
- package/dist/v1/schema/analysis/class.js +31 -66
- package/dist/v1/schema/canonical/revision.d.ts +2 -1
- package/dist/v1/schema/canonical/revision.js +4 -1
- package/dist/v1/schema/compatibility/api.d.ts +3 -0
- package/dist/v1/schema/compatibility/api.js +2 -0
- package/dist/v1/schema/compatibility/comparators/callables.d.ts +39 -0
- package/dist/v1/schema/compatibility/comparators/callables.js +101 -0
- package/dist/v1/schema/compatibility/comparators/classes.d.ts +47 -0
- package/dist/v1/schema/compatibility/comparators/classes.js +160 -0
- package/dist/v1/schema/compatibility/comparators/index.d.ts +12 -0
- package/dist/v1/schema/compatibility/comparators/index.js +53 -0
- package/dist/v1/schema/compatibility/comparators/members.d.ts +4 -0
- package/dist/v1/schema/compatibility/comparators/members.js +49 -0
- package/dist/v1/schema/compatibility/comparators/values.d.ts +5 -0
- package/dist/v1/schema/compatibility/comparators/values.js +37 -0
- package/dist/v1/schema/compatibility/compare.d.ts +5 -0
- package/dist/v1/schema/compatibility/compare.js +23 -0
- package/dist/v1/schema/compatibility/context.d.ts +19 -0
- package/dist/v1/schema/compatibility/context.js +49 -0
- package/dist/v1/schema/compatibility/coordinate.d.ts +40 -0
- package/dist/v1/schema/compatibility/coordinate.js +38 -0
- package/dist/v1/schema/compatibility/diff.d.ts +12 -0
- package/dist/v1/schema/compatibility/diff.js +39 -0
- package/dist/v1/schema/compatibility/evidence.d.ts +16 -0
- package/dist/v1/schema/compatibility/evidence.js +62 -0
- package/dist/v1/schema/compatibility/fields.d.ts +194 -0
- package/dist/v1/schema/compatibility/fields.js +94 -0
- package/dist/v1/schema/compatibility/index.d.ts +6 -0
- package/dist/v1/schema/compatibility/index.js +3 -0
- package/dist/v1/schema/compatibility/meaning/footprint.d.ts +7 -0
- package/dist/v1/schema/compatibility/meaning/footprint.js +59 -0
- package/dist/v1/schema/compatibility/meaning/index.d.ts +3 -0
- package/dist/v1/schema/compatibility/meaning/index.js +16 -0
- package/dist/v1/schema/compatibility/model.d.ts +131 -0
- package/dist/v1/schema/compatibility/model.js +1 -0
- package/dist/v1/schema/compatibility/references.d.ts +38 -0
- package/dist/v1/schema/compatibility/references.js +149 -0
- package/dist/v1/schema/compatibility/report.d.ts +27 -0
- package/dist/v1/schema/compatibility/report.js +100 -0
- package/dist/v1/schema/compatibility/scope.d.ts +36 -0
- package/dist/v1/schema/compatibility/scope.js +110 -0
- package/dist/v1/schema/compatibility/structure/index.d.ts +3 -0
- package/dist/v1/schema/compatibility/structure/index.js +40 -0
- package/dist/v1/schema/compatibility/structure/inheritance.d.ts +7 -0
- package/dist/v1/schema/compatibility/structure/inheritance.js +68 -0
- package/dist/v1/schema/compatibility/structure/requirements.d.ts +7 -0
- package/dist/v1/schema/compatibility/structure/requirements.js +97 -0
- package/dist/v1/schema/compatibility/subjects.d.ts +39 -0
- package/dist/v1/schema/compatibility/subjects.js +143 -0
- package/dist/v1/schema/compatibility/versioning/index.d.ts +8 -0
- package/dist/v1/schema/compatibility/versioning/index.js +50 -0
- package/dist/v1/schema/compatibility/versioning/members.d.ts +12 -0
- package/dist/v1/schema/compatibility/versioning/members.js +47 -0
- package/dist/v1/schema/compatibility/versioning/surface.d.ts +11 -0
- package/dist/v1/schema/compatibility/versioning/surface.js +61 -0
- package/dist/v1/schema/diagnostic.d.ts +1 -1
- package/dist/v1/schema/fingerprint.d.ts +2 -0
- package/dist/v1/schema/fingerprint.js +1 -0
- package/dist/v1/schema/index.d.ts +4 -3
- package/dist/v1/schema/index.js +2 -1
- package/dist/v1/schema/model/schema.d.ts +8 -11
- package/dist/v1/schema/normalization/domain.js +57 -13
- package/dist/v1/schema/resolution/definition.index.d.ts +1 -2
- package/dist/v1/schema/resolution/definition.index.js +0 -3
- package/dist/v1/schema/resolution/domain.d.ts +4 -1
- package/dist/v1/schema/resolution/domain.js +26 -18
- package/dist/v1/schema/resolution/origins.d.ts +28 -5
- package/dist/v1/schema/resolution/origins.js +68 -31
- package/dist/v1/schema/validation/callable.d.ts +4 -0
- package/dist/v1/schema/validation/callable.js +39 -0
- package/dist/v1/schema/validation/class.d.ts +10 -0
- package/dist/v1/schema/validation/class.js +79 -60
- package/dist/v1/schema/validation/core.js +83 -55
- package/dist/v1/schema/validation/domain.d.ts +2 -1
- package/dist/v1/schema/validation/domain.js +2 -0
- package/dist/v1/schema/validation/domain.structure.d.ts +0 -2
- package/dist/v1/schema/validation/domain.structure.js +214 -171
- package/dist/v1/schema/validation/policy/budgets.js +36 -6
- package/dist/v1/schema/validation/policy/context.js +5 -16
- package/dist/v1/schema/validation/policy/objects.d.ts +4 -0
- package/dist/v1/schema/validation/policy/objects.js +71 -0
- package/dist/v1/schema/validation/policy/references.js +16 -4
- package/dist/v1/schema/validation/policy/typing.d.ts +2 -0
- package/dist/v1/schema/validation/policy/typing.js +55 -7
- package/dist/v1/schema/validation/policy/uses.js +73 -99
- package/dist/v1/schema/validation/value-api.d.ts +2 -0
- package/dist/v1/schema/validation/value-api.js +1 -0
- package/dist/v1/schema/validation/value.js +7 -1
- package/dist/v1/schema/validation/view.js +14 -9
- package/dist/value/accept.d.ts +9 -0
- package/dist/value/accept.js +106 -7
- package/dist/value/canonical.d.ts +3 -0
- package/dist/value/canonical.js +22 -6
- package/dist/value/immutable.optimization.d.ts +15 -0
- package/dist/value/immutable.optimization.js +34 -0
- package/dist/value/index.d.ts +1 -1
- package/dist/value/index.js +1 -1
- package/dist/value/json.d.ts +1 -1
- package/dist/value/json.js +1 -1
- package/dist/value/limits.d.ts +1 -1
- package/dist/value/unicode.d.ts +4 -1
- package/dist/value/unicode.js +28 -0
- package/package.json +20 -5
- package/dist/v1/schema/compatibility/meaning.d.ts +0 -29
- package/dist/v1/schema/compatibility/meaning.js +0 -605
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { Key } from '../../../../addressing/index.js';
|
|
2
|
+
import {} from '../../../../language/class/model/edge.js';
|
|
3
|
+
import { branchesOf, targetMode, isConnected, } from '../../../../language/policy/analysis/branches.js';
|
|
4
|
+
import { MAX_PATTERN_DEPTH, MAX_BRANCHES, MAX_EDGES, MAX_DOMAINS, measureChecks, MAX_CHECK_DEPTH, MAX_CHECK_LEAVES, } from '../../../../language/policy/analysis/budgets.js';
|
|
5
|
+
import { admittedCheckClasses, neverAdmittedClasses, } from '../../../../language/policy/analysis/checks.js';
|
|
6
|
+
import { checksNameTheCaller, isClassRuleChecks, } from '../../../../language/policy/model/policy.js';
|
|
7
|
+
import { normalizePolicyExpression } from '../../../../language/policy/normalization/normalize.js';
|
|
8
|
+
import {} from '../../../model/schema.js';
|
|
9
|
+
import { fail } from '../../diagnostic.js';
|
|
10
|
+
import { isCompiledEdge } from '../context.js';
|
|
11
|
+
import { callableObjectContracts } from './contracts.js';
|
|
12
|
+
import { measureCompiledPolicy } from './measure.js';
|
|
13
|
+
import { CompiledPolicyTyping } from './typing.js';
|
|
14
|
+
/** Check Policy typing and expansion budgets against the entry’s own closure. */
|
|
15
|
+
export function validatePolicyParity(context, entry, entryIndex, policies, origins) {
|
|
16
|
+
const normalized = new Map([...policies].map(([name, policy]) => [name, normalizePolicyExpression(policy.expression)]));
|
|
17
|
+
const typing = new CompiledPolicyTyping(context, entry, normalized, origins);
|
|
18
|
+
for (const [name, declaration] of policies) {
|
|
19
|
+
const path = `/closure/${entryIndex}/definitions/policies/${declarationIndex(entry, 'policies', name)}`;
|
|
20
|
+
if ('match' in declaration.expression) {
|
|
21
|
+
for (const branch of branchesOf(declaration.expression.match, name)) {
|
|
22
|
+
if (targetMode(branch) === undefined) {
|
|
23
|
+
fail(`${path}/expression/match`, 'A Policy branch must target object or at least one of source and target.');
|
|
24
|
+
}
|
|
25
|
+
if (!isConnected(branch)) {
|
|
26
|
+
fail(`${path}/expression/match`, 'A Policy branch must connect subject, every referenced protected term, and every scoped variable.');
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const measure = measureCompiledPolicy(entry.origin, name, normalized, new Set());
|
|
31
|
+
if (measure !== undefined &&
|
|
32
|
+
(measure.depth > MAX_PATTERN_DEPTH ||
|
|
33
|
+
measure.edgeCounts.length > MAX_BRANCHES ||
|
|
34
|
+
Math.max(0, ...measure.edgeCounts) > MAX_EDGES ||
|
|
35
|
+
measure.domains.size > MAX_DOMAINS)) {
|
|
36
|
+
fail(path, 'Policy expansion exceeds the V1 depth, branch, Edge, or Domain budget.');
|
|
37
|
+
}
|
|
38
|
+
const branches = typing.expandedBranches(name, new Set(), `$${name}`);
|
|
39
|
+
if (branches !== undefined) {
|
|
40
|
+
for (const branch of branches) {
|
|
41
|
+
const mode = targetMode(branch);
|
|
42
|
+
if (mode === undefined)
|
|
43
|
+
fail(path, 'Expanded Policy branches must use one coherent target mode.');
|
|
44
|
+
const use = mode === 'object'
|
|
45
|
+
? { kind: 'object', object: { kind: 'default' } }
|
|
46
|
+
: { kind: 'edge', source: { kind: 'default' }, target: { kind: 'default' } };
|
|
47
|
+
if (!typing.branchIsTyped(branch, use))
|
|
48
|
+
fail(path, 'A Policy branch has contradictory endpoint or repeat contracts.');
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
for (const [classIndex, definition] of entry.definitions.classes.entries()) {
|
|
53
|
+
for (const operation of ['read', 'traverse']) {
|
|
54
|
+
const policy = definition.policies[operation];
|
|
55
|
+
if (typeof policy !== 'object')
|
|
56
|
+
continue;
|
|
57
|
+
const path = `/closure/${entryIndex}/definitions/classes/${classIndex}/policies/${operation}`;
|
|
58
|
+
if (isClassRuleChecks(policy)) {
|
|
59
|
+
// The wire admits rules only on a Node Class and only over `self` and `ref` objects.
|
|
60
|
+
validatePolicyChecks(context, typing, entry, policy, -1, definition.ref, path, 'class');
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
const label = operation === 'read' ? 'Read' : 'Traverse';
|
|
64
|
+
if (definition.kind === 'node') {
|
|
65
|
+
if (!typing.policyAccepts(policy.name, { kind: 'exact', ref: definition.ref })) {
|
|
66
|
+
fail(path, `${label} Policy is incompatible with its protected Node Class.`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
else if (isCompiledEdge(definition)) {
|
|
70
|
+
const endpoints = definition.orientation === 'directed'
|
|
71
|
+
? [definition.endpoints.source, definition.endpoints.target]
|
|
72
|
+
: definition.endpoints;
|
|
73
|
+
const sources = typing.concreteEndpointClasses(endpoints[0].accepts);
|
|
74
|
+
const targets = typing.concreteEndpointClasses(endpoints[1].accepts);
|
|
75
|
+
if (sources.some((source) => targets.some((target) => !typing.policyAcceptsEdge(policy.name, { kind: 'exact', ref: source }, { kind: 'exact', ref: target })))) {
|
|
76
|
+
fail(path, `${label} Policy is incompatible with an accepted Edge endpoint pair.`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (definition.kind === 'node') {
|
|
81
|
+
for (const [methodIndex, method] of definition.methods.entries()) {
|
|
82
|
+
if (typeof method.policy === 'object') {
|
|
83
|
+
validatePolicyChecks(context, typing, entry, method.policy, method.input, method.static ? undefined : definition.ref, `/closure/${entryIndex}/definitions/classes/${classIndex}/methods/${methodIndex}/policy`, 'callable');
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
for (const [functionIndex, callable] of entry.definitions.functions.entries()) {
|
|
89
|
+
if (typeof callable.policy === 'object') {
|
|
90
|
+
validatePolicyChecks(context, typing, entry, callable.policy, typeof callable.input === 'number' ? callable.input : callable.input.metadata, undefined, `/closure/${entryIndex}/definitions/functions/${functionIndex}/policy`, 'callable');
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function declarationIndex(entry, kind, name) {
|
|
95
|
+
return entry.definitions[kind].findIndex(({ ref }) => ref.name === name);
|
|
96
|
+
}
|
|
97
|
+
/** How a refusal names the checks of each site and the contract of their objects. */
|
|
98
|
+
const SITE = {
|
|
99
|
+
callable: { checks: 'Callable Policy checks', objects: 'the callable object contract' },
|
|
100
|
+
class: { checks: 'Class rule checks', objects: 'the Class rule object contract' },
|
|
101
|
+
};
|
|
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
|
+
}
|
|
106
|
+
const measure = measureChecks(expression);
|
|
107
|
+
if (measure.depth > MAX_CHECK_DEPTH ||
|
|
108
|
+
measure.branches > MAX_BRANCHES ||
|
|
109
|
+
measure.leaves > MAX_CHECK_LEAVES) {
|
|
110
|
+
fail(path, `${SITE[site].checks} exceed the V1 depth, branch, or leaf budget.`);
|
|
111
|
+
}
|
|
112
|
+
const leaves = new Map();
|
|
113
|
+
const visit = (value, pointer) => {
|
|
114
|
+
if ('sameNode' in value)
|
|
115
|
+
return;
|
|
116
|
+
if (!('check' in value)) {
|
|
117
|
+
const children = 'allOf' in value ? value.allOf : value.anyOf;
|
|
118
|
+
children.forEach((child, index) => visit(child, `${pointer}/${index}`));
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const contracts = callableObjectContracts(context, entry, input, receiver, value.object);
|
|
122
|
+
if (contracts === undefined)
|
|
123
|
+
return;
|
|
124
|
+
const typings = new Map(contracts.map((contract) => [
|
|
125
|
+
contract.kind === 'exact' ? Key.of(contract.ref) : 'default',
|
|
126
|
+
typing.policyBranchTyping(value.check.name, contract),
|
|
127
|
+
]));
|
|
128
|
+
const admitted = admittedCheckClasses(typings);
|
|
129
|
+
if (admitted === undefined) {
|
|
130
|
+
fail(pointer, `Named Policy is incompatible with ${SITE[site].objects}.`);
|
|
131
|
+
}
|
|
132
|
+
leaves.set(value, { accepted: [...typings.keys()], admitted });
|
|
133
|
+
};
|
|
134
|
+
visit(expression, path);
|
|
135
|
+
const [never] = neverAdmittedClasses(expression, leaves);
|
|
136
|
+
if (never !== undefined) {
|
|
137
|
+
fail(path, `${SITE[site].checks} can never admit ${never[0]} of Class ${never[1]}.`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type MethodAddress } from '../../../../addressing/index.js';
|
|
2
|
+
import { type PolicyExpression } from '../../../../language/policy/model/policy.js';
|
|
3
|
+
import { type CompiledSchemaEntry } from '../../../model/schema.js';
|
|
4
|
+
import { type SemanticIndex, type CompiledPolicy } from '../context.js';
|
|
5
|
+
/** Check named Policy composition and scoped pattern references. */
|
|
6
|
+
export declare function validatePolicyExpression(context: SemanticIndex, entry: CompiledSchemaEntry, expression: PolicyExpression, path: string, local: ReadonlyMap<string, CompiledPolicy>): void;
|
|
7
|
+
/** Require an exact executable Method declaration for a Policy reference. */
|
|
8
|
+
export declare function validatePolicyMethod(context: SemanticIndex, ref: MethodAddress, path: string): void;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { Key } from '../../../../addressing/index.js';
|
|
2
|
+
import { isMethodExecutable } from '../../../../language/callable/executable.js';
|
|
3
|
+
import { policyVariableClass } from '../../../../language/index.js';
|
|
4
|
+
import { MAX_REPEAT, MAX_VARIABLES } from '../../../../language/policy/analysis/budgets.js';
|
|
5
|
+
import {} from '../../../../language/policy/model/policy.js';
|
|
6
|
+
import {} from '../../../model/schema.js';
|
|
7
|
+
import { fail } from '../../diagnostic.js';
|
|
8
|
+
import {} from '../context.js';
|
|
9
|
+
/** Check named Policy composition and scoped pattern references. */
|
|
10
|
+
export function validatePolicyExpression(context, entry, expression, path, local) {
|
|
11
|
+
if ('match' in expression) {
|
|
12
|
+
validatePattern(context, expression.match, `${path}/match`, new Set(), new Set());
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const values = 'allOf' in expression ? expression.allOf : expression.anyOf;
|
|
16
|
+
if (values.length === 0)
|
|
17
|
+
fail(path, 'Named Policy composition must be non-empty.');
|
|
18
|
+
for (const [index, ref] of values.entries()) {
|
|
19
|
+
if (ref.origin !== entry.origin || ref.kind !== 'policy' || !local.has(ref.name))
|
|
20
|
+
fail(`${path}/${index}`, 'Named Policy composition must reference a local Policy.');
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function validatePattern(context, expression, path, scope, declared) {
|
|
24
|
+
if ('sameNode' in expression) {
|
|
25
|
+
validatePolicyTerm(context, expression.sameNode.left, `${path}/sameNode/left`, scope);
|
|
26
|
+
validatePolicyTerm(context, expression.sameNode.right, `${path}/sameNode/right`, scope);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
if ('source' in expression) {
|
|
30
|
+
if (context.classes.get(Key.of(expression.class))?.value.kind !== 'edge')
|
|
31
|
+
fail(`${path}/class`, 'Policy pattern Class must resolve to an Edge Class.');
|
|
32
|
+
validatePolicyTerm(context, expression.source, `${path}/source`, scope);
|
|
33
|
+
validatePolicyTerm(context, expression.target, `${path}/target`, scope);
|
|
34
|
+
if (expression.repeat !== undefined &&
|
|
35
|
+
(!Number.isInteger(expression.repeat.min) ||
|
|
36
|
+
!Number.isInteger(expression.repeat.max) ||
|
|
37
|
+
expression.repeat.min < 0 ||
|
|
38
|
+
expression.repeat.max < expression.repeat.min ||
|
|
39
|
+
expression.repeat.max > MAX_REPEAT))
|
|
40
|
+
fail(`${path}/repeat`, 'Policy repeat is outside the V1 bounds.');
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if ('exists' in expression) {
|
|
44
|
+
if (expression.exists.nodes.length > MAX_VARIABLES) {
|
|
45
|
+
fail(`${path}/exists/nodes`, 'Policy exists exceeds the V1 variable budget.');
|
|
46
|
+
}
|
|
47
|
+
const nested = new Set(scope);
|
|
48
|
+
for (const [index, node] of expression.exists.nodes.entries()) {
|
|
49
|
+
const id = node.variable.id;
|
|
50
|
+
if (declared.has(id) || nested.has(id))
|
|
51
|
+
fail(`${path}/exists/nodes/${index}/variable/id`, 'Policy variable IDs must be globally unique and cannot shadow.');
|
|
52
|
+
declared.add(id);
|
|
53
|
+
nested.add(id);
|
|
54
|
+
const classRef = policyVariableClass(node);
|
|
55
|
+
if (classRef !== undefined && context.classes.get(Key.of(classRef))?.value.kind !== 'node')
|
|
56
|
+
fail(`${path}/exists/nodes/${index}/${'class' in node ? 'class' : 'selector/class'}`, 'Policy variable Class must resolve to a Node Class.');
|
|
57
|
+
}
|
|
58
|
+
validatePattern(context, expression.exists.where, `${path}/exists/where`, nested, declared);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const values = 'allOf' in expression ? expression.allOf : expression.anyOf;
|
|
62
|
+
if (values.length === 0)
|
|
63
|
+
fail(path, 'Policy pattern composition must be non-empty.');
|
|
64
|
+
values.forEach((value, index) => validatePattern(context, value, `${path}/${index}`, scope, declared));
|
|
65
|
+
}
|
|
66
|
+
function validatePolicyTerm(context, term, path, scope) {
|
|
67
|
+
if (term.kind === 'ref' && term.ref.kind === 'method')
|
|
68
|
+
validatePolicyMethod(context, term.ref, `${path}/ref`);
|
|
69
|
+
if (term.kind === 'variable' && !scope.has(term.id))
|
|
70
|
+
fail(path, 'Policy variable is outside its declaring scope.');
|
|
71
|
+
}
|
|
72
|
+
/** Require an exact executable Method declaration for a Policy reference. */
|
|
73
|
+
export function validatePolicyMethod(context, ref, path) {
|
|
74
|
+
const owner = context.classes.get(Key.of(ref.owner))?.value;
|
|
75
|
+
const method = owner?.kind === 'node' ? owner.methods.find((method) => method.name === ref.name) : undefined;
|
|
76
|
+
if (method === undefined || !isMethodExecutable(owner, method))
|
|
77
|
+
fail(path, 'Policy Method ref must name an exact concrete Method declaration.');
|
|
78
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type ClassRef } from '../../../../addressing/index.js';
|
|
2
|
+
import { type PatternBranch } from '../../../../language/policy/analysis/branches.js';
|
|
3
|
+
import { type PolicyExpression } from '../../../../language/policy/model/policy.js';
|
|
4
|
+
import { type CompiledSchemaEntry } from '../../../model/schema.js';
|
|
5
|
+
import { type SemanticIndex } from '../context.js';
|
|
6
|
+
import { type CompiledObjectContract, type CompiledPolicyUse } from './contracts.js';
|
|
7
|
+
/** Types one entry's Policies against the Node Classes of its own closure, as source admission. */
|
|
8
|
+
export declare class CompiledPolicyTyping {
|
|
9
|
+
readonly context: SemanticIndex;
|
|
10
|
+
readonly entry: CompiledSchemaEntry;
|
|
11
|
+
readonly normalized: ReadonlyMap<string, PolicyExpression>;
|
|
12
|
+
readonly allNodeClasses: readonly ClassRef[];
|
|
13
|
+
readonly concreteNodeClasses: readonly ClassRef[];
|
|
14
|
+
constructor(context: SemanticIndex, entry: CompiledSchemaEntry, normalized: ReadonlyMap<string, PolicyExpression>, origins: ReadonlySet<string>);
|
|
15
|
+
expandedBranches(name: string, visiting: Set<string>, namespace: string): readonly PatternBranch[] | undefined;
|
|
16
|
+
policyAccepts(name: string, object: CompiledObjectContract): boolean;
|
|
17
|
+
policyBranchTyping(name: string, object: CompiledObjectContract): readonly boolean[] | undefined;
|
|
18
|
+
policyAcceptsEdge(name: string, source: CompiledObjectContract, target: CompiledObjectContract): boolean;
|
|
19
|
+
concreteEndpointClasses(accepts: readonly ClassRef[]): readonly ClassRef[];
|
|
20
|
+
endpointsOverlap(left: readonly ClassRef[], right: readonly ClassRef[]): boolean;
|
|
21
|
+
branchIsTyped(branch: PatternBranch, use: CompiledPolicyUse): boolean;
|
|
22
|
+
private constraintsSatisfiable;
|
|
23
|
+
private applyInitial;
|
|
24
|
+
private applyExact;
|
|
25
|
+
private applyAnyNodeClass;
|
|
26
|
+
private applyRequirement;
|
|
27
|
+
private applyEndpoint;
|
|
28
|
+
}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { Key } from '../../../../addressing/index.js';
|
|
2
|
+
import { compareUnicode } from '../../../../addressing/ordering.js';
|
|
3
|
+
import { branchesOf, branchProduct, capBranches, targetMode, termKey, } from '../../../../language/policy/analysis/branches.js';
|
|
4
|
+
import {} from '../../../../language/policy/model/policy.js';
|
|
5
|
+
import {} from '../../../model/schema.js';
|
|
6
|
+
import { classSatisfiesAny } from '../context.js';
|
|
7
|
+
import { compiledTargetContract, callableObjectContracts, } from './contracts.js';
|
|
8
|
+
import { CompiledUnionFind } from './equality.js';
|
|
9
|
+
import { compiledEdgeAlternatives } from './variants.js';
|
|
10
|
+
/** Types one entry's Policies against the Node Classes of its own closure, as source admission. */
|
|
11
|
+
export class CompiledPolicyTyping {
|
|
12
|
+
context;
|
|
13
|
+
entry;
|
|
14
|
+
normalized;
|
|
15
|
+
allNodeClasses;
|
|
16
|
+
concreteNodeClasses;
|
|
17
|
+
constructor(context, entry, normalized, origins) {
|
|
18
|
+
this.context = context;
|
|
19
|
+
this.entry = entry;
|
|
20
|
+
this.normalized = normalized;
|
|
21
|
+
const nodeClasses = [...context.classes.values()].filter(({ value }) => value.kind === 'node' && origins.has(value.ref.origin));
|
|
22
|
+
this.allNodeClasses = nodeClasses.map(({ value }) => value.ref);
|
|
23
|
+
this.concreteNodeClasses = nodeClasses
|
|
24
|
+
.filter(({ value }) => !value.abstract)
|
|
25
|
+
.map(({ value }) => value.ref);
|
|
26
|
+
}
|
|
27
|
+
expandedBranches(name, visiting, namespace) {
|
|
28
|
+
if (visiting.has(name))
|
|
29
|
+
return undefined;
|
|
30
|
+
const declaration = this.normalized.get(name);
|
|
31
|
+
if (declaration === undefined)
|
|
32
|
+
return undefined;
|
|
33
|
+
if ('match' in declaration)
|
|
34
|
+
return branchesOf(declaration.match, namespace);
|
|
35
|
+
const nested = new Set(visiting);
|
|
36
|
+
nested.add(name);
|
|
37
|
+
const refs = 'allOf' in declaration ? declaration.allOf : declaration.anyOf;
|
|
38
|
+
const children = [];
|
|
39
|
+
for (const [index, ref] of refs.entries()) {
|
|
40
|
+
if (ref.origin !== this.entry.origin || ref.kind !== 'policy')
|
|
41
|
+
return undefined;
|
|
42
|
+
const expanded = this.expandedBranches(ref.name, nested, `${namespace}/${index}:${ref.name}`);
|
|
43
|
+
if (expanded === undefined)
|
|
44
|
+
return undefined;
|
|
45
|
+
children.push(expanded);
|
|
46
|
+
}
|
|
47
|
+
return 'allOf' in declaration ? branchProduct(children) : capBranches(children.flat());
|
|
48
|
+
}
|
|
49
|
+
policyAccepts(name, object) {
|
|
50
|
+
return this.policyBranchTyping(name, object)?.every(Boolean) ?? false;
|
|
51
|
+
}
|
|
52
|
+
policyBranchTyping(name, object) {
|
|
53
|
+
const branches = this.expandedBranches(name, new Set(), `$use:${name}`);
|
|
54
|
+
return branches?.map((branch) => this.branchIsTyped(branch, { kind: 'object', object }));
|
|
55
|
+
}
|
|
56
|
+
policyAcceptsEdge(name, source, target) {
|
|
57
|
+
const branches = this.expandedBranches(name, new Set(), `$edge-use:${name}`);
|
|
58
|
+
return (branches !== undefined &&
|
|
59
|
+
branches.every((branch) => this.branchIsTyped(branch, { kind: 'edge', source, target })));
|
|
60
|
+
}
|
|
61
|
+
concreteEndpointClasses(accepts) {
|
|
62
|
+
return this.concreteNodeClasses.filter((candidate) => classSatisfiesAny(this.context, candidate, accepts));
|
|
63
|
+
}
|
|
64
|
+
endpointsOverlap(left, right) {
|
|
65
|
+
const seed = [{ kind: 'open', requirements: [] }];
|
|
66
|
+
return this.applyEndpoint(this.applyEndpoint(seed, left), right).length > 0;
|
|
67
|
+
}
|
|
68
|
+
branchIsTyped(branch, use) {
|
|
69
|
+
if (targetMode(branch) !== use.kind)
|
|
70
|
+
return false;
|
|
71
|
+
return compiledEdgeAlternatives(branch.edges, this).some((variants) => this.constraintsSatisfiable(branch, variants, use));
|
|
72
|
+
}
|
|
73
|
+
constraintsSatisfiable(branch, variants, use) {
|
|
74
|
+
const terms = new Set(use.kind === 'object' ? ['subject', 'object'] : ['subject', 'source', 'target']);
|
|
75
|
+
for (const key of branch.variables.keys())
|
|
76
|
+
terms.add(key);
|
|
77
|
+
for (const key of branch.terms.keys())
|
|
78
|
+
terms.add(key);
|
|
79
|
+
for (const edge of branch.edges) {
|
|
80
|
+
terms.add(termKey(edge.pattern.source, edge.namespace));
|
|
81
|
+
terms.add(termKey(edge.pattern.target, edge.namespace));
|
|
82
|
+
}
|
|
83
|
+
const union = new CompiledUnionFind(terms);
|
|
84
|
+
for (const [left, right] of branch.equalities)
|
|
85
|
+
union.join(left, right);
|
|
86
|
+
for (const variant of variants)
|
|
87
|
+
for (const [left, right] of variant.equalities)
|
|
88
|
+
union.join(left, right);
|
|
89
|
+
const constraints = new Map();
|
|
90
|
+
for (const variant of variants) {
|
|
91
|
+
for (const [term, accepts] of variant.constraints) {
|
|
92
|
+
const root = union.find(term);
|
|
93
|
+
const values = constraints.get(root) ?? [];
|
|
94
|
+
values.push(accepts);
|
|
95
|
+
constraints.set(root, values);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
const groups = new Map();
|
|
99
|
+
for (const term of terms) {
|
|
100
|
+
const root = union.find(term);
|
|
101
|
+
const values = groups.get(root) ?? [];
|
|
102
|
+
values.push(term);
|
|
103
|
+
groups.set(root, values);
|
|
104
|
+
}
|
|
105
|
+
for (const [root, members] of groups) {
|
|
106
|
+
let candidates = [{ kind: 'open', requirements: [] }];
|
|
107
|
+
for (const member of members) {
|
|
108
|
+
candidates = this.applyInitial(candidates, member, branch, use);
|
|
109
|
+
if (candidates.length === 0)
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
for (const endpoint of constraints.get(root) ?? []) {
|
|
113
|
+
candidates = this.applyEndpoint(candidates, endpoint);
|
|
114
|
+
if (candidates.length === 0)
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
applyInitial(candidates, term, branch, use) {
|
|
121
|
+
if (term === 'subject')
|
|
122
|
+
return this.applyAnyNodeClass(candidates);
|
|
123
|
+
const contract = compiledTargetContract(term, use);
|
|
124
|
+
if (contract !== undefined) {
|
|
125
|
+
return contract.kind === 'exact'
|
|
126
|
+
? this.applyExact(candidates, contract.ref)
|
|
127
|
+
: uniqueCompiledCandidates(this.allNodeClasses.flatMap((ref) => this.applyExact(candidates, ref)));
|
|
128
|
+
}
|
|
129
|
+
const referenced = branch.terms.get(term);
|
|
130
|
+
if (referenced?.kind === 'ref') {
|
|
131
|
+
const contract = callableObjectContracts(this.context, this.entry, 0, undefined, referenced)?.[0];
|
|
132
|
+
return contract?.kind === 'exact' ? this.applyExact(candidates, contract.ref) : [];
|
|
133
|
+
}
|
|
134
|
+
const selector = branch.variables.get(term);
|
|
135
|
+
if (selector === undefined)
|
|
136
|
+
return [];
|
|
137
|
+
if (selector.kind === 'exact')
|
|
138
|
+
return this.applyExact(candidates, selector.class);
|
|
139
|
+
if (selector.kind === 'any')
|
|
140
|
+
return candidates;
|
|
141
|
+
return this.applyRequirement(candidates, selector.class);
|
|
142
|
+
}
|
|
143
|
+
applyExact(candidates, exact) {
|
|
144
|
+
return uniqueCompiledCandidates(candidates.flatMap((candidate) => {
|
|
145
|
+
if (candidate.kind === 'exact')
|
|
146
|
+
return Key.of(candidate.ref) === Key.of(exact) ? [candidate] : [];
|
|
147
|
+
return candidate.requirements.every((required) => classSatisfiesAny(this.context, exact, [required]))
|
|
148
|
+
? [{ kind: 'exact', ref: exact }]
|
|
149
|
+
: [];
|
|
150
|
+
}));
|
|
151
|
+
}
|
|
152
|
+
applyAnyNodeClass(candidates) {
|
|
153
|
+
return uniqueCompiledCandidates(candidates.flatMap((candidate) => candidate.kind === 'exact'
|
|
154
|
+
? [candidate]
|
|
155
|
+
: this.allNodeClasses
|
|
156
|
+
.filter((ref) => candidate.requirements.every((required) => classSatisfiesAny(this.context, ref, [required])))
|
|
157
|
+
.map((ref) => ({ kind: 'exact', ref }))));
|
|
158
|
+
}
|
|
159
|
+
applyRequirement(candidates, required) {
|
|
160
|
+
const result = [];
|
|
161
|
+
for (const candidate of candidates) {
|
|
162
|
+
if (candidate.kind === 'exact') {
|
|
163
|
+
if (classSatisfiesAny(this.context, candidate.ref, [required]))
|
|
164
|
+
result.push(candidate);
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
result.push({
|
|
168
|
+
kind: 'open',
|
|
169
|
+
requirements: uniqueClassRefs([...candidate.requirements, required]),
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return uniqueCompiledCandidates(result);
|
|
174
|
+
}
|
|
175
|
+
applyEndpoint(candidates, accepts) {
|
|
176
|
+
const result = [];
|
|
177
|
+
for (const candidate of candidates) {
|
|
178
|
+
if (candidate.kind === 'exact') {
|
|
179
|
+
if (classSatisfiesAny(this.context, candidate.ref, accepts))
|
|
180
|
+
result.push(candidate);
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
for (const accept of accepts) {
|
|
184
|
+
result.push({
|
|
185
|
+
kind: 'open',
|
|
186
|
+
requirements: uniqueClassRefs([...candidate.requirements, accept]),
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return uniqueCompiledCandidates(result);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
function uniqueCompiledCandidates(values) {
|
|
195
|
+
const result = new Map();
|
|
196
|
+
for (const value of values) {
|
|
197
|
+
const key = value.kind === 'exact'
|
|
198
|
+
? `exact:${Key.of(value.ref)}`
|
|
199
|
+
: `open:${value.requirements.map(Key.of).sort(compareUnicode).join('|')}`;
|
|
200
|
+
result.set(key, value);
|
|
201
|
+
}
|
|
202
|
+
return [...result.values()];
|
|
203
|
+
}
|
|
204
|
+
function uniqueClassRefs(values) {
|
|
205
|
+
return [...new Map(values.map((value) => [Key.of(value), value])).values()];
|
|
206
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
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[])[];
|
|
@@ -0,0 +1,65 @@
|
|
|
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,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type CompiledSchema } from '../model/schema.js';
|
|
2
2
|
/**
|
|
3
3
|
* Re-admit contextual Language laws after the portable compiled grammar and
|
|
4
4
|
* exact closure have been established. This module deliberately depends only
|