@telorun/analyzer 0.73.0 → 0.74.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 (138) hide show
  1. package/dist/analyzer.d.ts.map +1 -1
  2. package/dist/analyzer.js +26 -7
  3. package/dist/artifact-axes.d.ts +14 -0
  4. package/dist/artifact-axes.d.ts.map +1 -0
  5. package/dist/artifact-axes.js +12 -0
  6. package/dist/artifact-layer-index.d.ts +2 -2
  7. package/dist/artifact-layer-index.d.ts.map +1 -1
  8. package/dist/artifact-layer-index.js +9 -4
  9. package/dist/artifact-selector.d.ts +47 -21
  10. package/dist/artifact-selector.d.ts.map +1 -1
  11. package/dist/artifact-selector.js +85 -16
  12. package/dist/builtins.d.ts.map +1 -1
  13. package/dist/builtins.js +73 -16
  14. package/dist/call-graph.d.ts +12 -1
  15. package/dist/call-graph.d.ts.map +1 -1
  16. package/dist/call-graph.js +22 -0
  17. package/dist/catch-scope.js +1 -1
  18. package/dist/forwarded-declaration.d.ts +26 -0
  19. package/dist/forwarded-declaration.d.ts.map +1 -0
  20. package/dist/forwarded-declaration.js +31 -0
  21. package/dist/index.d.ts +9 -3
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +4 -1
  24. package/dist/kernel-globals.d.ts.map +1 -1
  25. package/dist/kernel-globals.js +21 -5
  26. package/dist/module-alias-scope.d.ts +11 -0
  27. package/dist/module-alias-scope.d.ts.map +1 -1
  28. package/dist/module-alias-scope.js +10 -0
  29. package/dist/module-file-claims.d.ts +17 -1
  30. package/dist/module-file-claims.d.ts.map +1 -1
  31. package/dist/module-file-claims.js +38 -3
  32. package/dist/module-named-files.d.ts +72 -0
  33. package/dist/module-named-files.d.ts.map +1 -0
  34. package/dist/module-named-files.js +115 -0
  35. package/dist/native-entries.d.ts +83 -0
  36. package/dist/native-entries.d.ts.map +1 -0
  37. package/dist/native-entries.js +169 -0
  38. package/dist/normalize-inline-resources.d.ts +41 -13
  39. package/dist/normalize-inline-resources.d.ts.map +1 -1
  40. package/dist/normalize-inline-resources.js +236 -54
  41. package/dist/reference-field-map.d.ts +59 -1
  42. package/dist/reference-field-map.d.ts.map +1 -1
  43. package/dist/reference-field-map.js +200 -34
  44. package/dist/release/payload-digest.d.ts +2 -1
  45. package/dist/release/payload-digest.d.ts.map +1 -1
  46. package/dist/release/payload-digest.js +2 -1
  47. package/dist/resolve-ref-sentinels.d.ts.map +1 -1
  48. package/dist/resolve-ref-sentinels.js +8 -5
  49. package/dist/resolve-throws-union.d.ts +25 -4
  50. package/dist/resolve-throws-union.d.ts.map +1 -1
  51. package/dist/resolve-throws-union.js +62 -32
  52. package/dist/resolve-zone-requirements.d.ts.map +1 -1
  53. package/dist/resolve-zone-requirements.js +2 -1
  54. package/dist/rewrite-synthetic-origins.d.ts +6 -1
  55. package/dist/rewrite-synthetic-origins.d.ts.map +1 -1
  56. package/dist/rewrite-synthetic-origins.js +107 -13
  57. package/dist/schema-compat.d.ts.map +1 -1
  58. package/dist/schema-compat.js +18 -5
  59. package/dist/schema-walk.d.ts +47 -13
  60. package/dist/schema-walk.d.ts.map +1 -1
  61. package/dist/schema-walk.js +150 -30
  62. package/dist/scope-declarations.d.ts +59 -0
  63. package/dist/scope-declarations.d.ts.map +1 -0
  64. package/dist/scope-declarations.js +45 -0
  65. package/dist/source-entries.d.ts +119 -0
  66. package/dist/source-entries.d.ts.map +1 -0
  67. package/dist/source-entries.js +349 -0
  68. package/dist/step-bodies.d.ts +24 -0
  69. package/dist/step-bodies.d.ts.map +1 -0
  70. package/dist/step-bodies.js +28 -0
  71. package/dist/telo-version.d.ts +1 -1
  72. package/dist/telo-version.js +1 -1
  73. package/dist/validate-cel-context.d.ts.map +1 -1
  74. package/dist/validate-cel-context.js +3 -2
  75. package/dist/validate-module-artifact.d.ts +4 -2
  76. package/dist/validate-module-artifact.d.ts.map +1 -1
  77. package/dist/validate-module-artifact.js +43 -4
  78. package/dist/validate-native-entries.d.ts +15 -0
  79. package/dist/validate-native-entries.d.ts.map +1 -0
  80. package/dist/validate-native-entries.js +103 -0
  81. package/dist/validate-observed-state.d.ts +7 -1
  82. package/dist/validate-observed-state.d.ts.map +1 -1
  83. package/dist/validate-observed-state.js +24 -6
  84. package/dist/validate-reference-forms.d.ts.map +1 -1
  85. package/dist/validate-reference-forms.js +2 -2
  86. package/dist/validate-references.d.ts.map +1 -1
  87. package/dist/validate-references.js +11 -5
  88. package/dist/validate-scope-reach.d.ts +31 -0
  89. package/dist/validate-scope-reach.d.ts.map +1 -0
  90. package/dist/validate-scope-reach.js +180 -0
  91. package/dist/validate-source-entries.d.ts +16 -0
  92. package/dist/validate-source-entries.d.ts.map +1 -0
  93. package/dist/validate-source-entries.js +90 -0
  94. package/dist/validate-throws-coverage.d.ts.map +1 -1
  95. package/dist/validate-throws-coverage.js +21 -39
  96. package/dist/value-type-keyword.d.ts +22 -5
  97. package/dist/value-type-keyword.d.ts.map +1 -1
  98. package/dist/value-type-keyword.js +16 -7
  99. package/package.json +3 -3
  100. package/src/analyzer.ts +33 -9
  101. package/src/artifact-axes.ts +24 -0
  102. package/src/artifact-layer-index.ts +9 -6
  103. package/src/artifact-selector.ts +110 -35
  104. package/src/builtins.ts +75 -16
  105. package/src/call-graph.ts +30 -0
  106. package/src/catch-scope.ts +1 -1
  107. package/src/forwarded-declaration.ts +32 -0
  108. package/src/index.ts +36 -1
  109. package/src/kernel-globals.ts +28 -5
  110. package/src/migrations/CLAUDE.md +35 -0
  111. package/src/module-alias-scope.ts +17 -0
  112. package/src/module-file-claims.ts +63 -4
  113. package/src/module-named-files.ts +162 -0
  114. package/src/native-entries.ts +227 -0
  115. package/src/normalize-inline-resources.ts +326 -70
  116. package/src/reference-field-map.ts +257 -52
  117. package/src/release/CLAUDE.md +32 -0
  118. package/src/release/payload-digest.ts +2 -1
  119. package/src/resolve-ref-sentinels.ts +7 -6
  120. package/src/resolve-throws-union.ts +87 -32
  121. package/src/resolve-zone-requirements.ts +2 -1
  122. package/src/rewrite-synthetic-origins.ts +107 -16
  123. package/src/schema-compat.ts +18 -4
  124. package/src/schema-walk.ts +162 -34
  125. package/src/scope-declarations.ts +98 -0
  126. package/src/source-entries.ts +502 -0
  127. package/src/step-bodies.ts +55 -0
  128. package/src/telo-version.ts +1 -1
  129. package/src/validate-cel-context.ts +3 -2
  130. package/src/validate-module-artifact.ts +46 -3
  131. package/src/validate-native-entries.ts +147 -0
  132. package/src/validate-observed-state.ts +36 -7
  133. package/src/validate-reference-forms.ts +2 -3
  134. package/src/validate-references.ts +10 -6
  135. package/src/validate-scope-reach.ts +213 -0
  136. package/src/validate-source-entries.ts +120 -0
  137. package/src/validate-throws-coverage.ts +24 -31
  138. package/src/value-type-keyword.ts +35 -9
@@ -1,5 +1,23 @@
1
+ import { resolveLocalRef } from "./manifest-navigation.js";
1
2
  import { readRefSlot } from "./ref-slot.js";
3
+ import { readStepSlot } from "./step-slot.js";
2
4
  export { readRefSlot, isRefSlot, hasDeclaredUse } from "./ref-slot.js";
5
+ /** The slot an entry records, as `readRefSlot` read it. */
6
+ export function refSlotOfEntry(entry) {
7
+ const slot = {
8
+ kinds: entry.refs,
9
+ uses: entry.uses,
10
+ inline: entry.inline === true,
11
+ valueBranches: entry.valueBranches ?? [],
12
+ };
13
+ if (entry.useCases)
14
+ slot.useCases = entry.useCases;
15
+ if (entry.inputs !== undefined)
16
+ slot.inputs = entry.inputs;
17
+ if (entry.throwsThrough)
18
+ slot.throwsThrough = true;
19
+ return slot;
20
+ }
3
21
  export function isRefEntry(entry) {
4
22
  return "refs" in entry;
5
23
  }
@@ -121,9 +139,10 @@ export function resolveFieldValues(obj, path) {
121
139
  */
122
140
  export function buildReferenceFieldMap(schema) {
123
141
  const map = new Map();
142
+ const sink = injectionSink(map);
124
143
  if (schema.properties) {
125
144
  for (const [key, propSchema] of Object.entries(schema.properties)) {
126
- traverseNode(propSchema, key, map, schema);
145
+ traverseNode(propSchema, key, sink, schema);
127
146
  }
128
147
  }
129
148
  return map;
@@ -140,32 +159,175 @@ export function collectRefs(node) {
140
159
  * hid behind the schema-from indirection. */
141
160
  export function buildFieldMapAtPath(schema, pathPrefix) {
142
161
  const map = new Map();
143
- traverseNode(schema, pathPrefix, map, schema);
162
+ traverseNode(schema, pathPrefix, injectionSink(map), schema);
144
163
  return map;
145
164
  }
146
- function traverseNode(node, path, map, root, visitedRefs = new Set()) {
147
- // Local `$ref` is intentionally NOT followed. This map is the kernel's
165
+ const drivenSlotMaps = new WeakMap();
166
+ /** The resource envelope: present on every resource document, and never
167
+ * configuration a kind's root `additionalProperties` describes. */
168
+ const RESOURCE_ENVELOPE_KEYS = ["kind", "metadata"];
169
+ /**
170
+ * Every slot through which a resource of this schema DRIVES another — the
171
+ * reference field map's own traversal, plus what a dispatch analysis needs and
172
+ * the injection surface must not have:
173
+ *
174
+ * - local `$ref` is followed, resolved against the root. The injection map
175
+ * stops there so a step's `invoke` never becomes an injection site; this map
176
+ * stops AT a step body instead, which removes that reason. A reference back
177
+ * to a node already on the descent is recorded as a back-edge rather than
178
+ * unrolled, so a recursive shape stays finite here and is followed as deep as
179
+ * the data goes by `forEachDrivenSlot`;
180
+ * - a step body is recorded and not descended — the step traversal owns
181
+ * everything below it;
182
+ * - the root's own variant branches and `additionalProperties` are walked, not
183
+ * only its `properties`;
184
+ * - a path keeps EVERY slot any branch declares there, where the injection map
185
+ * keeps the last one written (see {@link DrivenPath.refs});
186
+ * - each `{}` path records the keys its `additionalProperties` does not cover.
187
+ *
188
+ * Shared by every throws question (a kind's `inherit` union, a scope list's
189
+ * denominator, catch-scope enclosure, and whether `inherit` is legal at all),
190
+ * so none can reach a slot another cannot. Memoized per schema object.
191
+ */
192
+ export function buildDrivenSlotMap(schema) {
193
+ const cached = drivenSlotMaps.get(schema);
194
+ if (cached)
195
+ return cached;
196
+ const slots = { paths: new Map(), declaredKeys: new Map(), drives: false };
197
+ traverseNode(schema, "", drivenSink(slots), schema);
198
+ drivenSlotMaps.set(schema, slots);
199
+ return slots;
200
+ }
201
+ const joinPath = (path, key) => (path ? `${path}.${key}` : key);
202
+ /** The injection map: one entry per path, the last one written. Step bodies,
203
+ * back-edges and map-value keys are the driven map's alone. */
204
+ function injectionSink(map) {
205
+ return {
206
+ driven: false,
207
+ ref: (path, entry) => {
208
+ map.set(path, entry);
209
+ },
210
+ stop: (path, entry) => {
211
+ map.set(path, entry);
212
+ },
213
+ step: () => { },
214
+ recurse: () => { },
215
+ mapValue: () => { },
216
+ };
217
+ }
218
+ function drivenSink(slots) {
219
+ const recorded = new Map();
220
+ const at = (path) => {
221
+ let entry = slots.paths.get(path);
222
+ if (!entry) {
223
+ entry = { refs: [], steps: [], recurse: [] };
224
+ slots.paths.set(path, entry);
225
+ }
226
+ return entry;
227
+ };
228
+ // One schema node reached twice at one path (two branches `$ref`-ing one
229
+ // definition) is one slot.
230
+ const firstTime = (path, node) => {
231
+ let nodes = recorded.get(path);
232
+ if (!nodes)
233
+ recorded.set(path, (nodes = new Set()));
234
+ if (nodes.has(node))
235
+ return false;
236
+ nodes.add(node);
237
+ return true;
238
+ };
239
+ return {
240
+ driven: true,
241
+ ref: (path, entry, node) => {
242
+ if (!firstTime(path, node))
243
+ return;
244
+ at(path).refs.push(entry);
245
+ slots.drives = true;
246
+ },
247
+ stop: () => { },
248
+ step: (path, step, node) => {
249
+ if (!firstTime(path, node))
250
+ return;
251
+ at(path).steps.push(step);
252
+ slots.drives = true;
253
+ },
254
+ recurse: (path, to) => {
255
+ const entry = at(path);
256
+ if (!entry.recurse.includes(to))
257
+ entry.recurse.push(to);
258
+ },
259
+ mapValue: (mapPath, declared) => {
260
+ const previous = slots.declaredKeys.get(mapPath);
261
+ slots.declaredKeys.set(mapPath, new Set(previous ? declared.filter((key) => previous.has(key)) : declared));
262
+ },
263
+ };
264
+ }
265
+ /** Follow a local `$ref` in driven mode. `onStack` maps each node on the
266
+ * current descent to the path it was entered at: re-entering one records a
267
+ * back-edge to that path, and a cycle that made no structural progress (same
268
+ * path) records nothing, since its body is already recorded there. */
269
+ function followLocalRef(node, path, sink, root, onStack) {
270
+ if (!root)
271
+ return;
272
+ const target = resolveLocalRef(node, root);
273
+ if (!target || target === node)
274
+ return;
275
+ const entered = onStack.get(target);
276
+ if (entered !== undefined) {
277
+ if (entered !== path)
278
+ sink.recurse(path, entered);
279
+ return;
280
+ }
281
+ onStack.set(target, path);
282
+ try {
283
+ traverseNode(target, path, sink, root, onStack);
284
+ }
285
+ finally {
286
+ onStack.delete(target);
287
+ }
288
+ }
289
+ /** `owner.additionalProperties`, the schema of every value in an open-keyed
290
+ * object. JSON Schema applies it only to keys `owner` does not declare, which
291
+ * the driven map records so a walk skips them. */
292
+ function traverseMapValue(owner, path, sink, root, onStack) {
293
+ const valueSchema = owner.additionalProperties;
294
+ if (!valueSchema || typeof valueSchema !== "object" || Array.isArray(valueSchema))
295
+ return;
296
+ const mapPath = joinPath(path, "{}");
297
+ const declared = owner.properties && typeof owner.properties === "object" ? Object.keys(owner.properties) : [];
298
+ sink.mapValue(mapPath, path === "" ? [...declared, ...RESOURCE_ENVELOPE_KEYS] : declared);
299
+ traverseNode(valueSchema, mapPath, sink, root, onStack);
300
+ }
301
+ function traverseNode(node, path, sink, root, onStack = new Map()) {
302
+ const driven = sink.driven;
303
+ // Local `$ref` is intentionally NOT followed here. This map is the kernel's
148
304
  // Phase-5 injection surface: descending into shared `$defs` (notably
149
305
  // `Run.Sequence`'s `step` definition) would make every step's `invoke` an
150
306
  // injection site, and step slots resolve at dispatch — injecting there is
151
307
  // unwanted regardless of tracing (the original dispatcher-bypass blocker
152
308
  // has since shipped via the `REF_IDENTITY` stamp). Static analysis is NOT
153
309
  // limited by this stop: the call graph (`call-graph.ts`) reads step slots
154
- // from the item schema itself and scans the value tree, so it sees what
155
- // this map deliberately hides. `visitedRefs` stays as a parameter so the
156
- // recursive calls below thread the right signature.
157
- if (typeof node?.$ref === "string")
310
+ // from the item schema itself and scans the value tree, and the driven-slot
311
+ // mode (`buildDrivenSlotMap`) follows the reference.
312
+ if (typeof node?.$ref === "string" && !driven)
158
313
  return;
159
314
  // Scope slot — record and stop; do not recurse into scope contents
160
315
  if ("x-telo-scope" in node) {
161
- map.set(path, { scope: node["x-telo-scope"] });
316
+ sink.stop(path, { scope: node["x-telo-scope"] });
162
317
  return;
163
318
  }
164
319
  // Schema-from slot — record and stop; no further traversal needed
165
320
  if ("x-telo-schema-from" in node) {
166
- map.set(path, { schemaFrom: node["x-telo-schema-from"] });
321
+ sink.stop(path, { schemaFrom: node["x-telo-schema-from"] });
167
322
  return;
168
323
  }
324
+ if (driven) {
325
+ const step = readStepSlot(node);
326
+ if (step) {
327
+ sink.step(path, step, node);
328
+ return;
329
+ }
330
+ }
169
331
  // Reference slot (direct, via a `kind:` list, or via anyOf)
170
332
  const slot = readRefSlot(node);
171
333
  if (slot && slot.kinds.length > 0) {
@@ -184,7 +346,9 @@ function traverseNode(node, path, map, root, visitedRefs = new Set()) {
184
346
  entry.context = node["x-telo-context"];
185
347
  if (slot.inline)
186
348
  entry.inline = true;
187
- map.set(path, entry);
349
+ if (slot.throwsThrough)
350
+ entry.throwsThrough = true;
351
+ sink.ref(path, entry, node);
188
352
  // A node can mix item-level ref branches (a bare string / `{kind, name}`)
189
353
  // with object branches that carry their OWN nested refs — e.g. Application
190
354
  // `targets`: a bare ref vs inline `{ invoke }` vs gated `{ ref }`. Descend
@@ -198,21 +362,24 @@ function traverseNode(node, path, map, root, visitedRefs = new Set()) {
198
362
  for (const variant of variants) {
199
363
  if (!variant || typeof variant !== "object")
200
364
  continue;
201
- traverseVariant(variant, path, map, root, visitedRefs);
365
+ traverseVariant(variant, path, sink, root, onStack);
202
366
  }
203
367
  }
204
368
  return;
205
369
  }
206
- if (typeof node?.$ref === "string")
370
+ // Reached only in driven mode — the injection map stopped at the top.
371
+ if (typeof node?.$ref === "string") {
372
+ followLocalRef(node, path, sink, root, onStack);
207
373
  return;
374
+ }
208
375
  // Array — recurse into items
209
376
  if (node.type === "array" && node.items) {
210
- traverseNode(node.items, path + "[]", map, root, visitedRefs);
377
+ traverseNode(node.items, path + "[]", sink, root, onStack);
211
378
  }
212
379
  // Object — recurse into properties
213
380
  if (node.properties) {
214
381
  for (const [key, propSchema] of Object.entries(node.properties)) {
215
- traverseNode(propSchema, `${path}.${key}`, map, root, visitedRefs);
382
+ traverseNode(propSchema, joinPath(path, key), sink, root, onStack);
216
383
  }
217
384
  }
218
385
  // Variant branches — descend into every alternative's properties / items.
@@ -221,10 +388,11 @@ function traverseNode(node, path, map, root, visitedRefs = new Set()) {
221
388
  // slots inside the branch. Walking each branch surfaces those slots into
222
389
  // the field map so downstream passes (ref validation, sentinel
223
390
  // resolution, dependency graph) cover them without a runtime fallback.
224
- // The same field path may be added by multiple branches; the later
225
- // assignment wins, which is fine — branches with the same field path
226
- // share the same ref/context configuration (any divergence is already
227
- // a schema bug).
391
+ // The same field path may be added by multiple branches. The injection map
392
+ // keeps the later assignment, which is fine for injection — branches with
393
+ // the same field path share the same ref/context configuration. The driven
394
+ // map keeps every one, because which branch applies decides what a
395
+ // dispatch can throw.
228
396
  for (const variantKey of ["oneOf", "anyOf", "allOf"]) {
229
397
  const variants = node[variantKey];
230
398
  if (!Array.isArray(variants))
@@ -232,34 +400,32 @@ function traverseNode(node, path, map, root, visitedRefs = new Set()) {
232
400
  for (const variant of variants) {
233
401
  if (!variant || typeof variant !== "object")
234
402
  continue;
235
- traverseVariant(variant, path, map, root, visitedRefs);
403
+ traverseVariant(variant, path, sink, root, onStack);
236
404
  }
237
405
  }
238
406
  // Map — `additionalProperties: { ... }` describes every value in an
239
407
  // open-keyed object. Encoder refs nested inside `content[mime]` map
240
408
  // entries reach Phase 5 through this branch.
241
- if (node.additionalProperties &&
242
- typeof node.additionalProperties === "object" &&
243
- !Array.isArray(node.additionalProperties)) {
244
- traverseNode(node.additionalProperties, `${path}.{}`, map, root, visitedRefs);
245
- }
409
+ traverseMapValue(node, path, sink, root, onStack);
246
410
  }
247
411
  /** Walk a single variant of a `oneOf` / `anyOf` / `allOf` branch. Only
248
412
  * the properties / items / map slots are followed — collectRefs at the
249
413
  * variant root is handled by the parent's `collectRefs(node)` already
250
- * (anyOf of x-telo-ref branches is the canonical multi-ref shape). */
251
- function traverseVariant(variant, path, map, root, visitedRefs = new Set()) {
414
+ * (anyOf of x-telo-ref branches is the canonical multi-ref shape). In
415
+ * driven mode a `$ref` branch is followed as a node in its own right, since
416
+ * `readRefSlot` does not look through one. */
417
+ function traverseVariant(variant, path, sink, root, onStack = new Map()) {
418
+ if (sink.driven && typeof variant.$ref === "string") {
419
+ followLocalRef(variant, path, sink, root, onStack);
420
+ return;
421
+ }
252
422
  if (variant.properties) {
253
423
  for (const [key, propSchema] of Object.entries(variant.properties)) {
254
- traverseNode(propSchema, `${path}.${key}`, map, root, visitedRefs);
424
+ traverseNode(propSchema, joinPath(path, key), sink, root, onStack);
255
425
  }
256
426
  }
257
427
  if (variant.type === "array" && variant.items) {
258
- traverseNode(variant.items, path + "[]", map, root, visitedRefs);
259
- }
260
- if (variant.additionalProperties &&
261
- typeof variant.additionalProperties === "object" &&
262
- !Array.isArray(variant.additionalProperties)) {
263
- traverseNode(variant.additionalProperties, `${path}.{}`, map, root, visitedRefs);
428
+ traverseNode(variant.items, path + "[]", sink, root, onStack);
264
429
  }
430
+ traverseMapValue(variant, path, sink, root, onStack);
265
431
  }
@@ -49,7 +49,8 @@ export declare const LOCALLY_DERIVED_LAYERS: ReadonlySet<string>;
49
49
  * `axis=value;…` form, because this string is read by a human in a ledger diff
50
50
  * and written into a plain YAML key; the axis order is `PLATFORM_AXES`, so the
51
51
  * rendering is deterministic rather than dependent on how the selector was
52
- * built.
52
+ * built. An axis a selector omits renders nothing, so a new axis appended to the
53
+ * vocabulary leaves every existing key unchanged — reordering it would not.
53
54
  */
54
55
  export declare function layerDigestKey(role: LayerRole | string, selector?: ArtifactSelector): string;
55
56
  /** A layer whose digest differs between two readings, or that exists in only
@@ -1 +1 @@
1
- {"version":3,"file":"payload-digest.d.ts","sourceRoot":"","sources":["../../src/release/payload-digest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAiB,KAAK,gBAAgB,EAAE,KAAK,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAE/F,sDAAsD;AACtD,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAE5D,yDAAyD;AACzD,eAAO,MAAM,cAAc,aAAa,CAAC;AAEzC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,sBAAsB,EAAE,WAAW,CAAC,MAAM,CAA6B,CAAC;AAErF;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,EAAE,QAAQ,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAM5F;AAED;;;mBAGmB;AACnB,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;mCACmC;AACnC,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,GAAG,WAAW,EAAE,CAQzF"}
1
+ {"version":3,"file":"payload-digest.d.ts","sourceRoot":"","sources":["../../src/release/payload-digest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAiB,KAAK,gBAAgB,EAAE,KAAK,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAE/F,sDAAsD;AACtD,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAE5D,yDAAyD;AACzD,eAAO,MAAM,cAAc,aAAa,CAAC;AAEzC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,sBAAsB,EAAE,WAAW,CAAC,MAAM,CAA6B,CAAC;AAErF;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,EAAE,QAAQ,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAM5F;AAED;;;mBAGmB;AACnB,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;mCACmC;AACnC,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,GAAG,WAAW,EAAE,CAQzF"}
@@ -47,7 +47,8 @@ export const LOCALLY_DERIVED_LAYERS = new Set([MANIFEST_LAYER]);
47
47
  * `axis=value;…` form, because this string is read by a human in a ledger diff
48
48
  * and written into a plain YAML key; the axis order is `PLATFORM_AXES`, so the
49
49
  * rendering is deterministic rather than dependent on how the selector was
50
- * built.
50
+ * built. An axis a selector omits renders nothing, so a new axis appended to the
51
+ * vocabulary leaves every existing key unchanged — reordering it would not.
51
52
  */
52
53
  export function layerDigestKey(role, selector) {
53
54
  if (!selector)
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-ref-sentinels.d.ts","sourceRoot":"","sources":["../src/resolve-ref-sentinels.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,0BAA0B,CAAC;AAGlC;+CAC+C;AAC/C,MAAM,WAAW,mBAAmB;IAClC,kBAAkB,CAChB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;QAAE,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;KAAE,GACvD,iBAAiB,GAAG,SAAS,CAAC;CAClC;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,gBAAgB,EAAE,EAC7B,OAAO,CAAC,EAAE,aAAa,EACvB,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,EAK5C,kBAAkB,GAAE,gBAAgB,EAAO;AAC3C;;+CAE+C;AAC/C,IAAI,CAAC,EAAE,mBAAmB,GACzB,IAAI,CAyIN"}
1
+ {"version":3,"file":"resolve-ref-sentinels.d.ts","sourceRoot":"","sources":["../src/resolve-ref-sentinels.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,0BAA0B,CAAC;AAIlC;+CAC+C;AAC/C,MAAM,WAAW,mBAAmB;IAClC,kBAAkB,CAChB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;QAAE,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;KAAE,GACvD,iBAAiB,GAAG,SAAS,CAAC;CAClC;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,gBAAgB,EAAE,EAC7B,OAAO,CAAC,EAAE,aAAa,EACvB,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,EAK5C,kBAAkB,GAAE,gBAAgB,EAAO;AAC3C;;+CAE+C;AAC/C,IAAI,CAAC,EAAE,mBAAmB,GACzB,IAAI,CAyIN"}
@@ -1,6 +1,7 @@
1
1
  import { isRefSentinel, isTaggedSentinel } from "@telorun/templating";
2
2
  import { isScopeEntry, resolveFieldEntries, } from "./reference-field-map.js";
3
3
  import { REF_RESOLUTION_SKIP_KINDS as SYSTEM_KINDS } from "./system-kinds.js";
4
+ import { isForwardedDeclaration, isForwardedExport } from "./forwarded-declaration.js";
4
5
  /**
5
6
  * Rewrites every `!ref <name>` sentinel in each non-system resource's value tree
6
7
  * to `{kind, name}` (local) or `{kind, name, alias}` (cross-module), in place.
@@ -48,9 +49,10 @@ crossModuleTargets = [],
48
49
  * it shadows — so both call sites pass it. */
49
50
  defs) {
50
51
  const moduleOf = (r) => r.metadata?.module;
51
- // Forwarded exports are flagged by flattenForAnalyzer (`metadata.forwardedExport`); they're
52
- // cross-module resolution targets only never walked as local ref sources here.
53
- const isForeign = (r) => r.metadata?.forwardedExport === true;
52
+ // A dependency's code a forwarded export, or what extraction pulled out of one — is
53
+ // never walked as a local ref source here and never a local name; only an EXPORT is a
54
+ // cross-module resolution target.
55
+ const isForeign = isForwardedDeclaration;
54
56
  // Local resources resolve a bare / `Self.`-qualified name; forwarded foreign exports
55
57
  // resolve an `Alias.`-qualified name keyed by (module, name).
56
58
  const byName = new Map();
@@ -60,14 +62,15 @@ defs) {
60
62
  continue;
61
63
  const name = r.metadata.name;
62
64
  if (isForeign(r)) {
63
- byModuleName.set(`${moduleOf(r)}\0${name}`, r);
65
+ if (isForwardedExport(r))
66
+ byModuleName.set(`${moduleOf(r)}\0${name}`, r);
64
67
  }
65
68
  else {
66
69
  byName.set(name, r);
67
70
  }
68
71
  }
69
72
  for (const r of crossModuleTargets) {
70
- if (!r.metadata?.name || SYSTEM_KINDS.has(r.kind) || !isForeign(r))
73
+ if (!r.metadata?.name || SYSTEM_KINDS.has(r.kind) || !isForwardedExport(r))
71
74
  continue;
72
75
  byModuleName.set(`${moduleOf(r)}\0${r.metadata.name}`, r);
73
76
  }
@@ -1,6 +1,7 @@
1
1
  import type { ResourceDefinition, ResourceManifest } from "@telorun/sdk";
2
2
  import { type AliasResolver } from "./alias-resolver.js";
3
3
  import type { DefinitionRegistry } from "./definition-registry.js";
4
+ import { type RefSlot, type RefUse } from "./ref-slot.js";
4
5
  export interface ThrowsCodeMeta {
5
6
  data?: Record<string, any>;
6
7
  }
@@ -56,11 +57,31 @@ export interface ResolveCtx {
56
57
  }
57
58
  export declare function createResolveCtx(allManifests: ResourceManifest[], defs: DefinitionRegistry, aliases: AliasResolver, aliasesByModule?: Map<string, AliasResolver>, rootModules?: Set<string>, moduleManifests?: Map<string, ResourceManifest[]>): ResolveCtx;
58
59
  /** Resolve the effective throw union for a named manifest. The result combines
59
- * explicit `throws.codes`, `throws.inherit: true` dataflow (step-context
60
- * traversal with try/catch subtraction), and unbounded markers for
61
- * unresolvable passthrough call sites. Cycles short-circuit to an empty
62
- * result so resolution always terminates. */
60
+ * explicit `throws.codes`, `throws.inherit: true` dataflow (step bodies with
61
+ * try/catch subtraction, plus reference slots that hand a failure back), and
62
+ * unbounded markers for unresolvable passthrough call sites. Cycles
63
+ * short-circuit to an empty result so resolution always terminates. */
63
64
  export declare function resolveThrowsUnion(manifest: ResourceManifest, ctx: ResolveCtx): ThrowsUnion;
65
+ /**
66
+ * True for a use through which a target's failure reaches the declaring
67
+ * resource's CALLER: `call` returns into my invocation, and `trigger.consumer`
68
+ * rejects the value my caller drains. `detached` and `trigger.inbound` run where
69
+ * no caller of mine awaits them; `dependency` and `schema` dispatch nothing.
70
+ *
71
+ * The reduction `inherit` is read through — by the resolver and by the check
72
+ * that a definition declaring it has something to inherit from.
73
+ */
74
+ export declare function handsFailureBack(use: RefUse): boolean;
75
+ /**
76
+ * The uses a throws consumer reads off a slot. A slot that declares no use —
77
+ * the legacy bare-string form — reads as `call`: the throws union must assume
78
+ * `call` to keep an error path, the direction the call graph takes for the same
79
+ * slot. The zone projection reads it the opposite way, deliberately.
80
+ *
81
+ * `uses` defaults to every use the slot can take; a consumer that resolved the
82
+ * slot's case map for one instance passes that answer instead.
83
+ */
84
+ export declare function throwsUses(slot: RefSlot, uses?: readonly RefUse[]): readonly RefUse[];
64
85
  /**
65
86
  * The union a SCOPE-LEVEL `catches:` list can be asked to render — everything
66
87
  * the resource it is written on drives, transitively.
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-throws-union.d.ts","sourceRoot":"","sources":["../src/resolve-throws-union.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEzE,OAAO,EAA0B,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGjF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAKnE,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;AAiCD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,gBAAgB,EAC1B,UAAU,EAAE,kBAAkB,EAC9B,GAAG,EAAE,UAAU,EACf,IAAI,GAAE,GAAG,CAAC,gBAAgB,CAAa,GACtC,WAAW,CAmCb;AAkMD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,OAAO,EACjB,GAAG,EAAE,UAAU,EACf,WAAW,EAAE,MAAM,GAAG,SAAS,GAC9B,gBAAgB,GAAG,SAAS,CAsB9B"}
1
+ {"version":3,"file":"resolve-throws-union.d.ts","sourceRoot":"","sources":["../src/resolve-throws-union.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEzE,OAAO,EAA0B,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGjF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAIL,KAAK,OAAO,EACZ,KAAK,MAAM,EACZ,MAAM,eAAe,CAAC;AAIvB,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;;;;wEAIwE;AACxE,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,gBAAgB,EAC1B,GAAG,EAAE,UAAU,GACd,WAAW,CAiDb;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAErD;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,OAAO,EACb,IAAI,GAAE,SAAS,MAAM,EAAuB,GAC3C,SAAS,MAAM,EAAE,CAEnB;AAuCD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,gBAAgB,EAC1B,UAAU,EAAE,kBAAkB,EAC9B,GAAG,EAAE,UAAU,EACf,IAAI,GAAE,GAAG,CAAC,gBAAgB,CAAa,GACtC,WAAW,CAkCb;AAiND;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,OAAO,EACjB,GAAG,EAAE,UAAU,EACf,WAAW,EAAE,MAAM,GAAG,SAAS,GAC9B,gBAAgB,GAAG,SAAS,CAsB9B"}
@@ -1,9 +1,8 @@
1
1
  import { isTaggedSentinel } from "@telorun/templating";
2
2
  import { scopeResolverForModule } from "./alias-resolver.js";
3
- import { resolveScopedName } from "./call-graph.js";
3
+ import { resolveScopedName, resolveSlotUseAt } from "./call-graph.js";
4
4
  import { refSentinelTarget } from "./ref-sentinel-target.js";
5
- import { possibleUses, transfersControl } from "./ref-slot.js";
6
- import { readStepSlot } from "./step-slot.js";
5
+ import { hasDeclaredUse, possibleUses, transfersControl, } from "./ref-slot.js";
7
6
  import { forEachDrivenSlot } from "./schema-walk.js";
8
7
  /** Code a non-`InvokeError` failure surfaces as inside a `catch` block. Mirrors
9
8
  * `PLAIN_ERROR_CODE` in `@telorun/run`'s `toSequenceError`: any invoke can throw
@@ -127,10 +126,10 @@ function codesFromDefinition(definition) {
127
126
  return out;
128
127
  }
129
128
  /** Resolve the effective throw union for a named manifest. The result combines
130
- * explicit `throws.codes`, `throws.inherit: true` dataflow (step-context
131
- * traversal with try/catch subtraction), and unbounded markers for
132
- * unresolvable passthrough call sites. Cycles short-circuit to an empty
133
- * result so resolution always terminates. */
129
+ * explicit `throws.codes`, `throws.inherit: true` dataflow (step bodies with
130
+ * try/catch subtraction, plus reference slots that hand a failure back), and
131
+ * unbounded markers for unresolvable passthrough call sites. Cycles
132
+ * short-circuit to an empty result so resolution always terminates. */
134
133
  export function resolveThrowsUnion(manifest, ctx) {
135
134
  const name = memoKey(manifest);
136
135
  if (name) {
@@ -182,29 +181,52 @@ export function resolveThrowsUnion(manifest, ctx) {
182
181
  }
183
182
  }
184
183
  /**
185
- * `throws.inherit: true` the union a composer's own STEP BODIES reach.
184
+ * True for a use through which a target's failure reaches the declaring
185
+ * resource's CALLER: `call` returns into my invocation, and `trigger.consumer`
186
+ * rejects the value my caller drains. `detached` and `trigger.inbound` run where
187
+ * no caller of mine awaits them; `dependency` and `schema` dispatch nothing.
186
188
  *
187
- * Deliberately steps only, and not every slot the resource drives: `inherit` is
188
- * a DECLARATION that a kind's union is the union of what it dispatches, and a
189
- * kind that does not make that claim must not have it inferred — a kind holding
190
- * a `call` ref it catches internally would silently gain codes it never lets
191
- * escape. What a CATCH SCOPE needs is a different question with a different
192
- * answer, and it has its own resolver below.
189
+ * The reduction `inherit` is read through by the resolver and by the check
190
+ * that a definition declaring it has something to inherit from.
191
+ */
192
+ export function handsFailureBack(use) {
193
+ return use === "call" || use === "trigger.consumer";
194
+ }
195
+ /**
196
+ * The uses a throws consumer reads off a slot. A slot that declares no use —
197
+ * the legacy bare-string form — reads as `call`: the throws union must assume
198
+ * `call` to keep an error path, the direction the call graph takes for the same
199
+ * slot. The zone projection reads it the opposite way, deliberately.
200
+ *
201
+ * `uses` defaults to every use the slot can take; a consumer that resolved the
202
+ * slot's case map for one instance passes that answer instead.
203
+ */
204
+ export function throwsUses(slot, uses = possibleUses(slot)) {
205
+ return hasDeclaredUse(slot) ? uses : ["call"];
206
+ }
207
+ /**
208
+ * `throws.inherit: true` — the union of what the resource dispatches: its step
209
+ * bodies (try/catch subtraction included) and every reference slot whose use,
210
+ * resolved for THIS instance, hands a failure back ({@link handsFailureBack}).
211
+ *
212
+ * Only on a kind that DECLARES `inherit`: it is a claim that the kind lets what
213
+ * it dispatches escape, and a kind catching a slot internally does not make it.
214
+ * What a CATCH SCOPE encloses is a different question, answered below.
193
215
  */
194
216
  function resolveInherited(manifest, definition, ctx, ownerModule) {
195
217
  const result = { codes: new Map(), unbounded: false };
196
- const props = definition.schema?.properties;
197
- if (!props)
198
- return result;
199
- for (const [fieldName, fieldSchema] of Object.entries(props)) {
200
- const stepCtx = readStepSlot(fieldSchema);
201
- if (!stepCtx)
202
- continue;
203
- const steps = manifest[fieldName];
204
- if (!Array.isArray(steps))
205
- continue;
206
- unionInto(result, collectStepArrayThrows(steps, stepCtx.invoke, undefined, ctx, ownerModule));
207
- }
218
+ const schema = definition.schema;
219
+ forEachDrivenSlot(schema, manifest, (driven) => {
220
+ if (driven.kind === "step") {
221
+ unionInto(result, stepSiteThrows(driven.data, driven.slots, ctx, ownerModule));
222
+ return;
223
+ }
224
+ // Several slots at one site are the branches declaring it; any one that
225
+ // hands a failure back counts, since a branch not applying can only add codes.
226
+ const handsBack = driven.slots.some(({ slot, fieldPath }) => throwsUses(slot, resolveSlotUseAt(slot, manifest, schema, driven.path, fieldPath).use).some(handsFailureBack));
227
+ if (handsBack)
228
+ unionInto(result, resolveRefTargetThrows(driven.data, ctx, ownerModule));
229
+ });
208
230
  return result;
209
231
  }
210
232
  /**
@@ -233,10 +255,13 @@ export function resolveScopeUnion(manifest, definition, ctx, seen = new Set()) {
233
255
  const ownerModule = manifest.metadata?.module;
234
256
  forEachDrivenSlot(definition.schema, manifest, (driven) => {
235
257
  if (driven.kind === "step") {
236
- unionInto(result, collectStepArrayThrows(driven.data, driven.slot.invoke, undefined, ctx, ownerModule));
258
+ unionInto(result, stepSiteThrows(driven.data, driven.slots, ctx, ownerModule));
237
259
  return;
238
260
  }
239
- if (driven.slot.throwsThrough) {
261
+ if (driven.slots.some(({ slot }) => !slot.throwsThrough && throwsUses(slot).some(transfersControl))) {
262
+ unionInto(result, resolveRefTargetThrows(driven.data, ctx, ownerModule));
263
+ }
264
+ if (driven.slots.some(({ slot }) => slot.throwsThrough)) {
240
265
  const target = resolveRefManifest(driven.data, ctx, ownerModule);
241
266
  const targetDef = target
242
267
  ? definitionFor(target.kind, ctx.defs, ctx.aliases, scopeResolverFor(ctx, target.metadata?.module))
@@ -247,14 +272,19 @@ export function resolveScopeUnion(manifest, definition, ctx, seen = new Set()) {
247
272
  // the scope's union is no longer enumerable.
248
273
  else
249
274
  result.unbounded = true;
250
- return;
251
275
  }
252
- if (!possibleUses(driven.slot).some(transfersControl))
253
- return;
254
- unionInto(result, resolveRefTargetThrows(driven.data, ctx, ownerModule));
255
276
  });
256
277
  return result;
257
278
  }
279
+ /** The union a step-body site reaches — once per distinct invoke field, since
280
+ * several branches may declare a body at one site. */
281
+ function stepSiteThrows(steps, slots, ctx, ownerModule) {
282
+ const result = emptyUnion();
283
+ for (const invoke of new Set(slots.map((slot) => slot.invoke))) {
284
+ unionInto(result, collectStepArrayThrows(steps, invoke, undefined, ctx, ownerModule));
285
+ }
286
+ return result;
287
+ }
258
288
  function collectStepArrayThrows(steps, invokeField, enclosingTryCodes, ctx, ownerModule) {
259
289
  const result = emptyUnion();
260
290
  for (const step of steps) {
@@ -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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"}
@@ -4,6 +4,7 @@ import { enclosingOf, propertySchemas, resolveLocalRef, } from "./manifest-navig
4
4
  import { readProvidesZone, readRequiresZone } from "./zone-slot.js";
5
5
  import { DiagnosticSeverity } from "./types.js";
6
6
  import { moduleAliasScope } from "./module-alias-scope.js";
7
+ import { isForwardedDeclaration } from "./forwarded-declaration.js";
7
8
  const SOURCE = "telo-analyzer";
8
9
  /** Resolve a possibly alias-form kind to its definition in the DECLARING
9
10
  * module's scope — the same layering `AnalysisRegistry.resolveDefinitionIn`
@@ -379,7 +380,7 @@ export function projectZoneRequirements(args) {
379
380
  // (with the internal graph in hand) and seeded below — deriving them here
380
381
  // against the flattened view would resolve correlation against a graph
381
382
  // that no longer holds the library's internals.
382
- if (meta?.forwardedExport)
383
+ if (isForwardedDeclaration(node.manifest))
383
384
  continue;
384
385
  const def = resolveDef(node.kind, meta?.module);
385
386
  const schema = def?.schema;
@@ -5,6 +5,11 @@ import type { AnalysisDiagnostic } from "./types.js";
5
5
  * `data.resource`, which has no YAML source. Rewrite each such diagnostic
6
6
  * back to the chain root: walk up `metadata.xTeloOrigin` until a manifest
7
7
  * with no origin is reached, and prepend each hop's `pathFromParent` to
8
- * `data.path` so position-index lookups against the root doc resolve. */
8
+ * `data.path` so position-index lookups against the root doc resolve.
9
+ *
10
+ * An extraction from a scope member lives INSIDE the scope array rather than at
11
+ * the top level, so a diagnostic about it names the top-level owner and a path
12
+ * through an array index the author never wrote (`with[3]`). That prefix is
13
+ * unfolded the same way, into the position the declaration was written at. */
9
14
  export declare function rewriteSyntheticOrigins(diagnostics: AnalysisDiagnostic[], manifests: ResourceManifest[]): AnalysisDiagnostic[];
10
15
  //# sourceMappingURL=rewrite-synthetic-origins.d.ts.map