@telorun/analyzer 0.62.0 → 0.63.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 (146) hide show
  1. package/dist/analysis-registry.d.ts.map +1 -1
  2. package/dist/analysis-registry.js +6 -0
  3. package/dist/analyzer.d.ts +1 -1
  4. package/dist/analyzer.d.ts.map +1 -1
  5. package/dist/analyzer.js +343 -13
  6. package/dist/call-graph.d.ts.map +1 -1
  7. package/dist/call-graph.js +2 -7
  8. package/dist/flatten-for-analyzer.js +1 -1
  9. package/dist/import-resolution-diagnostics.d.ts +9 -2
  10. package/dist/import-resolution-diagnostics.d.ts.map +1 -1
  11. package/dist/import-resolution-diagnostics.js +26 -7
  12. package/dist/index.d.ts +15 -1
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +13 -1
  15. package/dist/invocation-contract.d.ts +6 -1
  16. package/dist/invocation-contract.d.ts.map +1 -1
  17. package/dist/invocation-contract.js +27 -4
  18. package/dist/loaded-types.d.ts +12 -3
  19. package/dist/loaded-types.d.ts.map +1 -1
  20. package/dist/manifest-loader.d.ts +0 -1
  21. package/dist/manifest-loader.d.ts.map +1 -1
  22. package/dist/manifest-loader.js +62 -41
  23. package/dist/manifest-schemas.d.ts +699 -0
  24. package/dist/manifest-schemas.d.ts.map +1 -1
  25. package/dist/manifest-schemas.js +306 -14
  26. package/dist/module-compatibility.d.ts +40 -0
  27. package/dist/module-compatibility.d.ts.map +1 -0
  28. package/dist/module-compatibility.js +52 -0
  29. package/dist/ref-slot-reading.d.ts +30 -0
  30. package/dist/ref-slot-reading.d.ts.map +1 -0
  31. package/dist/ref-slot-reading.js +139 -0
  32. package/dist/referrer-rule.d.ts +67 -0
  33. package/dist/referrer-rule.d.ts.map +1 -0
  34. package/dist/referrer-rule.js +96 -0
  35. package/dist/release/index.d.ts +1 -1
  36. package/dist/release/index.d.ts.map +1 -1
  37. package/dist/release/index.js +1 -1
  38. package/dist/release/payload-digest.d.ts +7 -3
  39. package/dist/release/payload-digest.d.ts.map +1 -1
  40. package/dist/release/payload-digest.js +7 -3
  41. package/dist/release/version-stamp.d.ts +16 -0
  42. package/dist/release/version-stamp.d.ts.map +1 -1
  43. package/dist/release/version-stamp.js +52 -0
  44. package/dist/release/workspace-config.d.ts +10 -6
  45. package/dist/release/workspace-config.d.ts.map +1 -1
  46. package/dist/release/workspace-config.js +10 -6
  47. package/dist/resolve-schema-ref-kinds.d.ts +4 -3
  48. package/dist/resolve-schema-ref-kinds.d.ts.map +1 -1
  49. package/dist/resolve-schema-ref-kinds.js +16 -0
  50. package/dist/resolve-throws-union.d.ts.map +1 -1
  51. package/dist/resolve-throws-union.js +4 -3
  52. package/dist/resolve-zone-containment.d.ts +99 -0
  53. package/dist/resolve-zone-containment.d.ts.map +1 -0
  54. package/dist/resolve-zone-containment.js +212 -0
  55. package/dist/resolve-zone-requirements.d.ts +5 -0
  56. package/dist/resolve-zone-requirements.d.ts.map +1 -1
  57. package/dist/resolve-zone-requirements.js +48 -7
  58. package/dist/resource-rule.d.ts +106 -0
  59. package/dist/resource-rule.d.ts.map +1 -0
  60. package/dist/resource-rule.js +236 -0
  61. package/dist/rule-condition.d.ts +50 -0
  62. package/dist/rule-condition.d.ts.map +1 -0
  63. package/dist/rule-condition.js +108 -0
  64. package/dist/schema-keywords.d.ts.map +1 -1
  65. package/dist/schema-keywords.js +20 -0
  66. package/dist/schema-projection.d.ts +171 -0
  67. package/dist/schema-projection.d.ts.map +1 -0
  68. package/dist/schema-projection.js +317 -0
  69. package/dist/step-slot.d.ts +39 -0
  70. package/dist/step-slot.d.ts.map +1 -0
  71. package/dist/step-slot.js +49 -0
  72. package/dist/telo-version.d.ts +1 -1
  73. package/dist/telo-version.js +1 -1
  74. package/dist/validate-cel-context.d.ts.map +1 -1
  75. package/dist/validate-cel-context.js +17 -3
  76. package/dist/validate-durable-regions.d.ts +15 -0
  77. package/dist/validate-durable-regions.d.ts.map +1 -0
  78. package/dist/validate-durable-regions.js +336 -0
  79. package/dist/validate-references.d.ts.map +1 -1
  80. package/dist/validate-references.js +44 -2
  81. package/dist/validate-referrer-rules.d.ts +120 -0
  82. package/dist/validate-referrer-rules.d.ts.map +1 -0
  83. package/dist/validate-referrer-rules.js +255 -0
  84. package/dist/validate-resource-rules.d.ts +114 -0
  85. package/dist/validate-resource-rules.d.ts.map +1 -0
  86. package/dist/validate-resource-rules.js +283 -0
  87. package/dist/validate-schema-projection.d.ts +32 -0
  88. package/dist/validate-schema-projection.d.ts.map +1 -0
  89. package/dist/validate-schema-projection.js +110 -0
  90. package/dist/validate-step-inputs.d.ts +2 -1
  91. package/dist/validate-step-inputs.d.ts.map +1 -1
  92. package/dist/validate-step-inputs.js +5 -3
  93. package/dist/validate-throws-coverage.d.ts.map +1 -1
  94. package/dist/validate-throws-coverage.js +11 -5
  95. package/dist/validate-zone-slots.d.ts +2 -2
  96. package/dist/validate-zone-slots.d.ts.map +1 -1
  97. package/dist/validate-zone-slots.js +202 -6
  98. package/dist/validate-zone-violations.d.ts +12 -0
  99. package/dist/validate-zone-violations.d.ts.map +1 -0
  100. package/dist/validate-zone-violations.js +169 -0
  101. package/dist/value-type-keyword.d.ts +1 -1
  102. package/dist/value-type-keyword.d.ts.map +1 -1
  103. package/dist/value-type-keyword.js +4 -0
  104. package/dist/zone-slot.d.ts +61 -0
  105. package/dist/zone-slot.d.ts.map +1 -1
  106. package/dist/zone-slot.js +86 -5
  107. package/package.json +2 -2
  108. package/src/analysis-registry.ts +6 -0
  109. package/src/analyzer.ts +395 -14
  110. package/src/call-graph.ts +2 -8
  111. package/src/flatten-for-analyzer.ts +1 -1
  112. package/src/import-resolution-diagnostics.ts +25 -7
  113. package/src/index.ts +73 -0
  114. package/src/invocation-contract.ts +45 -2
  115. package/src/loaded-types.ts +12 -3
  116. package/src/manifest-loader.ts +87 -55
  117. package/src/manifest-schemas.ts +328 -14
  118. package/src/module-compatibility.ts +72 -0
  119. package/src/ref-slot-reading.ts +156 -0
  120. package/src/referrer-rule.ts +116 -0
  121. package/src/release/index.ts +1 -0
  122. package/src/release/payload-digest.ts +7 -3
  123. package/src/release/version-stamp.ts +58 -0
  124. package/src/release/workspace-config.ts +10 -6
  125. package/src/resolve-schema-ref-kinds.ts +28 -4
  126. package/src/resolve-throws-union.ts +4 -3
  127. package/src/resolve-zone-containment.ts +329 -0
  128. package/src/resolve-zone-requirements.ts +67 -7
  129. package/src/resource-rule.ts +252 -0
  130. package/src/rule-condition.ts +126 -0
  131. package/src/schema-keywords.ts +24 -0
  132. package/src/schema-projection.ts +403 -0
  133. package/src/step-slot.ts +64 -0
  134. package/src/telo-version.ts +1 -1
  135. package/src/validate-cel-context.ts +17 -3
  136. package/src/validate-durable-regions.ts +401 -0
  137. package/src/validate-references.ts +57 -2
  138. package/src/validate-referrer-rules.ts +373 -0
  139. package/src/validate-resource-rules.ts +401 -0
  140. package/src/validate-schema-projection.ts +184 -0
  141. package/src/validate-step-inputs.ts +5 -3
  142. package/src/validate-throws-coverage.ts +12 -5
  143. package/src/validate-zone-slots.ts +192 -8
  144. package/src/validate-zone-violations.ts +190 -0
  145. package/src/value-type-keyword.ts +4 -0
  146. package/src/zone-slot.ts +114 -5
@@ -1 +1 @@
1
- {"version":3,"file":"analysis-registry.d.ts","sourceRoot":"","sources":["../src/analysis-registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"analysis-registry.d.ts","sourceRoot":"","sources":["../src/analysis-registry.ts"],"names":[],"mappings":"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"}
@@ -131,6 +131,12 @@ export class AnalysisRegistry {
131
131
  const def = this.resolveDefinition(kind);
132
132
  if (!def)
133
133
  return undefined;
134
+ // A KIND-level query: there is no instance, so a DECLARATION-derived slot
135
+ // (`x-telo-schema-projection-from`) has no reference to project from and is
136
+ // left as the kind declared it. That is the honest answer here — the
137
+ // projected shape is a property of one instance, not of the kind — and it is
138
+ // why passing no manifest cannot silently drop a projection: the per-resource
139
+ // analysis pass is what resolves and reports them.
134
140
  return resolveContract(direction, undefined, def, {
135
141
  resolveDefinition: this.scopedDefResolver(),
136
142
  typeManifestsFor: () => [],
@@ -37,7 +37,7 @@ export declare function resolveLocalRef(schema: Record<string, any> | undefined,
37
37
  * failure with no diagnostic attached to it. */
38
38
  export declare function gatherPropertySchemas(schema: Record<string, any>, root?: Record<string, any>): Array<[string, Record<string, any>]>;
39
39
  /**
40
- * Generic, role-driven walk over an `x-telo-step-context` step array. Calls
40
+ * Generic, role-driven walk over a step array. Calls
41
41
  * `visit(step, stepPath)` for every step — top-level and nested through the
42
42
  * `x-telo-topology-role` forms (`branch`, `branch-list`, `case-map`). This is
43
43
  * the single definition of how steps nest, shared by `buildStepContextSchema`
@@ -1 +1 @@
1
- {"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"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"}
package/dist/analyzer.js CHANGED
@@ -17,8 +17,16 @@ import { REF_VALIDATION_SKIP_KINDS } from "./system-kinds.js";
17
17
  import { resolveRefSentinels } from "./resolve-ref-sentinels.js";
18
18
  import { resolveSchemaRefKinds } from "./resolve-schema-ref-kinds.js";
19
19
  import { runZoneAnalysis } from "./resolve-zone-requirements.js";
20
+ import { validateDurableRegions } from "./validate-durable-regions.js";
21
+ import { validateZoneViolations } from "./validate-zone-violations.js";
20
22
  import { MANIFEST_SCHEMA_URI, ManifestRootSchema } from "./manifest-schemas.js";
21
23
  import { validateZoneSlotDeclarations } from "./validate-zone-slots.js";
24
+ import { validateSchemaProjection, } from "./validate-schema-projection.js";
25
+ import { evaluateResourceRules, reportResourceRules, reportUnexercisedRule, ruleExercised, validateResourceRuleDeclarations, } from "./validate-resource-rules.js";
26
+ import { readResourceRules } from "./resource-rule.js";
27
+ import { readReferrerRules } from "./referrer-rule.js";
28
+ import { evaluateReferrerRules, referrerRuleExercised, reportReferrerRules, reportUnexercisedReferrerRule, validateReferrerRuleDeclarations, } from "./validate-referrer-rules.js";
29
+ import { describeProjectionFailure, } from "./schema-projection.js";
22
30
  import { validateDynamicSelectors, validateRefSlotDeclarations, } from "./validate-ref-slots.js";
23
31
  import { validateValueTypeSlots, } from "./validate-value-type-slots.js";
24
32
  import { resolveSchemaTypeRefs } from "./resolve-schema-type-refs.js";
@@ -47,6 +55,7 @@ import { validateReferences } from "./validate-references.js";
47
55
  import { validateReferenceForms } from "./validate-reference-forms.js";
48
56
  import { validateUnusedDeclarations } from "./validate-unused-declarations.js";
49
57
  import { validateThrowsCoverage } from "./validate-throws-coverage.js";
58
+ import { readStepSlot } from "./step-slot.js";
50
59
  const SELF_PREFIX = "Self.";
51
60
  /**
52
61
  * `StaticAnalyzer.analyze()` requires `metadata.source` (non-empty) and
@@ -256,7 +265,7 @@ export function gatherPropertySchemas(schema, root) {
256
265
  return out;
257
266
  }
258
267
  /**
259
- * Generic, role-driven walk over an `x-telo-step-context` step array. Calls
268
+ * Generic, role-driven walk over a step array. Calls
260
269
  * `visit(step, stepPath)` for every step — top-level and nested through the
261
270
  * `x-telo-topology-role` forms (`branch`, `branch-list`, `case-map`). This is
262
271
  * the single definition of how steps nest, shared by `buildStepContextSchema`
@@ -309,7 +318,7 @@ export function walkStepArray(steps, stepItemSchema, rootSchema, basePath, visit
309
318
  });
310
319
  }
311
320
  /**
312
- * Build a `steps` context schema from `x-telo-step-context` annotation.
321
+ * Build a `steps` context schema for a kind's step body.
313
322
  * Walks each step in the manifest array, resolves the invoked resource's output
314
323
  * contract, and builds `steps.<name>.result` context entries.
315
324
  *
@@ -330,7 +339,7 @@ export function walkStepArray(steps, stepItemSchema, rootSchema, basePath, visit
330
339
  * sub-properties (e.g. elseif: [{ if, then }]).
331
340
  * - `case-map` — value is an object whose values are step arrays (e.g. cases).
332
341
  * No specific Run.Sequence field name is hardcoded; any kind that uses
333
- * `x-telo-step-context` and tags its branch fields with these roles works.
342
+ * a step body and tags its branch fields with these roles works.
334
343
  */
335
344
  function buildStepContextSchema(manifest, defSchema, allManifests, defs, aliases, scopes) {
336
345
  const props = defSchema.properties;
@@ -339,7 +348,7 @@ function buildStepContextSchema(manifest, defSchema, allManifests, defs, aliases
339
348
  const contractScope = analyzerContractScope(defs, aliases, scopes, allManifests);
340
349
  const readingModule = manifest.metadata?.module;
341
350
  for (const [fieldName, fieldSchema] of Object.entries(props)) {
342
- const stepCtx = fieldSchema["x-telo-step-context"];
351
+ const stepCtx = readStepSlot(fieldSchema);
343
352
  if (!stepCtx)
344
353
  continue;
345
354
  const invokeField = stepCtx.invoke;
@@ -488,7 +497,7 @@ const NO_ENTRY_POINT_CAPABILITIES = new Set([
488
497
  "Telo.Sink",
489
498
  ]);
490
499
  /**
491
- * Validate `x-telo-step-context` step `invoke` references (e.g. `Run.Sequence`
500
+ * Validate step `invoke` references (e.g. `Run.Sequence`
492
501
  * steps).
493
502
  *
494
503
  * The reference field map deliberately does NOT descend into step `invoke`
@@ -507,7 +516,7 @@ const NO_ENTRY_POINT_CAPABILITIES = new Set([
507
516
  * contract has no entry point → `REFERENCE_KIND_MISMATCH` (runtime
508
517
  * `ERR_RESOURCE_NOT_INVOKABLE`).
509
518
  *
510
- * Generic and topology-driven — it walks steps via the same `x-telo-step-context`
519
+ * Generic and topology-driven — it walks steps via the same step-slot
511
520
  * / `x-telo-topology-role` annotations `buildStepContextSchema` uses (through the
512
521
  * shared `walkStepArray`), so nested branches (then/else/do/catch/cases) are
513
522
  * covered and no `Run.Sequence` field name is hardcoded. The cross-module
@@ -626,8 +635,7 @@ function validateStepInvokeReferences(allManifests, defs, aliases) {
626
635
  const resource = { kind: m.kind, name: meta.name };
627
636
  const filePath = typeof meta.source === "string" ? meta.source : undefined;
628
637
  for (const [fieldName, fieldSchema] of Object.entries(defSchema.properties)) {
629
- const stepCtx = fieldSchema["x-telo-step-context"];
630
- const invokeField = stepCtx?.invoke;
638
+ const invokeField = readStepSlot(fieldSchema)?.invoke;
631
639
  if (!invokeField)
632
640
  continue;
633
641
  const steps = m[fieldName];
@@ -1032,13 +1040,18 @@ export class StaticAnalyzer {
1032
1040
  }
1033
1041
  seen.add(alias);
1034
1042
  }
1035
- if (alias && source) {
1036
- const targetModule = resolvedModuleName ?? source.split("/").filter(Boolean).pop() ?? source;
1043
+ // An import whose target identity was never established registers NO
1044
+ // alias. The name is never guessed from the source string: a guess that
1045
+ // is usually right is what turned "this import did not resolve" into an
1046
+ // assertion that a published dependency was malformed, naming a module
1047
+ // no registry could ever hold. With no alias, every use degrades to
1048
+ // "cannot resolve alias '<X>'" — which points at the import the author
1049
+ // has to fix, and which the loader has already reported on its own line.
1050
+ if (alias && source && resolvedModuleName) {
1051
+ const targetModule = resolvedModuleName;
1037
1052
  // Module identity is registered globally so x-telo-ref resolution sees
1038
1053
  // transitively-imported modules regardless of which scope brought them in.
1039
- if (resolvedModuleName) {
1040
- defs.registerModuleIdentity(resolvedNamespace ?? null, resolvedModuleName);
1041
- }
1054
+ defs.registerModuleIdentity(resolvedNamespace ?? null, resolvedModuleName);
1042
1055
  // `metadata.reExportedKinds` (stamped by flattenForAnalyzer / the editor projection)
1043
1056
  // maps an exported suffix to the true owning module's canonical kind for kinds this
1044
1057
  // import transitively re-exports (`exports.kinds: [Alias.Kind]`).
@@ -1092,6 +1105,55 @@ export class StaticAnalyzer {
1092
1105
  const refConstraintIssues = [];
1093
1106
  const refSlotIssues = [];
1094
1107
  const zoneSlotIssues = [];
1108
+ // One place a rule report becomes a diagnostic. The pass decided WHAT and
1109
+ // WHERE; this only carries it across to the diagnostic shape.
1110
+ const SEVERITY = {
1111
+ error: DiagnosticSeverity.Error,
1112
+ warning: DiagnosticSeverity.Warning,
1113
+ information: DiagnosticSeverity.Information,
1114
+ };
1115
+ const resourceRuleDiagnostic = (report) => ({
1116
+ severity: SEVERITY[report.severity],
1117
+ code: report.code,
1118
+ source: SOURCE,
1119
+ message: report.message,
1120
+ data: {
1121
+ resource: {
1122
+ kind: report.manifest.kind,
1123
+ name: report.manifest.metadata?.name,
1124
+ },
1125
+ filePath: report.manifest.metadata?.source,
1126
+ path: report.path,
1127
+ rule: report.rule,
1128
+ },
1129
+ });
1130
+ const referrerRuleDiagnostic = (report) => ({
1131
+ severity: SEVERITY[report.severity],
1132
+ code: report.code,
1133
+ source: SOURCE,
1134
+ message: report.message,
1135
+ data: {
1136
+ resource: {
1137
+ kind: report.manifest.kind,
1138
+ name: report.manifest.metadata?.name,
1139
+ },
1140
+ filePath: report.manifest.metadata?.source,
1141
+ path: report.path,
1142
+ rule: report.rule,
1143
+ },
1144
+ });
1145
+ const projectionIssues = [];
1146
+ const resourceRuleIssues = [];
1147
+ const referrerRuleIssues = [];
1148
+ // A rule that never had anything to iterate is never proven — the second way
1149
+ // coverage varies invisibly, beside the dynamic-leaf skip. Tracked across the
1150
+ // whole run and reported once, since "empty on every resource" is not a fact
1151
+ // any single resource can establish.
1152
+ const ruleExercise = new Map();
1153
+ // Same for a referrer rule, where "never exercised" means nothing the
1154
+ // `referrer:` filter matches ever referenced a resource of the kind — which
1155
+ // is exactly what a typo in that filter looks like from the outside.
1156
+ const referrerRuleExercise = new Map();
1095
1157
  // `x-telo-type` is checked on EVERY manifest, not only on definition docs: a
1096
1158
  // schema fragment is written wherever a kind declares a schema-valued field,
1097
1159
  // so an inline `inputType:` on an ordinary resource carries one just as a
@@ -1124,6 +1186,28 @@ export class StaticAnalyzer {
1124
1186
  refConstraintIssues.push(...issues);
1125
1187
  refSlotIssues.push(...validateRefSlotDeclarations(m));
1126
1188
  zoneSlotIssues.push(...validateZoneSlotDeclarations(m));
1189
+ projectionIssues.push(...validateSchemaProjection(m));
1190
+ // Checked against the MERGED schema, so an `in:` pointer naming an
1191
+ // inherited field resolves — which is what lets a rule shared by every
1192
+ // backend be declared once on the abstract they extend.
1193
+ resourceRuleIssues.push(...validateResourceRuleDeclarations(m, effectiveAuthorSchema(m, (k) => defs.resolve(aliases.resolveKind(k) ?? k) ?? defs.resolve(k))));
1194
+ referrerRuleIssues.push(...validateReferrerRuleDeclarations(m));
1195
+ for (const rule of readReferrerRules(m.schema)) {
1196
+ referrerRuleExercise.set(`${m.metadata?.module}.${m.metadata?.name}#${rule.code}`, {
1197
+ manifest: m,
1198
+ rule,
1199
+ exercised: false,
1200
+ seen: false,
1201
+ });
1202
+ }
1203
+ for (const rule of readResourceRules(m.schema)) {
1204
+ ruleExercise.set(`${m.metadata?.module}.${m.metadata?.name}#${rule.code}`, {
1205
+ manifest: m,
1206
+ rule,
1207
+ exercised: false,
1208
+ seen: false,
1209
+ });
1210
+ }
1127
1211
  }
1128
1212
  const resolvedCapability = def.capability
1129
1213
  ? (scopeResolver.resolveKind(def.capability) ?? def.capability)
@@ -1177,6 +1261,24 @@ export class StaticAnalyzer {
1177
1261
  };
1178
1262
  const filePath = issue.manifest.metadata?.source;
1179
1263
  const data = { resource, filePath, path: issue.path };
1264
+ if (issue.annotation === "referrer") {
1265
+ // Mirrors ZONE_PROVIDER_UNRESOLVED: a filter naming no kind matches no
1266
+ // referrer, so the rule would pass on every manifest while checking
1267
+ // nothing — reported at the kind that wrote it, since the consumer
1268
+ // cannot see that the check is inert.
1269
+ diagnostics.push({
1270
+ severity: DiagnosticSeverity.Error,
1271
+ code: "REFERRER_RULE_INVALID",
1272
+ source: SOURCE,
1273
+ message: `x-telo-referrer-rules 'referrer: ${issue.ref}' at '${issue.path}' names no kind. ` +
1274
+ `The prefix must be an import alias declared in this file's 'imports:' map, ` +
1275
+ `'Self' for a kind in this library, or 'Telo' for a built-in. A filter that ` +
1276
+ `matches nothing leaves the rule inert. Known aliases: ` +
1277
+ `${issue.knownAliases?.join(", ") || "(none)"}.`,
1278
+ data,
1279
+ });
1280
+ continue;
1281
+ }
1180
1282
  if (issue.annotation === "zone") {
1181
1283
  // Mirrors X_TELO_REF_UNRESOLVED: an unresolvable provider kind would
1182
1284
  // leave the requirement silently unenforced — no provider ever
@@ -1262,6 +1364,57 @@ export class StaticAnalyzer {
1262
1364
  // OPPOSITE directions — a dropped requirement is silently unenforced, a
1263
1365
  // dropped provision invents failures — so neither can be left to
1264
1366
  // leniency.
1367
+ // A projection nothing can read does not fail — it stops typing the
1368
+ // consumers counting on it, which puts a misspelled field back where the
1369
+ // projection exists to catch it earlier.
1370
+ for (const issue of resourceRuleIssues) {
1371
+ diagnostics.push({
1372
+ severity: DiagnosticSeverity.Error,
1373
+ code: issue.code,
1374
+ source: SOURCE,
1375
+ message: issue.message,
1376
+ data: {
1377
+ resource: {
1378
+ kind: issue.manifest.kind,
1379
+ name: issue.manifest.metadata?.name,
1380
+ },
1381
+ filePath: issue.manifest.metadata?.source,
1382
+ path: issue.path,
1383
+ },
1384
+ });
1385
+ }
1386
+ for (const issue of referrerRuleIssues) {
1387
+ diagnostics.push({
1388
+ severity: DiagnosticSeverity.Error,
1389
+ code: issue.code,
1390
+ source: SOURCE,
1391
+ message: issue.message,
1392
+ data: {
1393
+ resource: {
1394
+ kind: issue.manifest.kind,
1395
+ name: issue.manifest.metadata?.name,
1396
+ },
1397
+ filePath: issue.manifest.metadata?.source,
1398
+ path: issue.path,
1399
+ },
1400
+ });
1401
+ }
1402
+ for (const issue of projectionIssues) {
1403
+ diagnostics.push({
1404
+ severity: DiagnosticSeverity.Error,
1405
+ code: issue.code,
1406
+ source: SOURCE,
1407
+ message: issue.message,
1408
+ data: {
1409
+ resource: {
1410
+ kind: issue.manifest.kind,
1411
+ name: issue.manifest.metadata?.name,
1412
+ },
1413
+ filePath: issue.manifest.metadata?.source,
1414
+ path: issue.path,
1415
+ },
1416
+ });
1417
+ }
1265
1418
  for (const issue of zoneSlotIssues) {
1266
1419
  diagnostics.push({
1267
1420
  severity: DiagnosticSeverity.Error,
@@ -1296,6 +1449,57 @@ export class StaticAnalyzer {
1296
1449
  aliases,
1297
1450
  aliasesByModule,
1298
1451
  }));
1452
+ /**
1453
+ * Whether a referrer of `kind` satisfies a referrer rule's `referrer:`
1454
+ * filter, which is canonical by the time it gets here (`resolveSchemaRefKinds`
1455
+ * rewrote it in the DECLARING module's scope). The referring manifest's own
1456
+ * `kind:` is not — it is whatever alias its author imported the kind under —
1457
+ * so it is resolved the same way every other kind comparison in this pass
1458
+ * resolves one. Liskov-substitutable, matching `checkKind`: a child of the
1459
+ * named kind is one.
1460
+ */
1461
+ const kindMatches = (filter, kind) => {
1462
+ const resolved = aliases.resolveKind(kind) ?? kind;
1463
+ if (resolved === filter)
1464
+ return true;
1465
+ return defs
1466
+ .getByExtends(filter)
1467
+ .some((d) => `${d.metadata.module}.${d.metadata.name}` === resolved);
1468
+ };
1469
+ /**
1470
+ * The resources that reach `manifest`, with the slot each one reaches it
1471
+ * through. A step's edge is attributed to the resource whose body declares
1472
+ * it: a step is not a manifest, and the requirement is about the resource
1473
+ * that has to declare something.
1474
+ *
1475
+ * Deduplication is the evaluation's, not this function's — a referrer
1476
+ * reaching one resource through two slots is two sites, and which one anchors
1477
+ * the diagnostic is a reporting decision.
1478
+ */
1479
+ const referrersOf = (manifest, graph) => {
1480
+ const name = manifest.metadata?.name;
1481
+ if (!name)
1482
+ return [];
1483
+ const node = graph.resource(manifest.kind, name) ?? graph.resourceByName(name);
1484
+ if (!node)
1485
+ return [];
1486
+ const out = [];
1487
+ for (const edge of graph.edgesTo(node.id)) {
1488
+ const from = graph.nodes.get(edge.from);
1489
+ if (!from)
1490
+ continue;
1491
+ const owner = from.type === "step" ? graph.nodes.get(from.owner) : from;
1492
+ if (!owner || owner.type !== "resource")
1493
+ continue;
1494
+ out.push({
1495
+ manifest: owner.manifest,
1496
+ kind: owner.kind,
1497
+ name: owner.name,
1498
+ path: edge.path,
1499
+ });
1500
+ }
1501
+ return out;
1502
+ };
1299
1503
  // A `use` case map's selector written in CEL is a hard diagnostic — a call
1300
1504
  // graph known only at runtime is not statically analyzable, and no fallback
1301
1505
  // is conservative for every consumer. Scoped to the entry's own modules:
@@ -1323,6 +1527,29 @@ export class StaticAnalyzer {
1323
1527
  moduleDocuments: options?.moduleDocuments,
1324
1528
  cache: zoneExportCache,
1325
1529
  }));
1530
+ // Durable regions — the SAME graph again, walked DOWNWARD this time.
1531
+ // Every rule here keys off a zone attribute rather than off any kind, so
1532
+ // a backend that ships its own workflow kind is covered without the
1533
+ // analyzer knowing it exists: going native costs a module, not a change
1534
+ // here.
1535
+ const resolveRegionDef = (kind, module) => {
1536
+ const scope = (module ? aliasesByModule.get(module) : undefined) ?? aliases;
1537
+ const canonical = scope.resolveKind(kind);
1538
+ return defs.resolve(kind) ?? (canonical ? defs.resolve(canonical) : undefined);
1539
+ };
1540
+ diagnostics.push(...validateDurableRegions({
1541
+ graph: getCallGraph(),
1542
+ resolveDef: resolveRegionDef,
1543
+ reportModules: rootModules,
1544
+ }),
1545
+ // The same walk once more, over EVERY attribute rather than the two
1546
+ // durability names — a region must not contain a resource that declares
1547
+ // it cannot honour what the region promises.
1548
+ ...validateZoneViolations({
1549
+ graph: getCallGraph(),
1550
+ resolveDef: resolveRegionDef,
1551
+ reportModules: rootModules,
1552
+ }));
1326
1553
  }
1327
1554
  // Phase 2.6: register each named `Telo.Type` resource's schema under its
1328
1555
  // canonical module-scoped id (`telo://<module>/<name>`), validate
@@ -1672,6 +1899,56 @@ export class StaticAnalyzer {
1672
1899
  });
1673
1900
  }
1674
1901
  }
1902
+ // Resource rules — relationships between this resource's own fields that
1903
+ // JSON Schema cannot state, declared by the kind as CEL over `self` and
1904
+ // `this`. Read off the AUTHOR-FACING schema, so an `extends` child without
1905
+ // `base:` inherits its parent's rules and one that declares its own
1906
+ // replaces them, exactly as the rest of the config contract merges.
1907
+ // The finding→diagnostic mapping lives with the finding vocabulary in
1908
+ // `validate-resource-rules.ts`, the shape every neighbouring pass uses:
1909
+ // issues out, one emit here.
1910
+ const ruleDeclarer = definition.metadata?.module;
1911
+ for (const report of reportResourceRules(m, definition, evaluateResourceRules(m, authorSchema), !ruleDeclarer || rootModules.has(ruleDeclarer))) {
1912
+ diagnostics.push(resourceRuleDiagnostic(report));
1913
+ }
1914
+ for (const rule of readResourceRules(authorSchema)) {
1915
+ const key = `${definition.metadata?.module}.${definition.metadata?.name}#${rule.code}`;
1916
+ const tracked = ruleExercise.get(key);
1917
+ if (!tracked)
1918
+ continue;
1919
+ tracked.seen = true;
1920
+ if (ruleExercised(m, rule))
1921
+ tracked.exercised = true;
1922
+ }
1923
+ // Referrer rules — what must be true of whoever REFERENCES this resource,
1924
+ // declared by the kind that has the requirement rather than by the kind
1925
+ // that must satisfy it. The subject is chosen by the EDGE, so no kind
1926
+ // literal appears on the referring side, where the spelling would be the
1927
+ // consumer's import alias rather than anything the rule's author controls.
1928
+ // A consumer of the shared call graph, never a second traversal.
1929
+ const referrerRules = readReferrerRules(authorSchema);
1930
+ if (referrerRules.length > 0) {
1931
+ const referrers = referrersOf(m, getCallGraph());
1932
+ for (const report of reportReferrerRules(m, definition, evaluateReferrerRules(m, authorSchema, referrers, kindMatches), !ruleDeclarer || rootModules.has(ruleDeclarer))) {
1933
+ // A VIOLATION is the referrer's data, so it is reported only when that
1934
+ // manifest is the entry's own — the same direction a resource-rule
1935
+ // violation takes, one hop further out.
1936
+ const owner = report.manifest.metadata?.module;
1937
+ if (report.code === "REFERRER_RULE_VIOLATED" && owner && !rootModules.has(owner)) {
1938
+ continue;
1939
+ }
1940
+ diagnostics.push(referrerRuleDiagnostic(report));
1941
+ }
1942
+ for (const rule of referrerRules) {
1943
+ const key = `${definition.metadata?.module}.${definition.metadata?.name}#${rule.code}`;
1944
+ const tracked = referrerRuleExercise.get(key);
1945
+ if (!tracked)
1946
+ continue;
1947
+ tracked.seen = true;
1948
+ if (referrerRuleExercised(rule, referrers, kindMatches))
1949
+ tracked.exercised = true;
1950
+ }
1951
+ }
1675
1952
  // Validate inline resources nested inside this resource's body (e.g. a
1676
1953
  // Run.Sequence step's `invoke: { kind, ...config }`). These sit at
1677
1954
  // x-telo-ref slots reached only through local `$ref`s, which the
@@ -1700,6 +1977,23 @@ export class StaticAnalyzer {
1700
1977
  }
1701
1978
  // (Invocation context compatibility check is handled via x-telo-context in the CEL pass below)
1702
1979
  }
1980
+ // A rule whose collection was empty on every resource of its kind is a rule
1981
+ // nothing proved. `check()` types `self` only shallowly (cel-js takes a flat
1982
+ // field map, so `columns` is `map`), which means a typo below the first level
1983
+ // survives declaration validation and is caught only by evaluation — so a
1984
+ // rule that never evaluated has been verified by nothing at all. Reported
1985
+ // only when the kind HAS resources here: a kind nobody instantiated in this
1986
+ // workspace says nothing about the rule.
1987
+ for (const tracked of ruleExercise.values()) {
1988
+ if (!tracked.seen || tracked.exercised)
1989
+ continue;
1990
+ diagnostics.push(resourceRuleDiagnostic(reportUnexercisedRule(tracked.manifest, tracked.rule)));
1991
+ }
1992
+ for (const tracked of referrerRuleExercise.values()) {
1993
+ if (!tracked.seen || tracked.exercised)
1994
+ continue;
1995
+ diagnostics.push(referrerRuleDiagnostic(reportUnexercisedReferrerRule(tracked.manifest, tracked.rule)));
1996
+ }
1703
1997
  // Template-body structural validations: check that template entry-points produce
1704
1998
  // values matching the contract of their dispatch target and (for `provide:`)
1705
1999
  // the abstract this definition `extends`. CEL fields inside the templated
@@ -1768,6 +2062,42 @@ export class StaticAnalyzer {
1768
2062
  }
1769
2063
  }
1770
2064
  }
2065
+ // A consumer's slot typed from a referenced declaration
2066
+ // (`x-telo-schema-projection-from`) fails in the direction that is hardest
2067
+ // to notice: the contract silently reopens, so a misspelled field passes
2068
+ // `telo check` exactly as it did before the projection existed. That is the
2069
+ // failure the projection exists to move earlier, so it is reported here
2070
+ // rather than left to degrade. Entry-module-scoped, like
2071
+ // `X_TELO_REF_UNRESOLVED` — a published dependency's slot is not the
2072
+ // consumer's to fix.
2073
+ for (const m of allManifests) {
2074
+ const md = m;
2075
+ if (typeof md.kind !== "string" || md.kind.startsWith("Telo."))
2076
+ continue;
2077
+ const ownModule = md.metadata?.module;
2078
+ if (ownModule && !rootModules.has(ownModule))
2079
+ continue;
2080
+ const definition = contractScope.resolveIn(md.kind, ownModule);
2081
+ if (!definition)
2082
+ continue;
2083
+ const failures = [];
2084
+ for (const direction of ["inputType", "outputType"]) {
2085
+ resolveContract(direction, md, definition, contractScope, failures);
2086
+ }
2087
+ for (const failure of failures) {
2088
+ diagnostics.push({
2089
+ severity: DiagnosticSeverity.Error,
2090
+ code: "SCHEMA_PROJECTION_FROM_UNRESOLVED",
2091
+ source: SOURCE,
2092
+ message: `${md.kind}: ${describeProjectionFailure(failure)}`,
2093
+ data: {
2094
+ resource: { kind: md.kind, name: md.metadata?.name },
2095
+ filePath: md.metadata?.source,
2096
+ path: failure.pointer.replace(/^\//, ""),
2097
+ },
2098
+ });
2099
+ }
2100
+ }
1771
2101
  // Validate CEL syntax and context variable access in all manifests. The
1772
2102
  // walker discovers every compiled CEL node by scanning the value tree and
1773
2103
  // hands back the `x-telo-context` schema matched at the enclosing path; the
@@ -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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"}
@@ -2,6 +2,7 @@ import { isRefSentinel, isTaggedSentinel } from "@telorun/templating";
2
2
  import { enclosingOf, propertySchemas, resolveLocalRef, } from "./manifest-navigation.js";
3
3
  import { visitManifest } from "./manifest-visitor.js";
4
4
  import { possibleUses, readRefSlot, transfersControl, } from "./ref-slot.js";
5
+ import { isStepSlot } from "./step-slot.js";
5
6
  import { isRefEntry, resolveFieldEntries } from "./reference-field-map.js";
6
7
  import { DEPENDENCY_GRAPH_SKIP_KINDS as SYSTEM_KINDS } from "./system-kinds.js";
7
8
  export const resourceId = (kind, name) => `${kind}\0${name}`;
@@ -126,11 +127,6 @@ function resolveUseAtSite(entry, root, concretePath, schemaDefault) {
126
127
  : "unmatched";
127
128
  return { use: possibleUses(slot), unresolved: entry.useCases, unresolvedReason };
128
129
  }
129
- /** Names the step-list annotation on an array property, if any. */
130
- function stepContextOf(schema) {
131
- const annotation = schema?.["x-telo-step-context"];
132
- return annotation && typeof annotation === "object" ? annotation : undefined;
133
- }
134
130
  /** A resolved plain reference value (`{kind, name}`, optionally `alias`) — the
135
131
  * shape `resolveRefSentinels` leaves at a ref site. NOT a step: a bare boot
136
132
  * target written `!ref X` must not mint a step node. */
@@ -339,8 +335,7 @@ export function buildCallGraph(resources, registry, options = {}) {
339
335
  return;
340
336
  const collected = [];
341
337
  for (const [key, propSchema] of propertySchemas(schema)) {
342
- const annotation = stepContextOf(propSchema);
343
- if (!annotation)
338
+ if (!isStepSlot(propSchema))
344
339
  continue;
345
340
  const value = node.manifest[key];
346
341
  if (!Array.isArray(value))
@@ -165,7 +165,7 @@ export function flattenForAnalyzer(graph) {
165
165
  if (!owner || !alias)
166
166
  continue;
167
167
  const edge = graph.importEdges.get(owner)?.get(alias);
168
- if (!edge?.targetModuleName)
168
+ if (!edge)
169
169
  continue;
170
170
  const newMetadata = {
171
171
  ...m.metadata,
@@ -1,12 +1,19 @@
1
1
  import type { LoadedGraph } from "./loaded-types.js";
2
2
  import { type AnalysisDiagnostic } from "./types.js";
3
3
  /**
4
- * Convert a graph's import-resolution failures (`graph.errors`) into structured,
5
- * coded diagnostics. This is the single source of truth for surfacing a broken
4
+ * Convert a graph's import failures (`graph.errors`) into structured, coded
5
+ * diagnostics. This is the single source of truth for surfacing a broken
6
6
  * import — every host (CLI, VS Code, telo-editor) 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
  *
10
+ * Three codes, because three different people fix them:
11
+ * `INVALID_IMPORT_SOURCE` (the ref is not a module reference at all),
12
+ * `IMPORT_UNRESOLVED` (a well-formed ref that could not be obtained), and
13
+ * `INVALID_IMPORT_TARGET` (obtained, but not an importable library — an
14
+ * application, no library document, or one that names no module). Collapsing
15
+ * the last into the second would tell an author to fix a ref that is correct.
16
+ *
10
17
  * The analyzer owns only this raw channel conversion; the *presentation* policy
11
18
  * — which analysis cascade to hold back for a compromised file — lives in
12
19
  * `@telorun/ide-support`'s `assembleGraphDiagnostics`.
@@ -1 +1 @@
1
- {"version":3,"file":"import-resolution-diagnostics.d.ts","sourceRoot":"","sources":["../src/import-resolution-diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrE,OAAO,EAAsB,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AA8BzE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,WAAW,GAAG,kBAAkB,EAAE,CAepF"}
1
+ {"version":3,"file":"import-resolution-diagnostics.d.ts","sourceRoot":"","sources":["../src/import-resolution-diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrE,OAAO,EAAsB,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAyCzE;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,WAAW,GAAG,kBAAkB,EAAE,CAepF"}