@telorun/analyzer 0.69.0 → 0.71.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 (98) hide show
  1. package/dist/analysis-registry.d.ts.map +1 -1
  2. package/dist/analysis-registry.js +4 -5
  3. package/dist/analyzer.d.ts.map +1 -1
  4. package/dist/analyzer.js +50 -8
  5. package/dist/call-graph.d.ts.map +1 -1
  6. package/dist/call-graph.js +10 -4
  7. package/dist/canonical-json.d.ts +18 -0
  8. package/dist/canonical-json.d.ts.map +1 -0
  9. package/dist/canonical-json.js +26 -0
  10. package/dist/cel-access-chains.d.ts +14 -0
  11. package/dist/cel-access-chains.d.ts.map +1 -0
  12. package/dist/cel-access-chains.js +45 -0
  13. package/dist/cel-scope-query.d.ts +14 -0
  14. package/dist/cel-scope-query.d.ts.map +1 -1
  15. package/dist/cel-scope-query.js +36 -6
  16. package/dist/definition-registry.d.ts.map +1 -1
  17. package/dist/definition-registry.js +3 -4
  18. package/dist/flatten-for-analyzer.d.ts +2 -2
  19. package/dist/flatten-for-analyzer.d.ts.map +1 -1
  20. package/dist/flatten-for-analyzer.js +1 -1
  21. package/dist/index.d.ts +5 -2
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +3 -1
  24. package/dist/manifest-diff.d.ts +111 -0
  25. package/dist/manifest-diff.d.ts.map +1 -0
  26. package/dist/manifest-diff.js +130 -0
  27. package/dist/manifest-visitor.d.ts.map +1 -1
  28. package/dist/manifest-visitor.js +11 -3
  29. package/dist/module-alias-scope.d.ts +65 -0
  30. package/dist/module-alias-scope.d.ts.map +1 -0
  31. package/dist/module-alias-scope.js +25 -0
  32. package/dist/{zone-module-documents.d.ts → module-documents.d.ts} +11 -7
  33. package/dist/module-documents.d.ts.map +1 -0
  34. package/dist/module-graph.d.ts.map +1 -1
  35. package/dist/module-graph.js +3 -25
  36. package/dist/ref-sentinel-target.d.ts +38 -0
  37. package/dist/ref-sentinel-target.d.ts.map +1 -0
  38. package/dist/ref-sentinel-target.js +13 -0
  39. package/dist/resolve-schema-type-refs.d.ts.map +1 -1
  40. package/dist/resolve-schema-type-refs.js +2 -1
  41. package/dist/resolve-throws-union.d.ts +18 -1
  42. package/dist/resolve-throws-union.d.ts.map +1 -1
  43. package/dist/resolve-throws-union.js +93 -9
  44. package/dist/resolve-zone-requirements.d.ts +3 -3
  45. package/dist/resolve-zone-requirements.d.ts.map +1 -1
  46. package/dist/resolve-zone-requirements.js +12 -12
  47. package/dist/telo-version.d.ts +1 -1
  48. package/dist/telo-version.js +1 -1
  49. package/dist/template-body.d.ts.map +1 -1
  50. package/dist/template-body.js +2 -4
  51. package/dist/types.d.ts +3 -3
  52. package/dist/types.d.ts.map +1 -1
  53. package/dist/validate-invocation-contract.d.ts +5 -0
  54. package/dist/validate-invocation-contract.d.ts.map +1 -1
  55. package/dist/validate-invocation-contract.js +114 -3
  56. package/dist/validate-logging.d.ts.map +1 -1
  57. package/dist/validate-logging.js +2 -2
  58. package/dist/validate-references.d.ts +16 -5
  59. package/dist/validate-references.d.ts.map +1 -1
  60. package/dist/validate-references.js +30 -12
  61. package/dist/validate-resource-inputs.d.ts +1 -26
  62. package/dist/validate-resource-inputs.d.ts.map +1 -1
  63. package/dist/validate-resource-inputs.js +12 -2
  64. package/dist/validate-schema-type-refs.d.ts.map +1 -1
  65. package/dist/validate-schema-type-refs.js +2 -1
  66. package/dist/validate-throws-coverage.d.ts +5 -1
  67. package/dist/validate-throws-coverage.d.ts.map +1 -1
  68. package/dist/validate-throws-coverage.js +6 -2
  69. package/package.json +2 -2
  70. package/src/analysis-registry.ts +4 -5
  71. package/src/analyzer.ts +61 -10
  72. package/src/call-graph.ts +9 -3
  73. package/src/canonical-json.ts +24 -0
  74. package/src/cel-access-chains.ts +47 -0
  75. package/src/cel-scope-query.ts +45 -8
  76. package/src/definition-registry.ts +3 -6
  77. package/src/flatten-for-analyzer.ts +3 -3
  78. package/src/index.ts +10 -2
  79. package/src/manifest-diff.ts +219 -0
  80. package/src/manifest-visitor.ts +11 -3
  81. package/src/module-alias-scope.ts +94 -0
  82. package/src/{zone-module-documents.ts → module-documents.ts} +10 -6
  83. package/src/module-graph.ts +2 -24
  84. package/src/ref-sentinel-target.ts +46 -0
  85. package/src/resolve-schema-type-refs.ts +2 -1
  86. package/src/resolve-throws-union.ts +123 -8
  87. package/src/resolve-zone-requirements.ts +14 -14
  88. package/src/telo-version.ts +1 -1
  89. package/src/template-body.ts +2 -5
  90. package/src/types.ts +3 -3
  91. package/src/validate-invocation-contract.ts +128 -2
  92. package/src/validate-logging.ts +2 -3
  93. package/src/validate-references.ts +41 -11
  94. package/src/validate-resource-inputs.ts +26 -3
  95. package/src/validate-schema-type-refs.ts +2 -1
  96. package/src/validate-throws-coverage.ts +12 -1
  97. package/dist/zone-module-documents.d.ts.map +0 -1
  98. /package/dist/{zone-module-documents.js → module-documents.js} +0 -0
@@ -0,0 +1,13 @@
1
+ import { isRefSentinel } from "@telorun/templating";
2
+ /** Parse a `!ref` sentinel. Returns `undefined` for anything that is not one —
3
+ * including the `{kind, name}` object `resolveRefSentinels` rewrites it into,
4
+ * which is a different shape with a different reader. */
5
+ export function refSentinelTarget(value) {
6
+ if (!isRefSentinel(value))
7
+ return undefined;
8
+ const source = value.source;
9
+ const dot = source.indexOf(".");
10
+ if (dot <= 0)
11
+ return { source, name: source };
12
+ return { source, alias: source.slice(0, dot), name: source.slice(dot + 1) };
13
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-schema-type-refs.d.ts","sourceRoot":"","sources":["../src/resolve-schema-type-refs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAKzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,gBAAgB,EAAE,EAC7B,OAAO,CAAC,EAAE,aAAa,EACvB,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,GAC3C,IAAI,CA6DN"}
1
+ {"version":3,"file":"resolve-schema-type-refs.d.ts","sourceRoot":"","sources":["../src/resolve-schema-type-refs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAMzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,gBAAgB,EAAE,EAC7B,OAAO,CAAC,EAAE,aAAa,EACvB,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,GAC3C,IAAI,CA6DN"}
@@ -1,4 +1,5 @@
1
1
  import { canonicalTypeSchemaId, parseTeloTypeRef } from "@telorun/sdk";
2
+ import { moduleAliasScope } from "./module-alias-scope.js";
2
3
  /** Schema-bearing fields on a Telo.Definition / Telo.Type resource. */
3
4
  const SCHEMA_FIELDS = ["schema", "inputType", "outputType"];
4
5
  /**
@@ -88,7 +89,7 @@ export function resolveSchemaTypeRefs(resources, aliases, aliasesByModule) {
88
89
  };
89
90
  for (const r of resources) {
90
91
  const ownModule = r.metadata?.module;
91
- const resolver = (ownModule ? aliasesByModule?.get(ownModule) : undefined) ?? aliases;
92
+ const resolver = moduleAliasScope(r.metadata, aliases, aliasesByModule);
92
93
  const resolveAuthority = (authority) => authority === "Self" ? ownModule : resolver?.moduleForAlias(authority);
93
94
  for (const field of SCHEMA_FIELDS) {
94
95
  walk(r[field], resolveAuthority, ownModule, true);
@@ -34,10 +34,27 @@ export interface ResolveCtx {
34
34
  aliasesByModule: Map<string, AliasResolver>;
35
35
  /** The consumer/root module names; resources owned by these resolve against `aliases`. */
36
36
  rootModules: Set<string>;
37
+ /**
38
+ * Every imported library's FULL manifest list, keyed by module name.
39
+ *
40
+ * A consumer's flat set holds a library's EXPORTED instances and nothing else,
41
+ * so the siblings an exported entry point invokes are not in it. Without this
42
+ * the walk stops at the first such hop, and the difference is not academic: a
43
+ * library whose entry point raises its own code through an internal guard
44
+ * presented an empty union to its consumer, which then had its `catches:`
45
+ * rejected for the very code the entry point documents.
46
+ *
47
+ * Consulted only as a FALLBACK, after the flat set — the flat set is what the
48
+ * consumer's own resources resolve against, and a library-internal name must
49
+ * never shadow one of them.
50
+ */
51
+ moduleManifests: Map<string, ResourceManifest[]>;
52
+ /** Keyed `<module>\0<name>`: resource names are module-scoped, so two
53
+ * libraries each declaring a `query` are two different unions. */
37
54
  memo: Map<string, ThrowsUnion>;
38
55
  inProgress: Set<string>;
39
56
  }
40
- export declare function createResolveCtx(allManifests: ResourceManifest[], defs: DefinitionRegistry, aliases: AliasResolver, aliasesByModule?: Map<string, AliasResolver>, rootModules?: Set<string>): ResolveCtx;
57
+ export declare function createResolveCtx(allManifests: ResourceManifest[], defs: DefinitionRegistry, aliases: AliasResolver, aliasesByModule?: Map<string, AliasResolver>, rootModules?: Set<string>, moduleManifests?: Map<string, ResourceManifest[]>): ResolveCtx;
41
58
  /** Resolve the effective throw union for a named manifest. The result combines
42
59
  * explicit `throws.codes`, `throws.inherit: true` dataflow (step-context
43
60
  * traversal with try/catch subtraction), and unbounded markers for
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-throws-union.d.ts","sourceRoot":"","sources":["../src/resolve-throws-union.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEzE,OAAO,EAA0B,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACjF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAGnE,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC5B;AAED;;gFAEgF;AAChF,eAAO,MAAM,gBAAgB,mBAAmB,CAAC;AAEjD,MAAM,WAAW,WAAW;IAC1B,gFAAgF;IAChF,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACnC;;;8EAG0E;IAC1E,SAAS,EAAE,OAAO,CAAC;IACnB;;;;gDAI4C;IAC5C,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IACzB,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,IAAI,EAAE,kBAAkB,CAAC;IACzB,OAAO,EAAE,aAAa,CAAC;IACvB;;;wFAGoF;IACpF,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC5C,0FAA0F;IAC1F,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACzB,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAC/B,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACzB;AAED,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,gBAAgB,EAAE,EAChC,IAAI,EAAE,kBAAkB,EACxB,OAAO,EAAE,aAAa,EACtB,eAAe,GAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAa,EACvD,WAAW,GAAE,GAAG,CAAC,MAAM,CAAa,GACnC,UAAU,CAUZ;AA6CD;;;;8CAI8C;AAC9C,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,gBAAgB,EAC1B,GAAG,EAAE,UAAU,GACd,WAAW,CAiDb"}
1
+ {"version":3,"file":"resolve-throws-union.d.ts","sourceRoot":"","sources":["../src/resolve-throws-union.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEzE,OAAO,EAA0B,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGjF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAGnE,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC5B;AAED;;gFAEgF;AAChF,eAAO,MAAM,gBAAgB,mBAAmB,CAAC;AAEjD,MAAM,WAAW,WAAW;IAC1B,gFAAgF;IAChF,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACnC;;;8EAG0E;IAC1E,SAAS,EAAE,OAAO,CAAC;IACnB;;;;gDAI4C;IAC5C,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IACzB,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,IAAI,EAAE,kBAAkB,CAAC;IACzB,OAAO,EAAE,aAAa,CAAC;IACvB;;;wFAGoF;IACpF,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC5C,0FAA0F;IAC1F,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACzB;;;;;;;;;;;;;OAaG;IACH,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,EAAE,CAAC,CAAC;IACjD;uEACmE;IACnE,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAC/B,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACzB;AAED,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,gBAAgB,EAAE,EAChC,IAAI,EAAE,kBAAkB,EACxB,OAAO,EAAE,aAAa,EACtB,eAAe,GAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAa,EACvD,WAAW,GAAE,GAAG,CAAC,MAAM,CAAa,EACpC,eAAe,GAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,EAAE,CAAa,GAC3D,UAAU,CAWZ;AA2HD;;;;8CAI8C;AAC9C,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,gBAAgB,EAC1B,GAAG,EAAE,UAAU,GACd,WAAW,CAiDb"}
@@ -1,21 +1,91 @@
1
1
  import { isTaggedSentinel } from "@telorun/templating";
2
2
  import { scopeResolverForModule } from "./alias-resolver.js";
3
+ import { resolveScopedName } from "./call-graph.js";
4
+ import { refSentinelTarget } from "./ref-sentinel-target.js";
3
5
  import { readStepSlot } from "./step-slot.js";
4
6
  /** Code a non-`InvokeError` failure surfaces as inside a `catch` block. Mirrors
5
7
  * `PLAIN_ERROR_CODE` in `@telorun/run`'s `toSequenceError`: any invoke can throw
6
8
  * a plain error, which the catch sees as `error.code === "INTERNAL_ERROR"`. */
7
9
  export const PLAIN_ERROR_CODE = "INTERNAL_ERROR";
8
- export function createResolveCtx(allManifests, defs, aliases, aliasesByModule = new Map(), rootModules = new Set()) {
10
+ export function createResolveCtx(allManifests, defs, aliases, aliasesByModule = new Map(), rootModules = new Set(), moduleManifests = new Map()) {
9
11
  return {
10
12
  allManifests,
11
13
  defs,
12
14
  aliases,
13
15
  aliasesByModule,
14
16
  rootModules,
17
+ moduleManifests,
15
18
  memo: new Map(),
16
19
  inProgress: new Set(),
17
20
  };
18
21
  }
22
+ /**
23
+ * A dispatch target named by a resolved `{kind, name}` ref.
24
+ *
25
+ * The flat set is the scope such a ref was resolved in, so it is asked first;
26
+ * the owning library's own documents are the fallback for a name the flattened
27
+ * view dropped. `kindMatches` applies to BOTH — one function, one rule, or the
28
+ * next caller inherits whichever half it happened to hit.
29
+ */
30
+ function findTarget(ctx, name, ownerModule, kindMatches) {
31
+ const flat = ctx.allManifests.find((m) => m.metadata?.name === name && kindMatches(m));
32
+ if (flat)
33
+ return flat;
34
+ if (!ownerModule)
35
+ return undefined;
36
+ return ctx.moduleManifests
37
+ .get(ownerModule)
38
+ ?.find((m) => m.metadata?.name === name && kindMatches(m));
39
+ }
40
+ /**
41
+ * The target of a `!ref` that still carries its sentinel — a library-internal
42
+ * reference inside a manifest forwarded into a consumer's flat set, where Phase
43
+ * 2.5 had nothing to resolve it against.
44
+ *
45
+ * **The declaring library is asked FIRST**, and that ordering is the whole rule:
46
+ * a bare name in a library manifest is unambiguously library-internal, so
47
+ * searching the consumer's flat set first let any consumer resource that
48
+ * happened to share the name supply another library's throw union — the same
49
+ * false `{∅}` this branch exists to remove, arrived at from the other side.
50
+ *
51
+ * An ALIAS-qualified source is the cross-module case and is resolved through the
52
+ * declaring module's own alias table, never by dropping the alias and matching
53
+ * the bare name anywhere.
54
+ *
55
+ * Ambiguity resolves to NOTHING rather than to a guess (`resolveScopedName`'s
56
+ * rule), and the caller reads that as unbounded — the safe direction here, since
57
+ * a union that cannot be enumerated must not read as empty.
58
+ */
59
+ function findSentinelTarget(ctx, target, ownerModule) {
60
+ const named = (pool) => (pool ?? []).filter((m) => m.metadata?.name === target.name);
61
+ if (target.alias !== undefined && target.alias !== "Self") {
62
+ // A forwarded export: its module is whatever the DECLARING module aliases
63
+ // that prefix to, and it keeps its export name in the flat set.
64
+ // A root-owned manifest resolves aliases against the global table, which is
65
+ // what `scopeResolverForModule` returns undefined for — so fall back to it
66
+ // rather than reading a root's own alias as unresolvable.
67
+ const resolver = scopeResolverFor(ctx, ownerModule) ?? ctx.aliases;
68
+ const module = resolver.moduleForAlias(target.alias);
69
+ if (!module)
70
+ return undefined;
71
+ return named(ctx.allManifests).find((m) => declaringModuleOf(m) === module);
72
+ }
73
+ const own = named(ctx.moduleManifests.get(ownerModule ?? ""));
74
+ if (own.length === 1)
75
+ return own[0];
76
+ if (own.length > 1)
77
+ return undefined;
78
+ return resolveScopedName(named(ctx.allManifests), declaringModuleOf, ownerModule);
79
+ }
80
+ const declaringModuleOf = (m) => m.metadata?.module;
81
+ /** Memo key. Module-scoped, because resource names are. */
82
+ function memoKey(manifest) {
83
+ const name = manifest.metadata?.name;
84
+ if (!name)
85
+ return undefined;
86
+ const mod = manifest.metadata?.module ?? "";
87
+ return `${mod}\0${name}`;
88
+ }
19
89
  function emptyUnion() {
20
90
  return { codes: new Map(), unbounded: false };
21
91
  }
@@ -60,7 +130,7 @@ function codesFromDefinition(definition) {
60
130
  * unresolvable passthrough call sites. Cycles short-circuit to an empty
61
131
  * result so resolution always terminates. */
62
132
  export function resolveThrowsUnion(manifest, ctx) {
63
- const name = manifest.metadata?.name;
133
+ const name = memoKey(manifest);
64
134
  if (name) {
65
135
  const cached = ctx.memo.get(name);
66
136
  if (cached)
@@ -223,8 +293,23 @@ function resolveStepInvokeThrows(step, invokeField, enclosingTryCodes, ctx, owne
223
293
  if (!invokeRef || typeof invokeRef !== "object")
224
294
  return emptyUnion();
225
295
  const invokedKind = invokeRef.kind;
226
- if (!invokedKind)
227
- return emptyUnion();
296
+ // A reference that still carries its parse-time sentinel — a library-internal
297
+ // `!ref` inside a manifest forwarded into a consumer's flat set, where Phase
298
+ // 2.5 had nothing to resolve it against. The target is in the declaring
299
+ // library's own documents, so it is looked up there; only a name that is not
300
+ // there either is UNKNOWN, which is unbounded rather than empty. Reading it as
301
+ // empty is what made a library's exported entry point present a `{∅}` union to
302
+ // its consumer and get the consumer's `catches:` rejected for the code the
303
+ // entry point documents.
304
+ if (!invokedKind) {
305
+ const sentinel = refSentinelTarget(invokeRef);
306
+ if (!sentinel)
307
+ return emptyUnion();
308
+ const target = findSentinelTarget(ctx, sentinel, ownerModule);
309
+ if (target)
310
+ return resolveThrowsUnion(target, ctx);
311
+ return { codes: new Map(), unbounded: true };
312
+ }
228
313
  // The invoked kind's alias resolves in the OWNER manifest's lexical scope (the
229
314
  // composer that declares the step), so a library's step referencing its own
230
315
  // import resolves against that library, not the consumer.
@@ -239,11 +324,10 @@ function resolveStepInvokeThrows(step, invokeField, enclosingTryCodes, ctx, owne
239
324
  const invokeName = invokeRef.name;
240
325
  if (invokeName) {
241
326
  const scopedInvokedKind = scopeResolver?.resolveKind(invokedKind);
242
- const target = ctx.allManifests.find((m) => m.metadata?.name === invokeName &&
243
- (m.kind === invokedKind ||
244
- ctx.aliases.resolveKind(m.kind) === invokedKind ||
245
- m.kind === ctx.aliases.resolveKind(invokedKind) ||
246
- (scopedInvokedKind !== undefined && m.kind === scopedInvokedKind)));
327
+ const target = findTarget(ctx, invokeName, ownerModule, (m) => m.kind === invokedKind ||
328
+ ctx.aliases.resolveKind(m.kind) === invokedKind ||
329
+ m.kind === ctx.aliases.resolveKind(invokedKind) ||
330
+ (scopedInvokedKind !== undefined && m.kind === scopedInvokedKind));
247
331
  if (target)
248
332
  return resolveThrowsUnion(target, ctx);
249
333
  }
@@ -17,7 +17,7 @@ import type { ResourceManifest } from "@telorun/sdk";
17
17
  import type { AliasResolver } from "./alias-resolver.js";
18
18
  import { type CallGraph, type ResourceGraphNode } from "./call-graph.js";
19
19
  import type { DefinitionRegistry } from "./definition-registry.js";
20
- import type { ZoneModuleDocuments } from "./zone-module-documents.js";
20
+ import type { ModuleDocuments } from "./module-documents.js";
21
21
  import { type AnalysisDiagnostic } from "./types.js";
22
22
  /** One open requirement on a library's exported resource — the contract an
23
23
  * importer must satisfy. Plain data, so it caches and crosses the
@@ -92,7 +92,7 @@ export declare function zoneDocumentsSignature(manifests: readonly ResourceManif
92
92
  * its full documents (which the flattened analysis view no longer holds), run
93
93
  * the projection derive-only, and keep what reaches an exported instance.
94
94
  */
95
- export declare function deriveLibraryExportRequirements(docs: ZoneModuleDocuments, defs: DefinitionRegistry, aliases: AliasResolver, aliasesByModule: Map<string, AliasResolver>, cache?: ZoneExportCache): ZoneExportRequirements;
95
+ export declare function deriveLibraryExportRequirements(docs: ModuleDocuments, defs: DefinitionRegistry, aliases: AliasResolver, aliasesByModule: Map<string, AliasResolver>, cache?: ZoneExportCache): ZoneExportRequirements;
96
96
  export interface ZoneAnalysisArgs {
97
97
  /** The entry analysis set (post inline-normalization + sentinel resolution). */
98
98
  manifests: ResourceManifest[];
@@ -101,7 +101,7 @@ export interface ZoneAnalysisArgs {
101
101
  aliases: AliasResolver;
102
102
  aliasesByModule: Map<string, AliasResolver>;
103
103
  rootModules: ReadonlySet<string>;
104
- moduleDocuments?: readonly ZoneModuleDocuments[];
104
+ moduleDocuments?: readonly ModuleDocuments[];
105
105
  cache?: ZoneExportCache;
106
106
  }
107
107
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-zone-requirements.d.ts","sourceRoot":"","sources":["../src/resolve-zone-requirements.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"resolve-zone-requirements.d.ts","sourceRoot":"","sources":["../src/resolve-zone-requirements.ts"],"names":[],"mappings":"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"}
@@ -1,15 +1,16 @@
1
- import { isRefSentinel } from "@telorun/templating";
1
+ import { refSentinelTarget } from "./ref-sentinel-target.js";
2
2
  import { buildCallGraph, } from "./call-graph.js";
3
3
  import { enclosingOf, propertySchemas, resolveLocalRef, } from "./manifest-navigation.js";
4
4
  import { readProvidesZone, readRequiresZone } from "./zone-slot.js";
5
5
  import { DiagnosticSeverity } from "./types.js";
6
+ import { moduleAliasScope } from "./module-alias-scope.js";
6
7
  const SOURCE = "telo-analyzer";
7
8
  /** Resolve a possibly alias-form kind to its definition in the DECLARING
8
9
  * module's scope — the same layering `AnalysisRegistry.resolveDefinitionIn`
9
10
  * uses. */
10
11
  function definitionResolver(defs, aliases, aliasesByModule) {
11
12
  return (kind, module) => {
12
- const scope = (module ? aliasesByModule.get(module) : undefined) ?? aliases;
13
+ const scope = moduleAliasScope({ module }, aliases, aliasesByModule);
13
14
  const canonical = scope.resolveKind(kind);
14
15
  return defs.resolve(kind) ?? (canonical ? defs.resolve(canonical) : undefined);
15
16
  };
@@ -67,18 +68,17 @@ function schemaNodeAt(rootSchema, slotPath) {
67
68
  * under-approximating direction the whole pass leans on. `Self.` is a local
68
69
  * name written the long way and does resolve.
69
70
  *
70
- * This deliberately differs from `call-graph`'s `refTargetName`, which answers a
71
- * different question (what an EDGE points at, cross-module included, for a graph
72
- * whose consumers tolerate an unresolved target) hence two functions rather
73
- * than one shared helper.
71
+ * This is this pass's REDUCTION over the shared `refSentinelTarget` parse, not a
72
+ * second reading of the tag: `call-graph`'s answers a different question (what
73
+ * an EDGE points at, cross-module included, for a graph whose consumers tolerate
74
+ * an unresolved target) and states its own reduction the same way.
74
75
  */
75
76
  function refName(value) {
76
- if (isRefSentinel(value)) {
77
- const source = value.source;
78
- const dot = source.indexOf(".");
79
- if (dot <= 0)
80
- return source;
81
- return source.slice(0, dot) === "Self" ? source.slice(dot + 1) : undefined;
77
+ const sentinel = refSentinelTarget(value);
78
+ if (sentinel) {
79
+ if (sentinel.alias === undefined)
80
+ return sentinel.name;
81
+ return sentinel.alias === "Self" ? sentinel.name : undefined;
82
82
  }
83
83
  if (!value || typeof value !== "object" || Array.isArray(value))
84
84
  return undefined;
@@ -1,3 +1,3 @@
1
1
  /** The surface generation this analyzer implements. */
2
- export declare const TELO_SURFACE_VERSION = "0.85.0";
2
+ export declare const TELO_SURFACE_VERSION = "0.87.0";
3
3
  //# sourceMappingURL=telo-version.d.ts.map
@@ -5,4 +5,4 @@
5
5
  // its release identity, this is the scale a module's `requires.telo` range is
6
6
  // written against, and every kernel in every language reports the same scale.
7
7
  /** The surface generation this analyzer implements. */
8
- export const TELO_SURFACE_VERSION = "0.85.0";
8
+ export const TELO_SURFACE_VERSION = "0.87.0";
@@ -1 +1 @@
1
- {"version":3,"file":"template-body.d.ts","sourceRoot":"","sources":["../src/template-body.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,YAAY;IAC3B;qBACiB;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,UAAU,EAAE,kBAAkB,GAAG,SAAS,CAAC;CAC5C;AAED;mDACmD;AACnD,wBAAgB,cAAc,CAC5B,CAAC,EAAE,gBAAgB,EACnB,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,EAAE,aAAa,GAAG,SAAS,EAClC,MAAM,EAAE,YAAY,GAAG,SAAS,GAC/B,YAAY,EAAE,CA8BhB;AAED,mEAAmE;AACnE,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAIhE;AAED;;+EAE+E;AAC/E,wBAAgB,WAAW,CAAC,CAAC,SAAS;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,EACtD,MAAM,EAAE,SAAS,CAAC,EAAE,EACpB,IAAI,EAAE,MAAM,GACX,CAAC,GAAG,SAAS,CAEf;AAED;;;;6CAI6C;AAC7C,wBAAgB,gBAAgB,CAAC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAQxF"}
1
+ {"version":3,"file":"template-body.d.ts","sourceRoot":"","sources":["../src/template-body.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGxD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,YAAY;IAC3B;qBACiB;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,UAAU,EAAE,kBAAkB,GAAG,SAAS,CAAC;CAC5C;AAED;mDACmD;AACnD,wBAAgB,cAAc,CAC5B,CAAC,EAAE,gBAAgB,EACnB,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,EAAE,aAAa,GAAG,SAAS,EAClC,MAAM,EAAE,YAAY,GAAG,SAAS,GAC/B,YAAY,EAAE,CA0BhB;AAED,mEAAmE;AACnE,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAIhE;AAED;;+EAE+E;AAC/E,wBAAgB,WAAW,CAAC,CAAC,SAAS;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,EACtD,MAAM,EAAE,SAAS,CAAC,EAAE,EACpB,IAAI,EAAE,MAAM,GACX,CAAC,GAAG,SAAS,CAEf;AAED;;;;6CAI6C;AAC7C,wBAAgB,gBAAgB,CAAC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAQxF"}
@@ -1,3 +1,4 @@
1
+ import { moduleAliasScope } from "./module-alias-scope.js";
1
2
  /** The template bodies a manifest declares — empty for anything that is not a
2
3
  * `Telo.Definition` with a `resources:` array. */
3
4
  export function templateBodies(m, registry, aliases, scopes) {
@@ -9,10 +10,7 @@ export function templateBodies(m, registry, aliases, scopes) {
9
10
  // A nested kind is written through the alias scope of the module that DECLARED
10
11
  // the definition, never the consumer's — the same rule every other kind
11
12
  // resolution in a forwarded manifest follows.
12
- const ownModule = m.metadata?.module;
13
- const scope = (ownModule && scopes && !scopes.rootModules.has(ownModule)
14
- ? scopes.aliasesByModule.get(ownModule)
15
- : undefined) ?? aliases;
13
+ const scope = moduleAliasScope(m.metadata, aliases, scopes?.aliasesByModule);
16
14
  const out = [];
17
15
  for (let i = 0; i < bodies.length; i++) {
18
16
  const body = bodies[i];
package/dist/types.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { HostVersions } from "./requires-block.js";
2
- import type { ZoneModuleDocuments } from "./zone-module-documents.js";
2
+ import type { ModuleDocuments } from "./module-documents.js";
3
3
  /** Matches LSP DiagnosticSeverity values exactly.
4
4
  * https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnosticSeverity */
5
5
  export declare const DiagnosticSeverity: {
@@ -130,10 +130,10 @@ export interface AnalysisOptions {
130
130
  /** Imported libraries' FULL document sets, for the zone stage's per-library
131
131
  * export derivation — the flattened analysis view forwards only each
132
132
  * library's export surface, never its internal dispatch chain. Collected
133
- * from a LoadedGraph via `collectZoneModuleDocuments`. Omitting it skips
133
+ * from a LoadedGraph via `collectModuleDocuments`. Omitting it skips
134
134
  * the derivation (the under-approximating direction — the runtime check
135
135
  * remains the enforcement). */
136
- moduleDocuments?: ZoneModuleDocuments[];
136
+ moduleDocuments?: ModuleDocuments[];
137
137
  /** When true, `analyze()` runs the state-mutating setup (module identity /
138
138
  * alias / definition registration plus `normalizeInlineResources`) but
139
139
  * skips every diagnostic-producing pass — per-resource validation, the
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -18,6 +18,11 @@ import { type AnalysisDiagnostic } from "./types.js";
18
18
  * whose input contract is now `inputType:`.
19
19
  * - CONTRACT_TYPE_NOT_FOUND: a contract names a type that is not declared in
20
20
  * scope, so every call through it would fail at dispatch.
21
+ * - CONTRACT_NOT_SUBSTITUTABLE: a definition replaces an ancestor's contract
22
+ * with a shape that cannot stand in for it. The one check nothing else makes:
23
+ * contracts resolve to the nearest declaration in BOTH halves, so a child that
24
+ * declares its own is compared against its abstract by neither the analyzer
25
+ * nor dispatch.
21
26
  *
22
27
  * Deliberately NOT diagnosed: an input that is neither `required:` nor
23
28
  * defaulted. It is indistinguishable from a genuinely optional one — `Ai.Text`
@@ -1 +1 @@
1
- {"version":3,"file":"validate-invocation-contract.d.ts","sourceRoot":"","sources":["../src/validate-invocation-contract.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AASnE,OAAO,EAAsB,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAIzE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,gBAAgB,EAAE,EAC7B,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,EAAE,aAAa,EACtB,eAAe,GAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAa,GACtD,kBAAkB,EAAE,CA4CtB"}
1
+ {"version":3,"file":"validate-invocation-contract.d.ts","sourceRoot":"","sources":["../src/validate-invocation-contract.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAanE,OAAO,EAAsB,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAIzE;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,gBAAgB,EAAE,EAC7B,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,EAAE,aAAa,EACtB,eAAe,GAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAa,GACtD,kBAAkB,EAAE,CA4CtB"}
@@ -1,5 +1,8 @@
1
- import { effectiveContractField, mappingFieldFor, needsContractMapping, } from "./extends-resolution.js";
1
+ import { ancestorChain, effectiveContractField, mappingFieldFor, needsContractMapping, } from "./extends-resolution.js";
2
+ import { resolveTypeFieldToSchema } from "./validate-cel-context.js";
3
+ import { moduleAliasScope } from "./module-alias-scope.js";
2
4
  import { buildReferenceFieldMap, isRefEntry } from "./reference-field-map.js";
5
+ import { checkSchemaCompatibility } from "./schema-compat.js";
3
6
  import { DiagnosticSeverity } from "./types.js";
4
7
  const SOURCE = "telo-analyzer";
5
8
  /**
@@ -18,6 +21,11 @@ const SOURCE = "telo-analyzer";
18
21
  * whose input contract is now `inputType:`.
19
22
  * - CONTRACT_TYPE_NOT_FOUND: a contract names a type that is not declared in
20
23
  * scope, so every call through it would fail at dispatch.
24
+ * - CONTRACT_NOT_SUBSTITUTABLE: a definition replaces an ancestor's contract
25
+ * with a shape that cannot stand in for it. The one check nothing else makes:
26
+ * contracts resolve to the nearest declaration in BOTH halves, so a child that
27
+ * declares its own is compared against its abstract by neither the analyzer
28
+ * nor dispatch.
21
29
  *
22
30
  * Deliberately NOT diagnosed: an input that is neither `required:` nor
23
31
  * defaulted. It is indistinguishable from a genuinely optional one — `Ai.Text`
@@ -29,8 +37,7 @@ const SOURCE = "telo-analyzer";
29
37
  export function validateInvocationContract(manifests, registry, aliases, aliasesByModule = new Map()) {
30
38
  const diagnostics = [];
31
39
  const resolveDef = (kind, from) => {
32
- const module = from?.metadata?.module;
33
- const scope = (module ? aliasesByModule.get(module) : undefined) ?? aliases;
40
+ const scope = moduleAliasScope(from?.metadata, aliases, aliasesByModule);
34
41
  return registry.resolve(kind) ?? registry.resolve(scope.resolveKind(kind) ?? kind);
35
42
  };
36
43
  // A published dependency's declarations are not the consumer's to fix.
@@ -58,6 +65,7 @@ export function validateInvocationContract(manifests, registry, aliases, aliases
58
65
  if (m.kind === "Telo.Definition" || m.kind === "Telo.Abstract") {
59
66
  checkMappingRequired(m, resource, filePath, resolveDef, diagnostics);
60
67
  checkContractResolves(m, md, manifests, resource, filePath, diagnostics);
68
+ checkAncestorSubstitutability(m, md, manifests, resource, filePath, resolveDef, diagnostics);
61
69
  continue;
62
70
  }
63
71
  // A RESOURCE (an instance of some kind) — a leftover `inputs:` map is only
@@ -318,6 +326,109 @@ function namedTypeReference(value) {
318
326
  return undefined;
319
327
  return typeof ref.name === "string" ? ref.name : undefined;
320
328
  }
329
+ /**
330
+ * A REPLACING CONTRACT MUST STILL STAND IN FOR THE ONE IT REPLACES.
331
+ *
332
+ * Contracts resolve to the NEAREST declaration and never merge, which is right —
333
+ * a call signature is not additive, and a backend narrowing `status` to the
334
+ * states it actually has could not express that through a merge. But the
335
+ * consequence is that an abstract's contract binds only the children that
336
+ * declare none of their own: a child that declares one is checked against
337
+ * nothing, statically or at dispatch, since `resolveBoundContract` stops at the
338
+ * same nearest declaration. So an abstract could state a floor every
339
+ * implementation must answer with (`Durable.Run`'s `runId` / `status`, the
340
+ * identity every later question about a run is asked by) and have that floor hold
341
+ * for exactly the implementations that declared nothing — while the real ones,
342
+ * which all declare their own, escaped it. A slot typed by the abstract would
343
+ * then be typed by a promise nothing kept.
344
+ *
345
+ * The rule is substitutability, and its direction differs per contract because
346
+ * one is produced and the other consumed:
347
+ *
348
+ * - `outputType` is COVARIANT — a consumer written against the ancestor reads
349
+ * the ancestor's shape, so the child's output must be acceptable where the
350
+ * ancestor's is declared. Dropping a required property is what breaks it.
351
+ * - `inputType` is CONTRAVARIANT — a caller written against the ancestor sends
352
+ * the ancestor's shape, so the ancestor's input must be acceptable where the
353
+ * child's is declared. Requiring an input the ancestor never mentions is what
354
+ * breaks it: no such caller could satisfy it.
355
+ *
356
+ * **Only an ABSTRACT ancestor's contract is a contract**, and that narrowing is a
357
+ * decision rather than an oversight. Extending a CONCRETE kind is how a friendlier
358
+ * schema is put over an existing controller — `base:` reshapes its config and
359
+ * `inputs:` / `result:` translate its call signature — so a child there is
360
+ * SUPPOSED to present different inputs, and demanding substitutability would
361
+ * reject the pattern the standard library and every custom-kind example are built
362
+ * on. An abstract has no implementation to reshape: extending one is a claim to
363
+ * BE the thing, its contract is written for implementors, and a slot typed by it
364
+ * is polymorphic by construction — which is exactly where an unkept promise has
365
+ * nowhere to be caught.
366
+ *
367
+ * A direction the child BRIDGES (`inputs:` for inputs, `result:` for outputs) is
368
+ * skipped for the same reason one hop down: the mapping is the author saying the
369
+ * shapes differ deliberately and are translated.
370
+ *
371
+ * The comparison is {@link checkSchemaCompatibility}, which reports only DEFINITE
372
+ * mismatches — a union, an absent `type`, an undeclared argument all read as
373
+ * compatible — so narrowing a value's type, adding an optional property or
374
+ * restricting an enum stays legal, which is the whole point of letting a child
375
+ * replace the contract at all.
376
+ */
377
+ function checkAncestorSubstitutability(m, md, manifests, resource, filePath, resolveDef, diagnostics) {
378
+ const def = m;
379
+ for (const direction of ["inputType", "outputType"]) {
380
+ const own = md[direction];
381
+ if (own === undefined || own === null)
382
+ continue;
383
+ // A declared bridge says the shapes differ on purpose and are translated.
384
+ if (md[mappingFieldFor(direction)] != null)
385
+ continue;
386
+ // The nearest ANCESTOR that declares it — the contract this one replaces.
387
+ // Walking past self is the whole question: `contractDeclarer` would answer
388
+ // "this one", which is what nothing checks.
389
+ const ancestor = ancestorChain(def, resolveDef).find((a) => {
390
+ const inherited = a[direction];
391
+ return inherited !== undefined && inherited !== null;
392
+ });
393
+ if (!ancestor || ancestor.kind !== "Telo.Abstract")
394
+ continue;
395
+ const inherited = ancestor[direction];
396
+ // The WHOLE manifest set, which is what `analyzerContractScope`'s
397
+ // `typeManifestsFor` hands `resolveContract` — so this resolves a named type
398
+ // exactly as the resolver the kernel binds with does. Filtering to the
399
+ // declaring module looked more careful and was strictly worse: a contract
400
+ // naming a shape from a shared module resolved to nothing, and an
401
+ // unresolvable side is skipped, so the check silently switched itself off for
402
+ // precisely the libraries that factor their shapes out. Nothing else caught
403
+ // it either — `CONTRACT_TYPE_NOT_FOUND` finds the type through its own global
404
+ // fallback, so such a kind passed `telo check` with no diagnostic at all.
405
+ const ownSchema = resolveTypeFieldToSchema(own, manifests);
406
+ const ancestorSchema = resolveTypeFieldToSchema(inherited, manifests);
407
+ // An unresolvable side says nothing about compatibility; CONTRACT_TYPE_NOT_FOUND
408
+ // is what reports a contract that names a type nothing declares.
409
+ if (!ownSchema || !ancestorSchema)
410
+ continue;
411
+ const { compatible, issues } = direction === "outputType"
412
+ ? checkSchemaCompatibility(ownSchema, ancestorSchema)
413
+ : checkSchemaCompatibility(ancestorSchema, ownSchema);
414
+ if (compatible)
415
+ continue;
416
+ const ancestorName = `${ancestor.metadata?.module ?? ""}.${ancestor.metadata?.name ?? "?"}`.replace(/^\./, "");
417
+ const why = direction === "outputType"
418
+ ? `every caller that holds this through '${ancestorName}' reads the shape that kind declares`
419
+ : `a caller that holds this through '${ancestorName}' sends the shape that kind declares`;
420
+ diagnostics.push({
421
+ severity: DiagnosticSeverity.Error,
422
+ code: "CONTRACT_NOT_SUBSTITUTABLE",
423
+ source: SOURCE,
424
+ message: `${m.kind}/${resource.name}: \`${direction}\` replaces the one declared by '${ancestorName}' ` +
425
+ `with a shape that cannot stand in for it — ${issues.join("; ")}. Contracts replace rather ` +
426
+ `than merge, so nothing re-checks this at dispatch: ${why}. Restate the fields ` +
427
+ `'${ancestorName}' declares, or drop \`${direction}\` to inherit the contract unchanged.`,
428
+ data: { resource, filePath, path: direction },
429
+ });
430
+ }
431
+ }
321
432
  /** A child that inherits its controller and REPLACES a contract must bridge it:
322
433
  * contracts resolve to the nearest declaration and never merge, so the
323
434
  * inherited controller only understands its own shape. Without the mapping the
@@ -1 +1 @@
1
- {"version":3,"file":"validate-logging.d.ts","sourceRoot":"","sources":["../src/validate-logging.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAEnE,OAAO,EAAsB,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAIzE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,gBAAgB,EAAE,EAC7B,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,EAAE,aAAa,EACtB,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,GAC3C,kBAAkB,EAAE,CAqBtB"}
1
+ {"version":3,"file":"validate-logging.d.ts","sourceRoot":"","sources":["../src/validate-logging.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAEnE,OAAO,EAAsB,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAKzE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,gBAAgB,EAAE,EAC7B,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,EAAE,aAAa,EACtB,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,GAC3C,kBAAkB,EAAE,CAqBtB"}
@@ -1,5 +1,6 @@
1
1
  import { parseRedactionPath, RedactionPathError } from "./redaction-path.js";
2
2
  import { DiagnosticSeverity } from "./types.js";
3
+ import { moduleAliasScope } from "./module-alias-scope.js";
3
4
  const SOURCE = "telo-analyzer";
4
5
  /**
5
6
  * Static validation of the `logging:` block — `kernel/specs/logging.md` §14.1
@@ -106,8 +107,7 @@ function isSinkKind(manifest, registry, aliases, aliasesByModule) {
106
107
  return false;
107
108
  if (manifest.kind === "Telo.ConsoleSink" || manifest.kind === "Telo.FileSink")
108
109
  return true;
109
- const ownModule = manifest.metadata?.module;
110
- const resolver = (ownModule ? aliasesByModule?.get(ownModule) : undefined) ?? aliases;
110
+ const resolver = moduleAliasScope(manifest.metadata, aliases, aliasesByModule);
111
111
  const canonical = resolver.resolveKind(manifest.kind) ?? manifest.kind;
112
112
  return registry.resolve(canonical)?.capability === "Telo.Sink";
113
113
  }
@@ -11,12 +11,23 @@ import type { DefinitionRegistry } from "./definition-registry.js";
11
11
  *
12
12
  * A value satisfies the slot when it transitively extends the target kind, or —
13
13
  * for a CONCRETE target — IS that kind; `getByExtends` is the same transitive
14
- * subtype index for both, and an abstract is satisfied only by an implementer,
15
- * never by the abstract itself (which is non-instantiable). Accepts a constraint
16
- * that resolves to nothing, and an abstract with no loaded implementations:
17
- * partial context, where a rejection would be a guess.
14
+ * subtype index for both. Accepts a constraint that resolves to nothing, and an
15
+ * abstract with no loaded implementations: partial context, where a rejection
16
+ * would be a guess.
17
+ *
18
+ * An abstract is satisfied only by an implementer, never by the abstract itself,
19
+ * because a resource declared `kind: <some abstract>` is refused at `create()`
20
+ * and reported as `ABSTRACT_KIND_INSTANTIATED` at its declaration — so accepting
21
+ * it here would leave the reference sites silent about a manifest that cannot
22
+ * run. `isDeclaration` is the ONE exception and it is not an instance: a
23
+ * library's `resources:` entry is constrained by kind alone, so its kind-only
24
+ * stand-in routinely IS an abstract (`connection: {kind: Sql.Connection}`), and
25
+ * every use of that name inside the library is a reference to it.
18
26
  */
19
- export declare function kindSatisfies(resolved: string, targetKind: string, registry: DefinitionRegistry): boolean;
27
+ export declare function kindSatisfies(resolved: string, targetKind: string, registry: DefinitionRegistry,
28
+ /** The referent is a kind-only stand-in for a `resources:` entry rather than a
29
+ * resource anything instantiates, so identity satisfies an abstract slot. */
30
+ isDeclaration?: boolean): boolean;
20
31
  /**
21
32
  * Phase 3 — Reference validation.
22
33
  *
@@ -1 +1 @@
1
- {"version":3,"file":"validate-references.d.ts","sourceRoot":"","sources":["../src/validate-references.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAarD,OAAO,EAAsB,KAAK,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAE/F,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAInE;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,kBAAkB,GAC3B,OAAO,CAwBT;AA8DD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,gBAAgB,EAAE,EAC7B,OAAO,EAAE,eAAe,GACvB,kBAAkB,EAAE,CA2gBtB"}
1
+ {"version":3,"file":"validate-references.d.ts","sourceRoot":"","sources":["../src/validate-references.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAarD,OAAO,EAAsB,KAAK,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAE/F,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAMnE;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,kBAAkB;AAC5B;8EAC8E;AAC9E,aAAa,UAAQ,GACpB,OAAO,CAwBT;AAgED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,gBAAgB,EAAE,EAC7B,OAAO,EAAE,eAAe,GACvB,kBAAkB,EAAE,CA0hBtB"}