@telorun/analyzer 0.64.0 → 0.66.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.
Files changed (114) hide show
  1. package/dist/analyzer.d.ts +1 -1
  2. package/dist/analyzer.d.ts.map +1 -1
  3. package/dist/analyzer.js +175 -65
  4. package/dist/call-graph.d.ts.map +1 -1
  5. package/dist/call-graph.js +7 -1
  6. package/dist/cel-environment.d.ts +12 -0
  7. package/dist/cel-environment.d.ts.map +1 -1
  8. package/dist/cel-environment.js +35 -19
  9. package/dist/cel-scope.d.ts.map +1 -1
  10. package/dist/cel-scope.js +24 -4
  11. package/dist/definition-registry.d.ts +47 -6
  12. package/dist/definition-registry.d.ts.map +1 -1
  13. package/dist/definition-registry.js +82 -13
  14. package/dist/eval-paths.d.ts +68 -0
  15. package/dist/eval-paths.d.ts.map +1 -1
  16. package/dist/eval-paths.js +138 -0
  17. package/dist/flatten-for-analyzer.d.ts +1 -1
  18. package/dist/flatten-for-analyzer.js +1 -1
  19. package/dist/import-resolution-diagnostics.d.ts +1 -1
  20. package/dist/import-resolution-diagnostics.js +1 -1
  21. package/dist/index.d.ts +13 -9
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +8 -6
  24. package/dist/manifest-visitor.d.ts.map +1 -1
  25. package/dist/manifest-visitor.js +8 -1
  26. package/dist/migrations/entries/index.d.ts.map +1 -1
  27. package/dist/migrations/entries/index.js +2 -0
  28. package/dist/migrations/entries/schema-prepare-bucket.json +27 -0
  29. package/dist/peer-binding.d.ts +232 -0
  30. package/dist/peer-binding.d.ts.map +1 -0
  31. package/dist/peer-binding.js +418 -0
  32. package/dist/ref-slot.d.ts +13 -0
  33. package/dist/ref-slot.d.ts.map +1 -1
  34. package/dist/ref-slot.js +26 -0
  35. package/dist/reference-field-map.d.ts +28 -0
  36. package/dist/reference-field-map.d.ts.map +1 -1
  37. package/dist/reference-field-map.js +25 -0
  38. package/dist/referrer-rule.d.ts +17 -0
  39. package/dist/referrer-rule.d.ts.map +1 -1
  40. package/dist/referrer-rule.js +4 -1
  41. package/dist/release/index.d.ts +1 -1
  42. package/dist/release/index.js +1 -1
  43. package/dist/resource-rule.d.ts +40 -27
  44. package/dist/resource-rule.d.ts.map +1 -1
  45. package/dist/resource-rule.js +61 -7
  46. package/dist/rule-condition.d.ts +11 -0
  47. package/dist/rule-condition.d.ts.map +1 -1
  48. package/dist/rule-condition.js +13 -0
  49. package/dist/schema-compat.d.ts +59 -22
  50. package/dist/schema-compat.d.ts.map +1 -1
  51. package/dist/schema-compat.js +60 -75
  52. package/dist/schema-error-report.d.ts +68 -0
  53. package/dist/schema-error-report.d.ts.map +1 -0
  54. package/dist/schema-error-report.js +356 -0
  55. package/dist/schema-projection.d.ts +106 -4
  56. package/dist/schema-projection.d.ts.map +1 -1
  57. package/dist/schema-projection.js +206 -18
  58. package/dist/telo-version.d.ts +1 -1
  59. package/dist/telo-version.js +1 -1
  60. package/dist/validate-cel-context.d.ts +1 -17
  61. package/dist/validate-cel-context.d.ts.map +1 -1
  62. package/dist/validate-cel-context.js +5 -70
  63. package/dist/validate-nested-inline.d.ts +22 -1
  64. package/dist/validate-nested-inline.d.ts.map +1 -1
  65. package/dist/validate-nested-inline.js +17 -9
  66. package/dist/validate-reference-forms.d.ts +10 -0
  67. package/dist/validate-reference-forms.d.ts.map +1 -1
  68. package/dist/validate-reference-forms.js +23 -0
  69. package/dist/validate-references.d.ts.map +1 -1
  70. package/dist/validate-references.js +9 -2
  71. package/dist/validate-referrer-rules.d.ts +38 -4
  72. package/dist/validate-referrer-rules.d.ts.map +1 -1
  73. package/dist/validate-referrer-rules.js +139 -31
  74. package/dist/validate-resource-rules.d.ts +11 -2
  75. package/dist/validate-resource-rules.d.ts.map +1 -1
  76. package/dist/validate-resource-rules.js +18 -12
  77. package/dist/validate-schema-projection.d.ts.map +1 -1
  78. package/dist/validate-schema-projection.js +33 -2
  79. package/dist/validate-step-inputs.js +11 -3
  80. package/dist/with-synthetic-positions.d.ts +1 -1
  81. package/dist/with-synthetic-positions.js +1 -1
  82. package/package.json +3 -3
  83. package/src/analyzer.ts +211 -68
  84. package/src/call-graph.ts +7 -1
  85. package/src/cel-environment.ts +48 -19
  86. package/src/cel-scope.ts +24 -6
  87. package/src/definition-registry.ts +90 -11
  88. package/src/eval-paths.ts +152 -0
  89. package/src/flatten-for-analyzer.ts +1 -1
  90. package/src/import-resolution-diagnostics.ts +1 -1
  91. package/src/index.ts +55 -6
  92. package/src/manifest-visitor.ts +8 -1
  93. package/src/migrations/entries/index.ts +2 -0
  94. package/src/migrations/entries/schema-prepare-bucket.json +27 -0
  95. package/src/peer-binding.ts +641 -0
  96. package/src/ref-slot.ts +36 -0
  97. package/src/reference-field-map.ts +42 -0
  98. package/src/referrer-rule.ts +20 -1
  99. package/src/release/index.ts +1 -1
  100. package/src/resource-rule.ts +69 -7
  101. package/src/rule-condition.ts +15 -0
  102. package/src/schema-compat.ts +92 -79
  103. package/src/schema-error-report.ts +417 -0
  104. package/src/schema-projection.ts +283 -20
  105. package/src/telo-version.ts +1 -1
  106. package/src/validate-cel-context.ts +6 -71
  107. package/src/validate-nested-inline.ts +35 -14
  108. package/src/validate-reference-forms.ts +22 -0
  109. package/src/validate-references.ts +15 -2
  110. package/src/validate-referrer-rules.ts +215 -28
  111. package/src/validate-resource-rules.ts +26 -12
  112. package/src/validate-schema-projection.ts +50 -1
  113. package/src/validate-step-inputs.ts +10 -4
  114. package/src/with-synthetic-positions.ts +1 -1
package/dist/cel-scope.js CHANGED
@@ -293,10 +293,16 @@ export class CelScopeResolver {
293
293
  enterResource(m, definition) {
294
294
  const { allManifests, defs, aliases, scopes } = this.inputs;
295
295
  this.invocationContext = m.metadata?.xTeloInvocationContext;
296
- this.stepContext = definition?.schema
297
- ? buildStepContextSchema(m, definition.schema, allManifests, defs, aliases, scopes)
296
+ // The INHERITANCE-RESOLVED schema at both sites, for the reason the CEL
297
+ // context regions use it: an `extends` child is authored against
298
+ // merge(parent, own), so a step body or a `catch:` region the parent
299
+ // declares is in force on the child. All three consumers share one memo so
300
+ // they cannot come to disagree about which schema a kind means.
301
+ const authorSchema = defs.effectiveSchemaOf(definition);
302
+ this.stepContext = authorSchema
303
+ ? buildStepContextSchema(m, authorSchema, allManifests, defs, aliases, scopes)
298
304
  : undefined;
299
- this.errorScopes = collectErrorContextScopes(definition?.schema);
305
+ this.errorScopes = collectErrorContextScopes(authorSchema);
300
306
  }
301
307
  /**
302
308
  * What the expression at `site` is typed against.
@@ -337,7 +343,21 @@ export class CelScopeResolver {
337
343
  const base = matched ?? { type: "object", properties: {}, additionalProperties: true };
338
344
  matched = {
339
345
  ...base,
340
- properties: { ...(base.properties ?? {}), steps: this.stepContext },
346
+ properties: {
347
+ // `inputs` is in scope beside `steps` wherever a step body runs — the
348
+ // step engine evaluates a step against the enclosing kind's own
349
+ // arguments, which is what `steps[0].inputs.x` reads. Modelled here
350
+ // because it was modelled NOWHERE: the step context is open, so a
351
+ // chain through it was never checked and the name's absence went
352
+ // unnoticed until something asked whether the root existed.
353
+ //
354
+ // OPEN, not typed from the kind's `inputType`: closing it would newly
355
+ // reject every read of an argument the contract does not spell out,
356
+ // which is a separate decision from knowing the name is legal.
357
+ inputs: { type: "object", additionalProperties: true },
358
+ ...(base.properties ?? {}),
359
+ steps: this.stepContext,
360
+ },
341
361
  };
342
362
  }
343
363
  // `error` is only in scope inside an error-bearing branch (e.g. a
@@ -1,7 +1,7 @@
1
1
  import type { ResourceDefinition, ResourceManifest } from "@telorun/sdk";
2
2
  import type { AliasResolver } from "./alias-resolver.js";
3
3
  import { type ReferenceFieldMap } from "./reference-field-map.js";
4
- /** Pure kind ResourceDefinition map. No controller loading, no lifecycle. */
4
+ import { type SchemaIssue } from "./schema-error-report.js";
5
5
  export declare class DefinitionRegistry {
6
6
  constructor();
7
7
  /** Per-instance AJV for cross-module $ref resolution. Isolated so each registry
@@ -9,6 +9,7 @@ export declare class DefinitionRegistry {
9
9
  * across analyze() calls and no unbounded growth across the process lifetime. */
10
10
  private readonly ajv;
11
11
  private readonly registeredSchemaIds;
12
+ private readonly compiledValidators;
12
13
  /** The subset of `registeredSchemaIds` claimed by a kind's schema. Kinds and
13
14
  * named `Telo.Type`s share one `telo://<module>/<Name>` id space, so this is
14
15
  * what lets a colliding type name be reported instead of silently dropped. */
@@ -17,6 +18,9 @@ export declare class DefinitionRegistry {
17
18
  private readonly fieldMaps;
18
19
  /** Reverse inheritance index: parent kind → direct child kinds. */
19
20
  private readonly extendedBy;
21
+ /** Memoized inheritance-resolved schemas. `null` records "resolved to
22
+ * nothing", so a kind with no schema is not re-walked on every resource. */
23
+ private readonly effectiveSchemas;
20
24
  /** DEPRECATED module identity table: identity string → canonical module name
21
25
  * ("std/pipeline" → "pipeline"). Serves only the legacy
22
26
  * `<namespace>/<module>#<Kind>` form of `x-telo-ref`, kept resolvable for
@@ -77,12 +81,28 @@ export declare class DefinitionRegistry {
77
81
  * sanctioned way to reuse one, so a comparator that cannot follow the
78
82
  * reference judges two opaque nodes and learns nothing. */
79
83
  schemaForId(id: string): Record<string, any> | undefined;
80
- /** Validates data against a schema using this registry's AJV instance, which has all
81
- * registered definition schemas loaded enabling cross-module $ref resolution.
82
- * A compile failure returns `[]` here; it is surfaced loudly (once, on the
83
- * owning definition) by `schemaCompileError` via the analyzer's
84
- * definition-schema compile check, so resources are never silently skipped. */
84
+ /**
85
+ * Validates a resource's configuration against its kind's schema, with the
86
+ * offending field's path — what a `SCHEMA_VIOLATION` diagnostic is built from.
87
+ *
88
+ * On THIS registry's AJV, which is the point: it holds every registered
89
+ * definition schema and every named `Telo.Type`, so a kind whose schema
90
+ * references a shape declared elsewhere is checked rather than skipped. The
91
+ * module-level instance this used to run on had none of them registered, so
92
+ * such a schema failed to compile and the failure was swallowed — a resource
93
+ * could be arbitrarily wrong and `telo check` reported nothing, while the
94
+ * kernel (whose validator does resolve the reference) rejected it at boot.
95
+ * Two AJVs answering one question is what made that possible; there is now
96
+ * one, and it is the same one `schemaCompileError` reports through.
97
+ */
85
98
  validateWithRefs(data: unknown, schema: Record<string, any>): string[];
99
+ /** {@link validateWithRefs}, with the path each issue is anchored at. */
100
+ validateResourceConfig(data: unknown, schema: Record<string, any>): SchemaIssue[];
101
+ /** Memoized per schema OBJECT — the analyzer validates every resource of a
102
+ * kind against the same one, and this runs at keystroke time in an editor.
103
+ * A schema AJV refuses compiles to `undefined`; that is reported once,
104
+ * anchored on the owning definition, by `schemaCompileError`. */
105
+ private compiledFor;
86
106
  /** Returns the AJV compile error for `schema`, or `undefined` when it compiles.
87
107
  * Compiles on this registry's instance, which has every loaded module schema
88
108
  * plus the manifest root registered, so local `#/$defs`, `telo://manifest`,
@@ -114,6 +134,27 @@ export declare class DefinitionRegistry {
114
134
  * never registered. */
115
135
  resolveRef(xTeloRef: string): string | undefined;
116
136
  resolve(kind: string): ResourceDefinition | undefined;
137
+ /**
138
+ * The kind's AUTHOR-FACING schema — its own merged with everything it
139
+ * inherits along `extends` — memoized per kind.
140
+ *
141
+ * This is what every consumer reading a kind's schema to interpret an
142
+ * INSTANCE must use, because that is the schema the instance was authored
143
+ * against and the one the kernel stamps at definition registration. Reading
144
+ * `resolve(kind).schema` instead sees only what the leaf declared, so an
145
+ * annotation on a parent — a CEL context region, a step body, an error
146
+ * context — is invisible on every child, silently and per consumer. Sharing
147
+ * one memo is what keeps those consumers from drifting apart.
148
+ *
149
+ * Lazy for the same reason `getFieldMap` is: a child registered before its
150
+ * parent still sees the inherited half once both are present.
151
+ */
152
+ effectiveSchema(kind: string): Record<string, unknown> | undefined;
153
+ /** The effective schema for a definition, by the kind it is registered under.
154
+ * Falls back to the definition's own schema when it is not in this registry
155
+ * (a synthesized or not-yet-registered kind), which is the pre-inheritance
156
+ * behaviour and the safe direction: it types less, never wrongly. */
157
+ effectiveSchemaOf(definition: ResourceDefinition | undefined): Record<string, unknown> | undefined;
117
158
  /** Returns the reference field map for the given kind, computed lazily from the
118
159
  * kind's AUTHOR-FACING (inheritance-resolved) schema and memoized. Lazy so a
119
160
  * child registered before its parent still sees the parent's inherited ref
@@ -1 +1 @@
1
- {"version":3,"file":"definition-registry.d.ts","sourceRoot":"","sources":["../src/definition-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,0BAA0B,CAAC;AAIlC,+EAA+E;AAC/E,qBAAa,kBAAkB;;IAK7B;;sFAEkF;IAClF,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAqB;IACzD;;mFAE+E;IAC/E,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAqB;IAEzD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAyC;IAC9D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwC;IAClE,mEAAmE;IACnE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA+B;IAC1D;;;;wEAIoE;IACpE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA6B;IAEzD,QAAQ,CAAC,UAAU,EAAE,kBAAkB,GAAG,IAAI;IAoC9C,OAAO,CAAC,aAAa;IASrB;;;;;;;;;;;;;2FAauF;IACvF,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAK1E;;;;;;;;;;gFAU4E;IAC5E,uBAAuB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO;IAQzE;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,YAAY;IASpB;uFACmF;IACnF,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAIhC;;;gEAG4D;IAC5D,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS;IAMxD;;;;oFAIgF;IAChF,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,EAAE;IAWtE;;;;;;iCAM6B;IAC7B,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,GAAG,SAAS;IASnE;;;;4EAIwE;IACxE,OAAO,CAAC,iBAAiB;IAqBzB;;;;;;;;;;;;;;4BAcwB;IACxB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAShD,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAIrD;;;uCAGmC;IACnC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAWxD,gGAAgG;IAChG,kBAAkB,CAChB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;QAAE,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;KAAE,GACvD,iBAAiB,GAAG,SAAS;IAOhC;;;;;;;;qFAQiF;IACjF,2BAA2B,CACzB,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,EAAE,aAAa,EACtB,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,GAC1C,iBAAiB,GAAG,SAAS;IAkChC;;;;;;;;;;;;;OAaG;IACH,qBAAqB,CACnB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,aAAa,GACxB,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS;IAsBlC,OAAO,CAAC,uBAAuB;IAU/B;;qEAEiE;IACjE,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,kBAAkB,EAAE;IAgBxD,KAAK,IAAI,MAAM,EAAE;CAGlB"}
1
+ {"version":3,"file":"definition-registry.d.ts","sourceRoot":"","sources":["../src/definition-registry.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,9 @@
1
1
  import { canonicalTypeSchemaId } from "@telorun/sdk";
2
2
  import { KERNEL_BUILTINS } from "./builtins.js";
3
3
  import { buildFieldMapAtPath, buildReferenceFieldMap, isSchemaFromEntry, } from "./reference-field-map.js";
4
- import { createAjv, formatSingleError, navigateJsonPointer } from "./schema-compat.js";
4
+ import { createAjv, navigateJsonPointer } from "./schema-compat.js";
5
+ import { formatSingleError, reduceSchemaErrors, schemaIssues, } from "./schema-error-report.js";
5
6
  import { effectiveAuthorSchema } from "./extends-resolution.js";
6
- /** Pure kind → ResourceDefinition map. No controller loading, no lifecycle. */
7
7
  export class DefinitionRegistry {
8
8
  constructor() {
9
9
  for (const def of KERNEL_BUILTINS)
@@ -14,6 +14,7 @@ export class DefinitionRegistry {
14
14
  * across analyze() calls and no unbounded growth across the process lifetime. */
15
15
  ajv = createAjv();
16
16
  registeredSchemaIds = new Set();
17
+ compiledValidators = new WeakMap();
17
18
  /** The subset of `registeredSchemaIds` claimed by a kind's schema. Kinds and
18
19
  * named `Telo.Type`s share one `telo://<module>/<Name>` id space, so this is
19
20
  * what lets a colliding type name be reported instead of silently dropped. */
@@ -22,6 +23,9 @@ export class DefinitionRegistry {
22
23
  fieldMaps = new Map();
23
24
  /** Reverse inheritance index: parent kind → direct child kinds. */
24
25
  extendedBy = new Map();
26
+ /** Memoized inheritance-resolved schemas. `null` records "resolved to
27
+ * nothing", so a kind with no schema is not re-walked on every resource. */
28
+ effectiveSchemas = new Map();
25
29
  /** DEPRECATED module identity table: identity string → canonical module name
26
30
  * ("std/pipeline" → "pipeline"). Serves only the legacy
27
31
  * `<namespace>/<module>#<Kind>` form of `x-telo-ref`, kept resolvable for
@@ -37,6 +41,7 @@ export class DefinitionRegistry {
37
41
  // so any already-computed map recomputes against the now-larger def set; the
38
42
  // maps rebuild lazily on first `getFieldMap` (after all defs are registered).
39
43
  this.fieldMaps.clear();
44
+ this.effectiveSchemas.clear();
40
45
  // `capability` populates extendedBy for backward-compat with the legacy pattern where
41
46
  // a concrete definition overloaded `capability: <AbstractKind>` to mean "implements
42
47
  // this abstract." The canonical pattern is `extends` (below). Both populate the index,
@@ -152,22 +157,49 @@ export class DefinitionRegistry {
152
157
  const schema = compiled?.schema;
153
158
  return schema && typeof schema === "object" ? schema : undefined;
154
159
  }
155
- /** Validates data against a schema using this registry's AJV instance, which has all
156
- * registered definition schemas loaded enabling cross-module $ref resolution.
157
- * A compile failure returns `[]` here; it is surfaced loudly (once, on the
158
- * owning definition) by `schemaCompileError` via the analyzer's
159
- * definition-schema compile check, so resources are never silently skipped. */
160
+ /**
161
+ * Validates a resource's configuration against its kind's schema, with the
162
+ * offending field's path — what a `SCHEMA_VIOLATION` diagnostic is built from.
163
+ *
164
+ * On THIS registry's AJV, which is the point: it holds every registered
165
+ * definition schema and every named `Telo.Type`, so a kind whose schema
166
+ * references a shape declared elsewhere is checked rather than skipped. The
167
+ * module-level instance this used to run on had none of them registered, so
168
+ * such a schema failed to compile and the failure was swallowed — a resource
169
+ * could be arbitrarily wrong and `telo check` reported nothing, while the
170
+ * kernel (whose validator does resolve the reference) rejected it at boot.
171
+ * Two AJVs answering one question is what made that possible; there is now
172
+ * one, and it is the same one `schemaCompileError` reports through.
173
+ */
160
174
  validateWithRefs(data, schema) {
161
- let validate;
175
+ const validate = this.compiledFor(schema);
176
+ if (!validate || validate(data))
177
+ return [];
178
+ return reduceSchemaErrors(validate.errors).map(formatSingleError);
179
+ }
180
+ /** {@link validateWithRefs}, with the path each issue is anchored at. */
181
+ validateResourceConfig(data, schema) {
182
+ const validate = this.compiledFor(schema);
183
+ if (!validate || validate(data))
184
+ return [];
185
+ return schemaIssues(validate.errors);
186
+ }
187
+ /** Memoized per schema OBJECT — the analyzer validates every resource of a
188
+ * kind against the same one, and this runs at keystroke time in an editor.
189
+ * A schema AJV refuses compiles to `undefined`; that is reported once,
190
+ * anchored on the owning definition, by `schemaCompileError`. */
191
+ compiledFor(schema) {
192
+ const cached = this.compiledValidators.get(schema);
193
+ if (cached)
194
+ return cached;
162
195
  try {
163
- validate = this.ajv.compile(schema);
196
+ const validate = this.ajv.compile(schema);
197
+ this.compiledValidators.set(schema, validate);
198
+ return validate;
164
199
  }
165
200
  catch {
166
- return [];
201
+ return undefined;
167
202
  }
168
- if (validate(data))
169
- return [];
170
- return (validate.errors ?? []).map(formatSingleError);
171
203
  }
172
204
  /** Returns the AJV compile error for `schema`, or `undefined` when it compiles.
173
205
  * Compiles on this registry's instance, which has every loaded module schema
@@ -235,6 +267,43 @@ export class DefinitionRegistry {
235
267
  resolve(kind) {
236
268
  return this.defs.get(kind);
237
269
  }
270
+ /**
271
+ * The kind's AUTHOR-FACING schema — its own merged with everything it
272
+ * inherits along `extends` — memoized per kind.
273
+ *
274
+ * This is what every consumer reading a kind's schema to interpret an
275
+ * INSTANCE must use, because that is the schema the instance was authored
276
+ * against and the one the kernel stamps at definition registration. Reading
277
+ * `resolve(kind).schema` instead sees only what the leaf declared, so an
278
+ * annotation on a parent — a CEL context region, a step body, an error
279
+ * context — is invisible on every child, silently and per consumer. Sharing
280
+ * one memo is what keeps those consumers from drifting apart.
281
+ *
282
+ * Lazy for the same reason `getFieldMap` is: a child registered before its
283
+ * parent still sees the inherited half once both are present.
284
+ */
285
+ effectiveSchema(kind) {
286
+ const cached = this.effectiveSchemas.get(kind);
287
+ if (cached !== undefined)
288
+ return cached ?? undefined;
289
+ const def = this.defs.get(kind);
290
+ if (!def)
291
+ return undefined;
292
+ const schema = effectiveAuthorSchema(def, (k) => this.resolve(k));
293
+ this.effectiveSchemas.set(kind, schema ?? null);
294
+ return schema;
295
+ }
296
+ /** The effective schema for a definition, by the kind it is registered under.
297
+ * Falls back to the definition's own schema when it is not in this registry
298
+ * (a synthesized or not-yet-registered kind), which is the pre-inheritance
299
+ * behaviour and the safe direction: it types less, never wrongly. */
300
+ effectiveSchemaOf(definition) {
301
+ if (!definition)
302
+ return undefined;
303
+ const { name, module: mod } = definition.metadata;
304
+ const resolved = this.effectiveSchema(mod ? `${mod}.${name}` : name);
305
+ return resolved ?? definition.schema;
306
+ }
238
307
  /** Returns the reference field map for the given kind, computed lazily from the
239
308
  * kind's AUTHOR-FACING (inheritance-resolved) schema and memoized. Lazy so a
240
309
  * child registered before its parent still sees the parent's inherited ref
@@ -1,3 +1,24 @@
1
+ /**
2
+ * WHERE IS CEL EVALUATED — the one reader, and the one decision built on it.
3
+ *
4
+ * Two independent ways a value is evaluated, and every consumer needs both:
5
+ * `x-telo-eval` names a field directly, while a REGION annotation
6
+ * (`x-telo-context` / `x-telo-step-context` / `x-telo-error-context`, or a step
7
+ * body) covers everything beneath it — which is how `Run.Choice`'s rows and an
8
+ * `Http.Api` route's `returns:` entries hold expressions while declaring no
9
+ * annotation of their own.
10
+ *
11
+ * The consumers are on both sides of the runtime: `telo check` decides whether a
12
+ * `!cel` here is live (`CEL_IN_NON_EVAL_FIELD`) or resolved at startup
13
+ * (`OBSERVED_STATE_IN_STARTUP_FIELD`), the kernel decides what to expand, and
14
+ * the editor decides whether to offer an expression at all. The editor's answer
15
+ * is a CLAIM that `telo check` will accept what it writes, so a second
16
+ * implementation there is a promise nothing keeps — it read `x-telo-eval` alone
17
+ * and left every predicate inside a region as a bare checkbox, with no way to
18
+ * write the expression the field exists to hold.
19
+ *
20
+ * Browser-safe: no Node built-ins.
21
+ */
1
22
  /**
2
23
  * The single containment rule for `x-telo-eval` paths, shared by every matcher so
3
24
  * the analyzer's coverage decision and the kernel's expansion/exclusion can't
@@ -22,4 +43,51 @@ export declare function buildEvalPaths(schema: Record<string, any>): {
22
43
  compile: string[];
23
44
  runtime: string[];
24
45
  };
46
+ /** True when this schema node declares a CEL-bearing region. Node-level, so a
47
+ * consumer holding one schema (an editor rendering one field) asks it directly
48
+ * rather than deriving scopes it would then have to match against. */
49
+ export declare function declaresCelRegion(schema: unknown): boolean;
50
+ /**
51
+ * Walk a JSON Schema tree and collect the JSONPath scopes of every field that
52
+ * declares a CEL-bearing region (`x-telo-context` / `x-telo-step-context` /
53
+ * `x-telo-error-context`). Used — alongside `x-telo-eval` paths — to decide
54
+ * whether a `!cel` expression sits in a slot the runtime actually evaluates.
55
+ * Scopes use the same `$.a.b[*]` form as `extractContextsFromSchema`, matched
56
+ * against expression paths with `pathMatchesScope`.
57
+ */
58
+ export declare function extractCelRegionScopes(schema: Record<string, any>, path?: string): string[];
59
+ /**
60
+ * Returns true when a CEL expression path (from walkCelExpressions, e.g. "routes[0].inputs.q")
61
+ * falls within the scope of a context (e.g. "$.routes[*].inputs").
62
+ *
63
+ * The scope is matched directly (no sibling sharing): a context at "$.routes[*].inputs" only
64
+ * applies to expressions whose path starts with "routes[N].inputs", not to other sibling fields.
65
+ */
66
+ export declare function pathMatchesScope(exprPath: string, scope: string): boolean;
67
+ /** Every place a schema says its values are evaluated: the `x-telo-eval` paths,
68
+ * by mode, plus the scopes of the regions that cover their contents. */
69
+ export interface CelEvalSites {
70
+ compile: readonly string[];
71
+ runtime: readonly string[];
72
+ regions: readonly string[];
73
+ }
74
+ export declare const NO_CEL_EVAL_SITES: CelEvalSites;
75
+ export declare function celEvalSites(schema: Record<string, any> | undefined): CelEvalSites;
76
+ /** The union of several schemas' sites — a kind's own and its capability
77
+ * abstract's, which is how a `Telo.Provider`'s implicit compile-eval reaches
78
+ * fields the provider never annotated. */
79
+ export declare function mergeCelEvalSites(...sites: CelEvalSites[]): CelEvalSites;
80
+ /**
81
+ * Whether the value at `path` is evaluated, and when — null for a field whose
82
+ * value is read as a literal.
83
+ *
84
+ * `compile` wins over `runtime`, and both win over a region: a field's own
85
+ * annotation is more specific than the region it sits in, which is the same
86
+ * precedence a nested annotation has over an enclosing one. A region resolves to
87
+ * `runtime` because that is what a region IS — a per-invocation scope naming
88
+ * what its expressions can read.
89
+ *
90
+ * `path` is the `walkCelExpressions` spelling (`routes[0].returns[1].when`).
91
+ */
92
+ export declare function celEvalModeAt(sites: CelEvalSites, path: string): "compile" | "runtime" | null;
25
93
  //# sourceMappingURL=eval-paths.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"eval-paths.d.ts","sourceRoot":"","sources":["../src/eval-paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAKxE;AAED;+BAC+B;AAC/B,wBAAgB,cAAc,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEtF;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG;IAC3D,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAcA"}
1
+ {"version":3,"file":"eval-paths.d.ts","sourceRoot":"","sources":["../src/eval-paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAIH;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAKxE;AAED;+BAC+B;AAC/B,wBAAgB,cAAc,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEtF;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG;IAC3D,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAcA;AAiCD;;uEAEuE;AACvE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAI1D;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,IAAI,SAAM,GAAG,MAAM,EAAE,CAqBxF;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAoBzE;AAED;yEACyE;AACzE,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5B;AAED,eAAO,MAAM,iBAAiB,EAAE,YAAwD,CAAC;AAEzF,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,GAAG,YAAY,CAIlF;AAED;;2CAE2C;AAC3C,wBAAgB,iBAAiB,CAAC,GAAG,KAAK,EAAE,YAAY,EAAE,GAAG,YAAY,CAMxE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,YAAY,EACnB,IAAI,EAAE,MAAM,GACX,SAAS,GAAG,SAAS,GAAG,IAAI,CAK9B"}
@@ -1,3 +1,25 @@
1
+ /**
2
+ * WHERE IS CEL EVALUATED — the one reader, and the one decision built on it.
3
+ *
4
+ * Two independent ways a value is evaluated, and every consumer needs both:
5
+ * `x-telo-eval` names a field directly, while a REGION annotation
6
+ * (`x-telo-context` / `x-telo-step-context` / `x-telo-error-context`, or a step
7
+ * body) covers everything beneath it — which is how `Run.Choice`'s rows and an
8
+ * `Http.Api` route's `returns:` entries hold expressions while declaring no
9
+ * annotation of their own.
10
+ *
11
+ * The consumers are on both sides of the runtime: `telo check` decides whether a
12
+ * `!cel` here is live (`CEL_IN_NON_EVAL_FIELD`) or resolved at startup
13
+ * (`OBSERVED_STATE_IN_STARTUP_FIELD`), the kernel decides what to expand, and
14
+ * the editor decides whether to offer an expression at all. The editor's answer
15
+ * is a CLAIM that `telo check` will accept what it writes, so a second
16
+ * implementation there is a promise nothing keeps — it read `x-telo-eval` alone
17
+ * and left every predicate inside a region as a bare checkbox, with no way to
18
+ * write the expression the field exists to hold.
19
+ *
20
+ * Browser-safe: no Node built-ins.
21
+ */
22
+ import { isStepSlot } from "./step-slot.js";
1
23
  /**
2
24
  * The single containment rule for `x-telo-eval` paths, shared by every matcher so
3
25
  * the analyzer's coverage decision and the kernel's expansion/exclusion can't
@@ -53,3 +75,119 @@ function collectEvalPathsNode(node, path, compile, runtime) {
53
75
  }
54
76
  }
55
77
  }
78
+ /** Schema keys that declare a CEL-bearing region: a field carrying any of these
79
+ * is evaluated at runtime, so a `!cel` inside it (or a descendant) is live. A
80
+ * STEP BODY is one too, and says so through the grammar its items point at
81
+ * rather than through a key — {@link isStepSlot} reads either spelling. */
82
+ const CEL_REGION_KEYS = [
83
+ "x-telo-context",
84
+ "x-telo-step-context",
85
+ "x-telo-error-context",
86
+ ];
87
+ /** True when this schema node declares a CEL-bearing region. Node-level, so a
88
+ * consumer holding one schema (an editor rendering one field) asks it directly
89
+ * rather than deriving scopes it would then have to match against. */
90
+ export function declaresCelRegion(schema) {
91
+ if (!schema || typeof schema !== "object")
92
+ return false;
93
+ const node = schema;
94
+ return CEL_REGION_KEYS.some((key) => node[key] !== undefined) || isStepSlot(node);
95
+ }
96
+ /**
97
+ * Walk a JSON Schema tree and collect the JSONPath scopes of every field that
98
+ * declares a CEL-bearing region (`x-telo-context` / `x-telo-step-context` /
99
+ * `x-telo-error-context`). Used — alongside `x-telo-eval` paths — to decide
100
+ * whether a `!cel` expression sits in a slot the runtime actually evaluates.
101
+ * Scopes use the same `$.a.b[*]` form as `extractContextsFromSchema`, matched
102
+ * against expression paths with `pathMatchesScope`.
103
+ */
104
+ export function extractCelRegionScopes(schema, path = "$") {
105
+ if (!schema || typeof schema !== "object")
106
+ return [];
107
+ const out = [];
108
+ if (declaresCelRegion(schema))
109
+ out.push(path);
110
+ if (schema.properties) {
111
+ for (const [key, value] of Object.entries(schema.properties)) {
112
+ out.push(...extractCelRegionScopes(value, `${path}.${key}`));
113
+ }
114
+ }
115
+ if (schema.items && typeof schema.items === "object") {
116
+ out.push(...extractCelRegionScopes(schema.items, `${path}[*]`));
117
+ }
118
+ for (const key of ["oneOf", "anyOf", "allOf"]) {
119
+ if (Array.isArray(schema[key])) {
120
+ for (const subschema of schema[key])
121
+ out.push(...extractCelRegionScopes(subschema, path));
122
+ }
123
+ }
124
+ return out;
125
+ }
126
+ /**
127
+ * Returns true when a CEL expression path (from walkCelExpressions, e.g. "routes[0].inputs.q")
128
+ * falls within the scope of a context (e.g. "$.routes[*].inputs").
129
+ *
130
+ * The scope is matched directly (no sibling sharing): a context at "$.routes[*].inputs" only
131
+ * applies to expressions whose path starts with "routes[N].inputs", not to other sibling fields.
132
+ */
133
+ export function pathMatchesScope(exprPath, scope) {
134
+ const stripped = scope.startsWith("$.") ? scope.slice(2) : scope;
135
+ if (!stripped)
136
+ return false;
137
+ // Split on wildcard array segments; each [*] must match a concrete [N] in exprPath
138
+ const parts = stripped.split("[*]");
139
+ let remaining = exprPath;
140
+ for (let i = 0; i < parts.length; i++) {
141
+ const part = parts[i];
142
+ if (!remaining.startsWith(part))
143
+ return false;
144
+ remaining = remaining.slice(part.length);
145
+ if (i < parts.length - 1) {
146
+ // Expect a concrete array index like [0], [12], ...
147
+ const m = remaining.match(/^\[\d+\]/);
148
+ if (!m)
149
+ return false;
150
+ remaining = remaining.slice(m[0].length);
151
+ }
152
+ }
153
+ // Expression must end here or continue into a child path
154
+ return remaining === "" || remaining[0] === "." || remaining[0] === "[";
155
+ }
156
+ export const NO_CEL_EVAL_SITES = { compile: [], runtime: [], regions: [] };
157
+ export function celEvalSites(schema) {
158
+ if (!schema)
159
+ return NO_CEL_EVAL_SITES;
160
+ const { compile, runtime } = buildEvalPaths(schema);
161
+ return { compile, runtime, regions: extractCelRegionScopes(schema) };
162
+ }
163
+ /** The union of several schemas' sites — a kind's own and its capability
164
+ * abstract's, which is how a `Telo.Provider`'s implicit compile-eval reaches
165
+ * fields the provider never annotated. */
166
+ export function mergeCelEvalSites(...sites) {
167
+ return {
168
+ compile: sites.flatMap((s) => s.compile),
169
+ runtime: sites.flatMap((s) => s.runtime),
170
+ regions: sites.flatMap((s) => s.regions),
171
+ };
172
+ }
173
+ /**
174
+ * Whether the value at `path` is evaluated, and when — null for a field whose
175
+ * value is read as a literal.
176
+ *
177
+ * `compile` wins over `runtime`, and both win over a region: a field's own
178
+ * annotation is more specific than the region it sits in, which is the same
179
+ * precedence a nested annotation has over an enclosing one. A region resolves to
180
+ * `runtime` because that is what a region IS — a per-invocation scope naming
181
+ * what its expressions can read.
182
+ *
183
+ * `path` is the `walkCelExpressions` spelling (`routes[0].returns[1].when`).
184
+ */
185
+ export function celEvalModeAt(sites, path) {
186
+ if (evalPathsCover(sites.compile, path))
187
+ return "compile";
188
+ if (evalPathsCover(sites.runtime, path))
189
+ return "runtime";
190
+ if (sites.regions.some((scope) => pathMatchesScope(path, scope)))
191
+ return "runtime";
192
+ return null;
193
+ }
@@ -15,7 +15,7 @@ export interface ParsedExportEntry {
15
15
  * the empty prefix isn't a valid alias. */
16
16
  export declare function parseExportEntry(entry: string): ParsedExportEntry;
17
17
  /** The import-boundary forwarding rule, shared by `flattenForAnalyzer` (the
18
- * CLI / kernel loader path) and the telo-editor's workspace projection so the
18
+ * CLI / kernel loader path) and telo studio's workspace projection so the
19
19
  * two cannot drift. Given one module's stamped manifests and whether that
20
20
  * module is the analysis entry (root), returns the manifests that cross into
21
21
  * the consumer's flat analysis list:
@@ -9,7 +9,7 @@ export function parseExportEntry(entry) {
9
9
  return dot > 0 ? { name: entry.slice(dot + 1), alias: entry.slice(0, dot) } : { name: entry };
10
10
  }
11
11
  /** The import-boundary forwarding rule, shared by `flattenForAnalyzer` (the
12
- * CLI / kernel loader path) and the telo-editor's workspace projection so the
12
+ * CLI / kernel loader path) and telo studio's workspace projection so the
13
13
  * two cannot drift. Given one module's stamped manifests and whether that
14
14
  * module is the analysis entry (root), returns the manifests that cross into
15
15
  * the consumer's flat analysis list:
@@ -3,7 +3,7 @@ import { type AnalysisDiagnostic } from "./types.js";
3
3
  /**
4
4
  * Convert a graph's import failures (`graph.errors`) into structured, coded
5
5
  * diagnostics. This is the single source of truth for surfacing a broken
6
- * import — every host (CLI, VS Code, telo-editor) routes these instead of each
6
+ * import — every host (CLI, VS Code, telo studio) routes these instead of each
7
7
  * re-deriving the channel and drifting (the VS Code extension used to drop it
8
8
  * entirely, showing nothing for a broken import).
9
9
  *
@@ -38,7 +38,7 @@ function messageFor(e, code) {
38
38
  /**
39
39
  * Convert a graph's import failures (`graph.errors`) into structured, coded
40
40
  * diagnostics. This is the single source of truth for surfacing a broken
41
- * import — every host (CLI, VS Code, telo-editor) routes these instead of each
41
+ * import — every host (CLI, VS Code, telo studio) routes these instead of each
42
42
  * re-deriving the channel and drifting (the VS Code extension used to drop it
43
43
  * entirely, showing nothing for a broken import).
44
44
  *
package/dist/index.d.ts CHANGED
@@ -4,7 +4,8 @@ export { StaticAnalyzer } from "./analyzer.js";
4
4
  export { importResolutionDiagnostics } from "./import-resolution-diagnostics.js";
5
5
  export type { GraphLoadError, ImportEdge, LoadedFile, LoadedGraph, LoadedModule, ParseError, } from "./loaded-types.js";
6
6
  export { collectZoneModuleDocuments, flattenForAnalyzer, flattenLoadedModule, forwardReExportManifests, parseExportEntry, reExportSpecsFromExports, resolveExportedKinds, selectModuleManifestsForAnalysis, stampExportedKinds, stampReExportedKinds, type ParsedExportEntry, type ReExportSpec, } from "./flatten-for-analyzer.js";
7
- export { buildEvalPaths, evalPathCovers } from "./eval-paths.js";
7
+ export { buildEvalPaths, celEvalModeAt, celEvalSites, declaresCelRegion, evalPathCovers, mergeCelEvalSites, NO_CEL_EVAL_SITES, } from "./eval-paths.js";
8
+ export type { CelEvalSites } from "./eval-paths.js";
8
9
  export { BINDINGS_ANNOTATION, bindingContextProperties, bindingDependencies, findBindingSites, resolveBindingOrder, } from "./cel-bindings.js";
9
10
  export type { BindingSites } from "./cel-bindings.js";
10
11
  export { CEL_RESERVED_WORDS, TYPE_LEVEL_DOC_KINDS, checkName, } from "./identifier-name.js";
@@ -21,8 +22,8 @@ export { hasIntermediateWildcard, parseRedactionPath, RedactionPathError, } from
21
22
  export type { RedactionSegment } from "./redaction-path.js";
22
23
  export { buildCallGraph, projectToPairs, resourceId } from "./call-graph.js";
23
24
  export type { BuildCallGraphOptions, CallGraph, CallGraphEdge, CallGraphNode, ResourceGraphNode, StepGraphNode, } from "./call-graph.js";
24
- export { buildReferenceFieldMap, isRefEntry, isScopeEntry } from "./reference-field-map.js";
25
- export type { ReferenceFieldMap, RefFieldEntry } from "./reference-field-map.js";
25
+ export { buildReferenceFieldMap, isRefEntry, isScopeEntry, satisfiesValueBranch, } from "./reference-field-map.js";
26
+ export type { ReferenceFieldMap, RefFieldEntry, ValueBranchValidator, } from "./reference-field-map.js";
26
27
  export { hasDeclaredUse, isRefSlot, isRefUse, possibleUses, readRefSlot, REF_USES, refSlotAnnotation, rewriteRefSlotKinds, transfersControl, } from "./ref-slot.js";
27
28
  export type { RefSlot, RefUse, RefUseCases } from "./ref-slot.js";
28
29
  export { isStepSlot, readStepSlot, STEP_FRAGMENT } from "./step-slot.js";
@@ -45,12 +46,13 @@ export { deriveLibraryExportRequirements, projectZoneRequirements, runZoneAnalys
45
46
  export type { ZoneExportCache, ZoneExportCacheEntry, ZoneExportRequirements, ZoneRequirementSpec, } from "./resolve-zone-requirements.js";
46
47
  export type { ZoneModuleDocuments } from "./zone-module-documents.js";
47
48
  export { validateZoneSlotDeclarations } from "./validate-zone-slots.js";
48
- export { RESOURCE_RULES_ANNOTATION, readResourceRules, readRawResourceRules, resolveRuleSubjects, findDynamicLeaf, type ResourceRule, type ResourceRuleSeverity, type RuleSubject, } from "./resource-rule.js";
49
+ export { RESOURCE_RULES_ANNOTATION, readResourceRules, readRawResourceRules, resolveRuleSubjects, findDynamicLeaf, dynamicNode, type DynamicLeaf, type ResourceRule, type ResourceRuleSeverity, type RuleSubject, } from "./resource-rule.js";
49
50
  export { validateResourceRuleDeclarations, evaluateResourceRules, ruleExercised, RESOURCE_RULE_BUDGET_MS, type ResourceRuleIssue, type ResourceRuleFinding, } from "./validate-resource-rules.js";
50
51
  export { REFERRER_RULES_ANNOTATION, readReferrerRules, readRawReferrerRules, hasReferrerRules, rewriteReferrerRuleKinds, type ReferrerRule, } from "./referrer-rule.js";
51
- export { validateReferrerRuleDeclarations, evaluateReferrerRules, referrerRuleExercised, reportReferrerRules, reportUnexercisedReferrerRule, type Referrer, type ReferrerRuleIssue, type ReferrerRuleFinding, type ReferrerRuleDiagnostic, } from "./validate-referrer-rules.js";
52
- export { RULE_BUDGET_MS } from "./rule-condition.js";
53
- export { readSchemaProjection, readSchemaMap, readProjectionFrom, readProjectionRef, manifestListScope, projectionKeyMap, projectEntries, resolveSchemaProjections, describeProjectionFailure, type SchemaProjection, type SchemaMap, type ProjectionRef, type ProjectionLookup, type ProjectionScope, type ProjectionFailure, } from "./schema-projection.js";
52
+ export { validateReferrerRuleDeclarations, evaluateReferrerRules, referrerRuleExercised, reportReferrerRules, reportUnexercisedReferrerRule, type Referrer, type ReferrerRuleIssue, type ReferrerRuleFinding, type ReferrerRuleDiagnostic, type ReferrerRuleContext, type ReferrerRuleDeclarationContext, } from "./validate-referrer-rules.js";
53
+ export { PeerBinder, analyzerPeerBinder, analyzerPeersTarget, entryBoundary, navigatePath, referenceValueOf, shapeMatches, type DeclarationLookup, type PeerAliasScope, type PeerBinderEnv, type PeerBinderRegistry, type PeerBinding, type PeerBindingFailure, type PeerBindingResult, type PeersTarget, } from "./peer-binding.js";
54
+ export { RULE_BUDGET_MS, UNTAGGED_CONDITION } from "./rule-condition.js";
55
+ export { readSchemaProjection, type ProjectionReference, readSchemaMap, schemaMapBranch, readProjectionFrom, readProjectionRef, manifestListScope, projectionKeyMap, projectEntries, resolveSchemaProjections, describeProjectionFailure, type SchemaProjection, type SchemaMap, type ProjectionRef, type ProjectionLookup, type ProjectionScope, type ProjectionFailure, } from "./schema-projection.js";
54
56
  export { validateSchemaProjection, type SchemaProjectionIssue } from "./validate-schema-projection.js";
55
57
  export { validateDurableRegions } from "./validate-durable-regions.js";
56
58
  export { validateZoneViolations } from "./validate-zone-violations.js";
@@ -60,8 +62,10 @@ export { validateDynamicSelectors, validateRefSlotDeclarations } from "./validat
60
62
  export type { RefSlotIssue } from "./validate-ref-slots.js";
61
63
  export { validateValueTypeSlots } from "./validate-value-type-slots.js";
62
64
  export type { ValueTypeSlotIssue } from "./validate-value-type-slots.js";
63
- export { checkSchemaCompatibility, selectUnionBranch } from "./schema-compat.js";
64
- export type { CompatibilityResult } from "./schema-compat.js";
65
+ export { checkSchemaCompatibility, resolveRefIn, selectUnionBranch } from "./schema-compat.js";
66
+ export type { CompatibilityResult, ExternalSchemaResolver } from "./schema-compat.js";
67
+ export { ajvErrorToPath, formatAjvErrors, formatSingleError, reduceSchemaErrors, schemaIssues, } from "./schema-error-report.js";
68
+ export type { AjvErrorLike, SchemaIssue } from "./schema-error-report.js";
65
69
  export { visitManifest } from "./manifest-visitor.js";
66
70
  export type { CelSiteEvent, ManifestVisitor, RefSiteEvent, ResourceEnterEvent, ResourceExitEvent, ScopeBoundaryEvent, SchemaFromSiteEvent, VisitOptions, } from "./manifest-visitor.js";
67
71
  export { Loader } from "./manifest-loader.js";