@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
@@ -33,7 +33,7 @@ export declare class StaticAnalyzer {
33
33
  * `DUPLICATE_RESOURCE_NAME` reads those fields to tell a pipeline echo
34
34
  * apart from a genuine collision, and downstream diagnostic positioning
35
35
  * depends on them too. Real callers stamp positions already (the `Loader`,
36
- * `flattenForAnalyzer`, the telo-editor's `emitDocsFor`, the VSCode
36
+ * `flattenForAnalyzer`, telo studio's `emitDocsFor`, the VSCode
37
37
  * extension). Programmatic callers — tests, ad-hoc scripts — should pass
38
38
  * their inputs through `withSyntheticPositions(...)` before calling
39
39
  * `analyze()`. A missing position throws a clear error rather than
@@ -1 +1 @@
1
- {"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAiBzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAIL,KAAK,WAAW,EACjB,MAAM,sBAAsB,CAAC;AA8B9B,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAWvF,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACzF,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAoDjE,OAAO,EAAsB,KAAK,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AA2F/F;0CAC0C;AAC1C,eAAO,MAAM,eAAe,GAAI,OAAO;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,KAAG,OACT,CAAC;AAErD;8EAC8E;AAC9E,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGhD;AAqUD,8DAA8D;AAC9D,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACtC;AA6DD,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAkFD,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;gBAEzB,OAAO,GAAE,qBAA0B;IAI/C;;;;;;;;;;;;;;OAcG;IACH,OAAO,CACL,SAAS,EAAE,gBAAgB,EAAE,EAC7B,OAAO,CAAC,EAAE,eAAe,EACzB,QAAQ,CAAC,EAAE,gBAAgB,EAC3B,eAAe,CAAC,EAAE,eAAe,GAChC,kBAAkB,EAAE;IAiwDvB,aAAa,CACX,SAAS,EAAE,gBAAgB,EAAE,EAC7B,OAAO,CAAC,EAAE,eAAe,EACzB,QAAQ,CAAC,EAAE,gBAAgB,EAC3B,eAAe,CAAC,EAAE,eAAe,GAChC,kBAAkB,EAAE;IAMvB,SAAS,CACP,SAAS,EAAE,gBAAgB,EAAE,EAC7B,QAAQ,EAAE,gBAAgB,EAI1B,kBAAkB,CAAC,EAAE,gBAAgB,EAAE,GACtC,gBAAgB,EAAE;IAyBrB,OAAO,CACL,SAAS,EAAE,gBAAgB,EAAE,EAC7B,QAAQ,EAAE,gBAAgB,GACzB;QAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE;CAsB5F"}
1
+ {"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAiBzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAKL,KAAK,WAAW,EACjB,MAAM,sBAAsB,CAAC;AA8B9B,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAWvF,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACzF,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAwDjE,OAAO,EAAsB,KAAK,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AA+F/F;0CAC0C;AAC1C,eAAO,MAAM,eAAe,GAAI,OAAO;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,KAAG,OACT,CAAC;AAErD;8EAC8E;AAC9E,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGhD;AAqUD,8DAA8D;AAC9D,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACtC;AA6DD,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAkFD,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;gBAEzB,OAAO,GAAE,qBAA0B;IAI/C;;;;;;;;;;;;;;OAcG;IACH,OAAO,CACL,SAAS,EAAE,gBAAgB,EAAE,EAC7B,OAAO,CAAC,EAAE,eAAe,EACzB,QAAQ,CAAC,EAAE,gBAAgB,EAC3B,eAAe,CAAC,EAAE,eAAe,GAChC,kBAAkB,EAAE;IAu4DvB,aAAa,CACX,SAAS,EAAE,gBAAgB,EAAE,EAC7B,OAAO,CAAC,EAAE,eAAe,EACzB,QAAQ,CAAC,EAAE,gBAAgB,EAC3B,eAAe,CAAC,EAAE,eAAe,GAChC,kBAAkB,EAAE;IAMvB,SAAS,CACP,SAAS,EAAE,gBAAgB,EAAE,EAC7B,QAAQ,EAAE,gBAAgB,EAI1B,kBAAkB,CAAC,EAAE,gBAAgB,EAAE,GACtC,gBAAgB,EAAE;IAyBrB,OAAO,CACL,SAAS,EAAE,gBAAgB,EAAE,EAC7B,QAAQ,EAAE,gBAAgB,GACzB;QAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE;CAsB5F"}
package/dist/analyzer.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { canonicalTypeSchemaId, OBSERVED_STATE_KEY } from "@telorun/sdk";
2
2
  import { defaultRegistry, isRefSentinel, isTaggedSentinel, plainChainOf, } from "@telorun/templating";
3
3
  import { AliasResolver, scopeResolverForModule, } from "./alias-resolver.js";
4
- import { buildCelEnvironment, } from "./cel-environment.js";
4
+ import { buildCelEnvironment, isKindDocument, } from "./cel-environment.js";
5
5
  import { DefinitionRegistry } from "./definition-registry.js";
6
6
  import { effectiveAuthorSchema } from "./extends-resolution.js";
7
7
  import { analyzerContractScope, resolveContract, } from "./invocation-contract.js";
@@ -30,10 +30,11 @@ export { analyzerContractScope } from "./invocation-contract.js";
30
30
  import { validateZoneSlotDeclarations } from "./validate-zone-slots.js";
31
31
  import { validateSchemaProjection, } from "./validate-schema-projection.js";
32
32
  import { evaluateResourceRules, reportResourceRules, reportUnexercisedRule, ruleExercised, validateResourceRuleDeclarations, } from "./validate-resource-rules.js";
33
- import { readResourceRules } from "./resource-rule.js";
33
+ import { pointerToPath, readResourceRules } from "./resource-rule.js";
34
34
  import { readReferrerRules } from "./referrer-rule.js";
35
35
  import { evaluateReferrerRules, referrerRuleExercised, reportReferrerRules, reportUnexercisedReferrerRule, validateReferrerRuleDeclarations, } from "./validate-referrer-rules.js";
36
- import { describeProjectionFailure, } from "./schema-projection.js";
36
+ import { analyzerPeerBinder, analyzerPeersTarget } from "./peer-binding.js";
37
+ import { describeProjectionFailure, manifestListScope, resolveSchemaProjections, } from "./schema-projection.js";
37
38
  import { validateDynamicSelectors, validateRefSlotDeclarations, } from "./validate-ref-slots.js";
38
39
  import { validateValueTypeSlots, } from "./validate-value-type-slots.js";
39
40
  import { resolveSchemaTypeRefs } from "./resolve-schema-type-refs.js";
@@ -42,8 +43,8 @@ import { rewriteSyntheticOrigins } from "./rewrite-synthetic-origins.js";
42
43
  import { celTypeSatisfiesJsonSchema, checkSchemaCompatibility, navigateSchemaToExprPath, substituteCelFields, validateAgainstSchema, } from "./schema-compat.js";
43
44
  import { collectValueSchemaIssues } from "./validate-value-schema.js";
44
45
  import { DiagnosticSeverity } from "./types.js";
45
- import { extractAccessChains, extractCelRegionScopes, pathMatchesScope, } from "./validate-cel-context.js";
46
- import { buildEvalPaths, evalPathsCover } from "./eval-paths.js";
46
+ import { extractAccessChains, } from "./validate-cel-context.js";
47
+ import { celEvalModeAt, celEvalSites, mergeCelEvalSites, NO_CEL_EVAL_SITES, } from "./eval-paths.js";
47
48
  import { BINDINGS_ANNOTATION, findBindingSites, resolveBindingOrder, } from "./cel-bindings.js";
48
49
  import { CEL_RESERVED_WORDS, checkName } from "./identifier-name.js";
49
50
  import { validateIdentifierNames } from "./validate-identifier-names.js";
@@ -554,7 +555,7 @@ export class StaticAnalyzer {
554
555
  * `DUPLICATE_RESOURCE_NAME` reads those fields to tell a pipeline echo
555
556
  * apart from a genuine collision, and downstream diagnostic positioning
556
557
  * depends on them too. Real callers stamp positions already (the `Loader`,
557
- * `flattenForAnalyzer`, the telo-editor's `emitDocsFor`, the VSCode
558
+ * `flattenForAnalyzer`, telo studio's `emitDocsFor`, the VSCode
558
559
  * extension). Programmatic callers — tests, ad-hoc scripts — should pass
559
560
  * their inputs through `withSyntheticPositions(...)` before calling
560
561
  * `analyze()`. A missing position throws a clear error rather than
@@ -776,6 +777,11 @@ export class StaticAnalyzer {
776
777
  const projectionIssues = [];
777
778
  const resourceRuleIssues = [];
778
779
  const referrerRuleIssues = [];
780
+ /** Definition docs of the entry's own modules that may declare rules. Their
781
+ * referrer-rule declarations are checked after every kind is registered,
782
+ * because a `peers:` pointer is checked against the REFERRER kind's schema
783
+ * and that kind may be declared later in the same file. */
784
+ const ownRuleDeclarers = [];
779
785
  // A rule that never had anything to iterate is never proven — the second way
780
786
  // coverage varies invisibly, beside the dynamic-leaf skip. Tracked across the
781
787
  // whole run and reported once, since "empty on every resource" is not a fact
@@ -822,7 +828,10 @@ export class StaticAnalyzer {
822
828
  // inherited field resolves — which is what lets a rule shared by every
823
829
  // backend be declared once on the abstract they extend.
824
830
  resourceRuleIssues.push(...validateResourceRuleDeclarations(m, effectiveAuthorSchema(m, (k) => defs.resolve(aliases.resolveKind(k) ?? k) ?? defs.resolve(k))));
825
- referrerRuleIssues.push(...validateReferrerRuleDeclarations(m));
831
+ // Deferred to after the registration loop: the `peers:` half is checked
832
+ // against the REFERRER kind's schema, and a rule may name a kind
833
+ // declared later in the same file.
834
+ ownRuleDeclarers.push(m);
826
835
  for (const rule of readReferrerRules(m.schema)) {
827
836
  referrerRuleExercise.set(`${m.metadata?.module}.${m.metadata?.name}#${rule.code}`, {
828
837
  manifest: m,
@@ -873,6 +882,23 @@ export class StaticAnalyzer {
873
882
  : def;
874
883
  defs.register(normalized);
875
884
  }
885
+ /**
886
+ * What a peer rule's `peers:` pointer names in the kind its `referrer:`
887
+ * filters to.
888
+ *
889
+ * Liskov in BOTH directions, which is what the check has to be: the filter
890
+ * is usually an abstract (`Sql.Schema`, so one rule serves every backend)
891
+ * while the collection is declared by the backends that implement it, so a
892
+ * pointer resolving on any candidate resolves the rule. Reported only when
893
+ * NO candidate declares it, or when every candidate that does holds plain
894
+ * data — the two shapes where the rule would see no declaration at all.
895
+ */
896
+ const peersTarget = analyzerPeersTarget(defs);
897
+ if (!options?.skipValidation) {
898
+ for (const declarer of ownRuleDeclarers) {
899
+ referrerRuleIssues.push(...validateReferrerRuleDeclarations(declarer, { peersTarget }));
900
+ }
901
+ }
876
902
  // Reference-form validation — enforce `!ref` as the only reference shape.
877
903
  // Runs on the RAW manifests, BEFORE inline extraction and sentinel
878
904
  // resolution, while an author-written `{kind, name}` is still
@@ -1257,6 +1283,17 @@ export class StaticAnalyzer {
1257
1283
  diagnostics.push(...validateIncludePlacement(allManifests));
1258
1284
  }
1259
1285
  resolveSchemaTypeRefs(allManifests, aliases, aliasesByModule);
1286
+ // ...and over the manifests the DEFINITION REGISTRY holds, which are not
1287
+ // these. `normalizeInlineResources` deep-clones — that clone is the
1288
+ // analyzer's immutability boundary — while `defs.register` ran before it, on
1289
+ // the originals. So a kind whose `schema:` references a named shape kept the
1290
+ // authored `telo://Self/<Type>` spelling everywhere the registry is read,
1291
+ // which is where a resource's configuration is validated: the schema failed
1292
+ // to compile, the failure was swallowed, and `telo check` reported nothing
1293
+ // about a resource the kernel then rejected at boot. The pass is idempotent
1294
+ // — a canonical id parses as no authority and is left alone — so running it
1295
+ // over both is the whole repair.
1296
+ resolveSchemaTypeRefs(manifests, aliases, aliasesByModule);
1260
1297
  // Trusted-input fast path: when the caller has already attested that
1261
1298
  // this exact manifest set passes analysis (e.g. via the kernel's
1262
1299
  // hash-stamped `.validated.json` cache), skip the validation walk.
@@ -1266,13 +1303,12 @@ export class StaticAnalyzer {
1266
1303
  if (options?.skipValidation) {
1267
1304
  return suppressUnreadableModuleDiagnostics(diagnostics, unreadableFiles);
1268
1305
  }
1269
- // Build a name→manifest map for looking up referenced resources
1270
- const byName = new Map();
1271
- for (const m of allManifests) {
1272
- if (m.metadata?.name) {
1273
- byName.set(m.metadata.name, m);
1274
- }
1275
- }
1306
+ // ONE binder for the whole run, built beside the binding it serves: it caches
1307
+ // each referrer's resolved collection, which is what keeps a rule over an
1308
+ // n-entry collection from re-resolving that collection once per entry.
1309
+ const referrerRuleContext = {
1310
+ peerBinder: analyzerPeerBinder(defs, aliases, allManifests),
1311
+ };
1276
1312
  // Fail loud on definition schemas AJV cannot compile. `validateAgainstSchema`
1277
1313
  // and `validateWithRefs` swallow compile failures (returning no issues),
1278
1314
  // which would silently skip schema validation for every resource of that
@@ -1409,6 +1445,44 @@ export class StaticAnalyzer {
1409
1445
  moduleManifest,
1410
1446
  observedStateContext,
1411
1447
  });
1448
+ /**
1449
+ * The schema a resource of this kind is validated against, per DEFINITION.
1450
+ *
1451
+ * Both halves derive a fresh object — `effectiveAuthorSchema` merges along
1452
+ * `extends`, and the closed-schema branch spreads `kind` / `metadata` in —
1453
+ * so asking per resource handed `validateResourceConfig` a schema object it
1454
+ * had never seen. That registry memoizes its compiled AJV validator by
1455
+ * object IDENTITY, precisely because every resource of a kind is checked
1456
+ * against the same one at keystroke time, so a fresh object per resource
1457
+ * recompiled the whole kind schema per resource. Keyed on the definition,
1458
+ * which is stable for the run.
1459
+ */
1460
+ const authorSchemaCache = new WeakMap();
1461
+ const validationSchemaFor = (def) => {
1462
+ const cached = authorSchemaCache.get(def);
1463
+ if (cached)
1464
+ return cached;
1465
+ const authorSchema = effectiveAuthorSchema(def, (k) => defs.resolve(aliases.resolveKind(k) ?? k) ?? defs.resolve(k));
1466
+ // `kind` and `metadata` are implicit on every resource — inject them so
1467
+ // module authors don't have to repeat them under `additionalProperties:
1468
+ // false`.
1469
+ const schema = authorSchema.additionalProperties === false
1470
+ ? {
1471
+ ...authorSchema,
1472
+ properties: {
1473
+ kind: { type: "string" },
1474
+ metadata: { type: "object" },
1475
+ ...authorSchema.properties,
1476
+ },
1477
+ }
1478
+ : authorSchema;
1479
+ authorSchemaCache.set(def, schema);
1480
+ return schema;
1481
+ };
1482
+ // One scope for the whole run: it closes over the manifest list and the
1483
+ // registry, neither of which changes per resource, and it is asked once per
1484
+ // schema-valued slot that carries a projection.
1485
+ const resourceProjectionScope = manifestListScope(allManifests, (kind) => (defs.resolve(kind) ?? defs.resolve(aliases.resolveKind(kind) ?? kind)));
1412
1486
  // Validate each non-definition, non-system resource
1413
1487
  for (const m of allManifests) {
1414
1488
  const filePath = m.metadata?.source;
@@ -1499,32 +1573,47 @@ export class StaticAnalyzer {
1499
1573
  continue;
1500
1574
  }
1501
1575
  // Validate resource config against the definition's AUTHOR-FACING schema —
1502
- // inheritance-resolved: with `base:` the child's own schema (parent config
1503
- // is internal), else `merge(parent, own)` so a `base:`-less `extends` child
1504
- // is validated against the inherited fields it may set. For a definition
1505
- // that neither extends nor uses `base:` this is exactly its own schema.
1506
- // `kind` and `metadata` are implicit on every resource — inject them so module
1507
- // authors don't have to repeat them when using additionalProperties: false.
1508
- const authorSchema = effectiveAuthorSchema(definition, (k) => defs.resolve(aliases.resolveKind(k) ?? k) ?? defs.resolve(k));
1509
- if (authorSchema && Object.keys(authorSchema).length > 0) {
1510
- const schema = authorSchema.additionalProperties === false
1511
- ? {
1512
- ...authorSchema,
1513
- properties: {
1514
- kind: { type: "string" },
1515
- metadata: { type: "object" },
1516
- ...authorSchema.properties,
1517
- },
1518
- }
1519
- : authorSchema;
1576
+ // inheritance-resolved, with `kind` / `metadata` injected. See
1577
+ // `validationSchemaFor`, which is where both derivations and the reason
1578
+ // they are memoized per definition live.
1579
+ const schema = validationSchemaFor(definition);
1580
+ if (Object.keys(schema).length > 0) {
1520
1581
  // Phase 1: collect the pure-CEL leaves and the schema of the slot each
1521
1582
  // flows into. The expression's own type is resolved later, by the
1522
1583
  // engine walk that owns type-checking; this half only knows the target.
1523
1584
  for (const slot of collectCelValueSlots(m, schema, "")) {
1524
1585
  celReturnSlots.push({ manifest: m, resource, filePath, ...slot });
1525
1586
  }
1526
- // Phase 2+3: AJV on substituted data CEL fields replaced with typed placeholders
1527
- const ajvIssues = validateAgainstSchema(substituteCelFields(m, schema), schema);
1587
+ // A kind's own schema may point a slot at a PROJECTION of a resource it
1588
+ // references, or (the empty pointer) of this very declaration, which is
1589
+ // what types a table's seed rows against its own `columns:`. Resolved
1590
+ // PER RESOURCE, because a projection is declaration-derived: the same
1591
+ // kind schema yields a different row shape for every table.
1592
+ //
1593
+ // A failure here is REPORTED, never dropped. An entry that could not be
1594
+ // read vanishes from the projected shape, so the slot typed from it then
1595
+ // rejects a field the author did declare ("'status' is not allowed") with
1596
+ // nothing saying why — the projection's own failure mode, blaming the
1597
+ // wrong line. Entry-module-scoped, like every other schema issue.
1598
+ const projectionFailures = [];
1599
+ const projected = resolveSchemaProjections(schema, m, resourceProjectionScope, projectionFailures);
1600
+ if (!ownModule || rootModules.has(ownModule)) {
1601
+ for (const failure of projectionFailures) {
1602
+ diagnostics.push({
1603
+ severity: DiagnosticSeverity.Error,
1604
+ code: "SCHEMA_PROJECTION_FROM_UNRESOLVED",
1605
+ source: SOURCE,
1606
+ message: `${m.kind}/${resource.name}: ${describeProjectionFailure(failure)}`,
1607
+ data: { resource, filePath, path: pointerToPath(failure.pointer) },
1608
+ });
1609
+ }
1610
+ }
1611
+ // Phase 2+3: AJV on substituted data — CEL fields replaced with typed
1612
+ // placeholders. Through the REGISTRY, so a kind whose schema references
1613
+ // a shape declared elsewhere is checked on the instance that holds it.
1614
+ const ajvIssues = defs.validateResourceConfig(substituteCelFields(m, projected, undefined, {
1615
+ external: (ref) => defs.schemaForId(ref),
1616
+ }), projected);
1528
1617
  // Phase 4: value slots that must satisfy a type declared elsewhere on
1529
1618
  // the resource (`x-telo-value-schema-from`) — e.g. every row of a
1530
1619
  // decision table against its declared `outputType`, so a mistyped branch
@@ -1550,10 +1639,10 @@ export class StaticAnalyzer {
1550
1639
  // `validate-resource-rules.ts`, the shape every neighbouring pass uses:
1551
1640
  // issues out, one emit here.
1552
1641
  const ruleDeclarer = definition.metadata?.module;
1553
- for (const report of reportResourceRules(m, definition, evaluateResourceRules(m, authorSchema), !ruleDeclarer || rootModules.has(ruleDeclarer))) {
1642
+ for (const report of reportResourceRules(m, definition, evaluateResourceRules(m, schema), !ruleDeclarer || rootModules.has(ruleDeclarer))) {
1554
1643
  diagnostics.push(resourceRuleDiagnostic(report));
1555
1644
  }
1556
- for (const rule of readResourceRules(authorSchema)) {
1645
+ for (const rule of readResourceRules(schema)) {
1557
1646
  const key = `${definition.metadata?.module}.${definition.metadata?.name}#${rule.code}`;
1558
1647
  const tracked = ruleExercise.get(key);
1559
1648
  if (!tracked)
@@ -1568,10 +1657,10 @@ export class StaticAnalyzer {
1568
1657
  // literal appears on the referring side, where the spelling would be the
1569
1658
  // consumer's import alias rather than anything the rule's author controls.
1570
1659
  // A consumer of the shared call graph, never a second traversal.
1571
- const referrerRules = readReferrerRules(authorSchema);
1660
+ const referrerRules = readReferrerRules(schema);
1572
1661
  if (referrerRules.length > 0) {
1573
1662
  const referrers = referrersOf(m, getCallGraph());
1574
- for (const report of reportReferrerRules(m, definition, evaluateReferrerRules(m, authorSchema, referrers, kindMatches), !ruleDeclarer || rootModules.has(ruleDeclarer))) {
1663
+ for (const report of reportReferrerRules(m, definition, evaluateReferrerRules(m, schema, referrers, kindMatches, referrerRuleContext), !ruleDeclarer || rootModules.has(ruleDeclarer))) {
1575
1664
  // A VIOLATION is the referrer's data, so it is reported only when that
1576
1665
  // manifest is the entry's own — the same direction a resource-rule
1577
1666
  // violation takes, one hop further out.
@@ -1580,6 +1669,15 @@ export class StaticAnalyzer {
1580
1669
  continue;
1581
1670
  }
1582
1671
  diagnostics.push(referrerRuleDiagnostic(report));
1672
+ // A rule that VIOLATED plainly ran, whatever its peer set held. The
1673
+ // unexercised report exists to catch silence — a `peers:` naming
1674
+ // nothing makes every `!peers.exists(…)` pass vacuously — so a finding
1675
+ // is exactly the evidence it asks for.
1676
+ if (report.code === "REFERRER_RULE_VIOLATED") {
1677
+ const violated = referrerRuleExercise.get(`${definition.metadata?.module}.${definition.metadata?.name}#${report.rule}`);
1678
+ if (violated)
1679
+ violated.exercised = true;
1680
+ }
1583
1681
  }
1584
1682
  for (const rule of referrerRules) {
1585
1683
  const key = `${definition.metadata?.module}.${definition.metadata?.name}#${rule.code}`;
@@ -1587,8 +1685,9 @@ export class StaticAnalyzer {
1587
1685
  if (!tracked)
1588
1686
  continue;
1589
1687
  tracked.seen = true;
1590
- if (referrerRuleExercised(rule, referrers, kindMatches))
1688
+ if (referrerRuleExercised(rule, referrers, kindMatches, referrerRuleContext)) {
1591
1689
  tracked.exercised = true;
1690
+ }
1592
1691
  }
1593
1692
  }
1594
1693
  // Validate inline resources nested inside this resource's body (e.g. a
@@ -1615,7 +1714,10 @@ export class StaticAnalyzer {
1615
1714
  }
1616
1715
  const viaRoot = aliases.resolveKind(kind);
1617
1716
  return viaRoot ? defs.resolve(viaRoot) : undefined;
1618
- }, allManifests));
1717
+ }, allManifests, {
1718
+ validate: (data, target) => defs.validateResourceConfig(data, target),
1719
+ external: (ref) => defs.schemaForId(ref),
1720
+ }));
1619
1721
  }
1620
1722
  // (Invocation context compatibility check is handled via x-telo-context in the CEL pass below)
1621
1723
  }
@@ -1753,18 +1855,15 @@ export class StaticAnalyzer {
1753
1855
  // same schema an expression is typed against.
1754
1856
  let celStepContextSchema;
1755
1857
  let celErrorScopes = new Map();
1756
- // Region coverage for the "CEL in a non-eval field" check: the union of
1757
- // `x-telo-eval` paths (own + capability) and `x-telo-context` /
1758
- // `x-telo-step-context` / `x-telo-error-context` scopes. A `!cel` outside
1759
- // every region is read as a literal the runtime never evaluates it.
1760
- let celEvalPaths = [];
1858
+ // Where this kind says its values are evaluated — `x-telo-eval` paths (own +
1859
+ // capability) and the regions covering their contents. A `!cel` outside every
1860
+ // one of them is read as a literal, and one under a compile path resolves at
1861
+ // startup, where observed state cannot exist yet. Both questions are
1862
+ // `celEvalModeAt`, which the editor asks of the same sites.
1863
+ let celSites = NO_CEL_EVAL_SITES;
1761
1864
  // The bindings field this kind declares (if any), read by the CEL sites that
1762
1865
  // see the names it introduces.
1763
1866
  let celBindingSites;
1764
- // The compile half alone: a field that resolves at startup, where observed
1765
- // state cannot exist yet.
1766
- let celCompilePaths = [];
1767
- let celRegionScopes = [];
1768
1867
  let celRuleApplies = false;
1769
1868
  visitManifest(allManifests, defs, {
1770
1869
  onResourceEnter: (e) => {
@@ -1896,23 +1995,23 @@ export class StaticAnalyzer {
1896
1995
  celRuleApplies =
1897
1996
  !!e.definition?.schema && capability !== undefined && capability !== "Telo.Template";
1898
1997
  if (celRuleApplies) {
1899
- const ownSchema = e.definition.schema;
1900
- const own = buildEvalPaths(ownSchema);
1998
+ // The INHERITANCE-RESOLVED schema, not the kind's own: without
1999
+ // `base:`, an `extends` child is authored against merge(parent, own),
2000
+ // so a CEL-bearing field the parent declares is a legal field on the
2001
+ // child and the kernel expands it — it stamps the merged schema at
2002
+ // definition registration and builds eval paths from that. Reading
2003
+ // the own schema here reported `CEL_IN_NON_EVAL_FIELD` for an
2004
+ // expression the runtime evaluates correctly, which is the two halves
2005
+ // disagreeing about what the manifest means.
2006
+ const ownSchema = effectiveAuthorSchema(e.definition, (k) => defs.resolve(aliases.resolveKind(k) ?? k) ?? defs.resolve(k));
1901
2007
  const capabilityDef = capability ? defs.resolve(capability) : undefined;
1902
- const parent = capabilityDef?.schema
1903
- ? buildEvalPaths(capabilityDef.schema)
1904
- : { compile: [], runtime: [] };
1905
- celEvalPaths = [...own.compile, ...own.runtime, ...parent.compile, ...parent.runtime];
1906
2008
  // A `Telo.Provider`'s fields are implicitly compile-eval — the
1907
2009
  // capability abstract carries the root annotation — so its reads are
1908
2010
  // covered here without the provider restating anything.
1909
- celCompilePaths = [...own.compile, ...parent.compile];
1910
- celRegionScopes = extractCelRegionScopes(ownSchema);
2011
+ celSites = mergeCelEvalSites(celEvalSites(ownSchema), celEvalSites(capabilityDef?.schema));
1911
2012
  }
1912
2013
  else {
1913
- celEvalPaths = [];
1914
- celCompilePaths = [];
1915
- celRegionScopes = [];
2014
+ celSites = NO_CEL_EVAL_SITES;
1916
2015
  }
1917
2016
  },
1918
2017
  onCel: (e) => {
@@ -1928,8 +2027,7 @@ export class StaticAnalyzer {
1928
2027
  if (celRuleApplies &&
1929
2028
  engineName === "cel" &&
1930
2029
  celScope.invocationContextSchema === undefined &&
1931
- !evalPathsCover(celEvalPaths, path) &&
1932
- !celRegionScopes.some((scope) => pathMatchesScope(path, scope)) &&
2030
+ celEvalModeAt(celSites, path) === null &&
1933
2031
  !pathCrossesNestedResource(m, path)) {
1934
2032
  diagnostics.push({
1935
2033
  severity: DiagnosticSeverity.Error,
@@ -1953,7 +2051,7 @@ export class StaticAnalyzer {
1953
2051
  // the two-level shape it publishes under, so a cross-module read
1954
2052
  // is checked exactly like a local one.
1955
2053
  const reported = observedState.get(read.alias ? `${read.alias}.${read.name}` : read.name);
1956
- if (celRuleApplies && evalPathsCover(celCompilePaths, path)) {
2054
+ if (celRuleApplies && celEvalModeAt(celSites, path) === "compile") {
1957
2055
  diagnostics.push({
1958
2056
  severity: DiagnosticSeverity.Error,
1959
2057
  code: "OBSERVED_STATE_IN_STARTUP_FIELD",
@@ -1997,7 +2095,19 @@ export class StaticAnalyzer {
1997
2095
  contextSchema: e.contextSchema,
1998
2096
  matchedScope,
1999
2097
  });
2000
- const result = engine.analyze(expr, { celEnv: typedEnv, contextSchema: effectiveContext });
2098
+ const result = engine.analyze(expr, {
2099
+ celEnv: typedEnv,
2100
+ contextSchema: effectiveContext,
2101
+ // `scopeFor` registers every kernel global and every name the site's
2102
+ // context declares, so a root this environment does not know is one
2103
+ // nothing puts in scope. Two places where the CEL belongs to another
2104
+ // scope, both already recognised by the non-eval-field check: a kind
2105
+ // document, whose CEL is written for whoever instantiates the kind,
2106
+ // and anything below a nested inline `{ kind }`, whose CEL the
2107
+ // nested kind evaluates — and which is analyzed again, in its own
2108
+ // scope, as the resource it was extracted into.
2109
+ rootsDeclared: !isKindDocument(m) && !pathCrossesNestedResource(m, path),
2110
+ });
2001
2111
  if (result.type !== undefined) {
2002
2112
  let byPath = celTypeByPath.get(m);
2003
2113
  if (!byPath)
@@ -2033,7 +2143,7 @@ export class StaticAnalyzer {
2033
2143
  // intent (a boot timestamp, a run id), so it warns rather than
2034
2144
  // blocking. The engine reports which calls re-evaluate; the eval mode
2035
2145
  // is manifest policy and stays here.
2036
- if (celRuleApplies && evalPathsCover(celCompilePaths, path)) {
2146
+ if (celRuleApplies && celEvalModeAt(celSites, path) === "compile") {
2037
2147
  const volatile = [
2038
2148
  ...new Set(result.calls.filter((c) => c.deterministic === false).map((c) => c.name)),
2039
2149
  ].sort();
@@ -1 +1 @@
1
- {"version":3,"file":"call-graph.d.ts","sourceRoot":"","sources":["../src/call-graph.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"call-graph.d.ts","sourceRoot":"","sources":["../src/call-graph.ts"],"names":[],"mappings":"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"}
@@ -119,7 +119,13 @@ function resolveUseAtSite(entry, root, concretePath, schemaDefault) {
119
119
  if (resolved)
120
120
  return { use: resolved };
121
121
  }
122
- const slot = { kinds: entry.refs, uses: entry.uses, useCases: entry.useCases, inline: false };
122
+ const slot = {
123
+ kinds: entry.refs,
124
+ uses: entry.uses,
125
+ useCases: entry.useCases,
126
+ inline: false,
127
+ valueBranches: [],
128
+ };
123
129
  const unresolvedReason = isTaggedSentinel(selector)
124
130
  ? "dynamic"
125
131
  : selector === undefined
@@ -13,6 +13,18 @@ export type { CelHandlers } from "@telorun/templating";
13
13
  * NOTE: The set of kernel globals registered here must match `KERNEL_GLOBAL_NAMES`
14
14
  * in kernel-globals.ts, which is used for chain-access validation. */
15
15
  export declare function buildTypedCelEnvironment(baseEnv: Environment, manifest: ResourceManifest, extraContextSchema?: Record<string, any> | null, rootModuleManifest?: ResourceManifest): Environment;
16
+ /**
17
+ * A kind document — whose CEL is written for whoever instantiates the kind, not
18
+ * evaluated in the declaring module's own scope.
19
+ *
20
+ * Its `examples:` show a consumer's route reading `request` and `result`, its
21
+ * `description`s show `${{ secrets.API_KEY }}`, and a rule condition reads the
22
+ * `self` / `referrer` its own evaluator binds. None of those names are in scope
23
+ * where they are WRITTEN, and all of them are correct where they are READ — so
24
+ * every check that asks "is this name in scope here" has to stand down on these
25
+ * documents, or it reports errors nobody can fix without deleting the example.
26
+ */
27
+ export declare function isKindDocument(manifest: ResourceManifest): boolean;
16
28
  /** CEL environment for the `variables:`/`secrets:` expressions on a `Telo.Import`.
17
29
  *
18
30
  * Import inputs are a config-only contract: their expressions are evaluated
@@ -1 +1 @@
1
- {"version":3,"file":"cel-environment.d.ts","sourceRoot":"","sources":["../src/cel-environment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAcrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD;;;;;;;;;uEASuE;AACvE,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,gBAAgB,EAC1B,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,EAI/C,kBAAkB,CAAC,EAAE,gBAAgB,GACpC,WAAW,CAgGb;AAuBD;;;;;;8DAM8D;AAC9D,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,WAAW,EACpB,cAAc,EAAE,gBAAgB,GAAG,SAAS,GAC3C,WAAW,CAkCb"}
1
+ {"version":3,"file":"cel-environment.d.ts","sourceRoot":"","sources":["../src/cel-environment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAcrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD;;;;;;;;;uEASuE;AACvE,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,gBAAgB,EAC1B,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,EAI/C,kBAAkB,CAAC,EAAE,gBAAgB,GACpC,WAAW,CA8Gb;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAElE;AAuBD;;;;;;8DAM8D;AAC9D,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,WAAW,EACpB,cAAc,EAAE,gBAAgB,GAAG,SAAS,GAC3C,WAAW,CAkCb"}
@@ -35,24 +35,26 @@ rootModuleManifest) {
35
35
  for (const brand of Object.keys(VALUE_BRAND_BASE)) {
36
36
  env.registerType(brand, { fields: {} });
37
37
  }
38
- // Build typed ObjectSchema from manifest.variables if it looks like a schema map
39
- const vars = manifest.variables;
40
- if (vars !== null && typeof vars === "object" && !Array.isArray(vars)) {
41
- const entries = Object.entries(vars).filter(([, v]) => v !== null && typeof v === "object" && !Array.isArray(v));
42
- if (entries.length > 0) {
43
- const schema = {};
44
- for (const [k, v] of entries) {
45
- schema[k] = jsonSchemaToCelType(v);
46
- }
47
- env.registerVariable({ name: "variables", schema });
48
- }
49
- else {
50
- env.registerVariable("variables", "map");
51
- }
52
- }
53
- else {
54
- env.registerVariable("variables", "map");
55
- }
38
+ // `variables` / `secrets`: the DECLARING module's blocks, which is the
39
+ // contract the resource's CEL is evaluated against at runtime. Read the
40
+ // same three ways `ports` and `module` are, and for the same reason — a
41
+ // resource doc does not carry them, so typing from `manifest` alone left
42
+ // every ordinary resource with an open `variables` and no check at all,
43
+ // while `ports.<typo>` one line away was an error.
44
+ //
45
+ // Order matters: a module-identity doc analyzing itself carries its own
46
+ // block; a resource forwarded from an imported library carries its
47
+ // library's as `metadata.moduleGlobals`, which must win over the consuming
48
+ // application's; everything else is the entry module's own doc.
49
+ const moduleGlobals = manifest.metadata?.moduleGlobals;
50
+ // A KIND document is the exception, and it is not a detail: the CEL inside
51
+ // a `Telo.Definition`'s `schema:` — an `examples:` entry, a `description`
52
+ // showing `${{ secrets.API_KEY }}` — illustrates what a CONSUMER writes, in
53
+ // the consumer's scope. Closing those over the declaring module's blocks
54
+ // reported an error against a name the module never meant to declare, and
55
+ // one nobody could fix without deleting the example.
56
+ const root = (isKindDocument(manifest) ? undefined : rootModuleManifest);
57
+ registerConfigNamespace(env, manifest.variables ?? moduleGlobals?.variables ?? root?.variables, "variables");
56
58
  // `ports` namespace: each entry types as the brand its `protocol` selects
57
59
  // (tcp → TcpPort, udp → UdpPort), so `${{ ports.http }}` carries a nominal
58
60
  // type that consuming fields can check against.
@@ -73,7 +75,7 @@ rootModuleManifest) {
73
75
  else {
74
76
  env.registerVariable("ports", "map");
75
77
  }
76
- env.registerVariable("secrets", "map");
78
+ registerConfigNamespace(env, manifest.secrets ?? moduleGlobals?.secrets ?? root?.secrets, "secrets");
77
79
  env.registerVariable("resources", "map");
78
80
  // `module` — the declaring module's own `metadata`, so a manifest reads its
79
81
  // version instead of restating it. A resource forwarded from an imported
@@ -110,6 +112,20 @@ rootModuleManifest) {
110
112
  return baseEnv.clone();
111
113
  }
112
114
  }
115
+ /**
116
+ * A kind document — whose CEL is written for whoever instantiates the kind, not
117
+ * evaluated in the declaring module's own scope.
118
+ *
119
+ * Its `examples:` show a consumer's route reading `request` and `result`, its
120
+ * `description`s show `${{ secrets.API_KEY }}`, and a rule condition reads the
121
+ * `self` / `referrer` its own evaluator binds. None of those names are in scope
122
+ * where they are WRITTEN, and all of them are correct where they are READ — so
123
+ * every check that asks "is this name in scope here" has to stand down on these
124
+ * documents, or it reports errors nobody can fix without deleting the example.
125
+ */
126
+ export function isKindDocument(manifest) {
127
+ return manifest.kind === "Telo.Definition" || manifest.kind === "Telo.Abstract";
128
+ }
113
129
  /** Register a `variables`/`secrets` namespace typed from a module doc's schema map
114
130
  * (`{ name: <schema>, … }`), falling back to dyn `map` when absent or untyped. */
115
131
  function registerConfigNamespace(env, block, name) {
@@ -1 +1 @@
1
- {"version":3,"file":"cel-scope.d.ts","sourceRoot":"","sources":["../src/cel-scope.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cel-scope.d.ts","sourceRoot":"","sources":["../src/cel-scope.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAQvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAO9D,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,qBAAqB,CAAC;AAsE7B;;;;;;;;;;;oEAWoE;AACpE,wBAAgB,uBAAuB,CACrC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACtB,IAAI,EAAE,kBAAkB,EACxB,OAAO,EAAE,aAAa,EACtB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EACnC,MAAM,EAAE,YAAY,GACnB,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAQrB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC7B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC9B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EACnC,IAAI,EAAE,kBAAkB,EACxB,OAAO,EAAE,aAAa,EACtB,MAAM,EAAE,YAAY,GACnB,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,CAqGjC;AAED,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,GACzC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAmClC;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,GACvC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,CAWjC;AAED;;;+DAG+D;AAC/D,wBAAgB,gBAAgB,CAC9B,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAClC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC5B,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAcrB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,QAAQ;IACvB,wDAAwD;IACxD,GAAG,EAAE,WAAW,CAAC;IACjB;+EAC2E;IAC3E,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;CAC3C;AAED;+CAC+C;AAC/C,MAAM,WAAW,cAAc;IAC7B,0CAA0C;IAC1C,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,kBAAkB,CAAC;IACzB,OAAO,EAAE,aAAa,CAAC;IACvB,MAAM,EAAE,YAAY,CAAC;IACrB,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,aAAa,EAAE,kBAAkB,CAAC;IAClC,sEAAsE;IACtE,cAAc,CAAC,EAAE,gBAAgB,CAAC;IAClC,+EAA+E;IAC/E,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;CAClD;AAED;;;6BAG6B;AAC7B,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,gBAAgB,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACpC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;GAOG;AACH,qBAAa,gBAAgB;IAQf,OAAO,CAAC,QAAQ,CAAC,MAAM;IAPnC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA4C;IAE/E,4DAA4D;IAC5D,OAAO,CAAC,WAAW,CAAkC;IACrD,OAAO,CAAC,iBAAiB,CAAkC;IAC3D,OAAO,CAAC,WAAW,CAA+C;gBAErC,MAAM,EAAE,cAAc;IAEnD;;;uDAGmD;IACnD,IAAI,iBAAiB,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,CAEvD;IAED,sEAAsE;IACtE,IAAI,kBAAkB,IAAI,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAEjE;IAED;;;+CAG2C;IAC3C,IAAI,uBAAuB,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,CAE7D;IAED,oDAAoD;IACpD,aAAa,CAAC,CAAC,EAAE,gBAAgB,EAAE,UAAU,EAAE,kBAAkB,GAAG,SAAS,GAAG,IAAI;IAwBpF;;;;;;;;;OASG;IACH,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,QAAQ;IAoCpC;;sEAEkE;IAClE,OAAO,CAAC,iBAAiB;CAwE1B"}