@telorun/analyzer 0.72.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 (208) hide show
  1. package/dist/analyzer.d.ts.map +1 -1
  2. package/dist/analyzer.js +76 -20
  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 +144 -113
  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/cel-scope-query.d.ts.map +1 -1
  19. package/dist/cel-scope-query.js +32 -11
  20. package/dist/cel-scope.d.ts.map +1 -1
  21. package/dist/cel-scope.js +1 -0
  22. package/dist/eval-paths.d.ts +36 -5
  23. package/dist/eval-paths.d.ts.map +1 -1
  24. package/dist/eval-paths.js +47 -6
  25. package/dist/extends-resolution.d.ts +12 -0
  26. package/dist/extends-resolution.d.ts.map +1 -1
  27. package/dist/extends-resolution.js +23 -0
  28. package/dist/forwarded-declaration.d.ts +26 -0
  29. package/dist/forwarded-declaration.d.ts.map +1 -0
  30. package/dist/forwarded-declaration.js +31 -0
  31. package/dist/index.d.ts +10 -4
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +5 -2
  34. package/dist/kernel-globals.d.ts.map +1 -1
  35. package/dist/kernel-globals.js +21 -5
  36. package/dist/module-alias-scope.d.ts +11 -0
  37. package/dist/module-alias-scope.d.ts.map +1 -1
  38. package/dist/module-alias-scope.js +10 -0
  39. package/dist/module-file-claims.d.ts +17 -1
  40. package/dist/module-file-claims.d.ts.map +1 -1
  41. package/dist/module-file-claims.js +38 -3
  42. package/dist/module-named-files.d.ts +72 -0
  43. package/dist/module-named-files.d.ts.map +1 -0
  44. package/dist/module-named-files.js +115 -0
  45. package/dist/native-entries.d.ts +83 -0
  46. package/dist/native-entries.d.ts.map +1 -0
  47. package/dist/native-entries.js +169 -0
  48. package/dist/nearest-name.d.ts +22 -0
  49. package/dist/nearest-name.d.ts.map +1 -0
  50. package/dist/nearest-name.js +43 -0
  51. package/dist/normalize-inline-resources.d.ts +41 -13
  52. package/dist/normalize-inline-resources.d.ts.map +1 -1
  53. package/dist/normalize-inline-resources.js +236 -54
  54. package/dist/reference-field-map.d.ts +59 -1
  55. package/dist/reference-field-map.d.ts.map +1 -1
  56. package/dist/reference-field-map.js +200 -34
  57. package/dist/release/destinations.d.ts +59 -0
  58. package/dist/release/destinations.d.ts.map +1 -0
  59. package/dist/release/destinations.js +75 -0
  60. package/dist/release/index.d.ts +6 -2
  61. package/dist/release/index.d.ts.map +1 -1
  62. package/dist/release/index.js +3 -1
  63. package/dist/release/ledger.d.ts +20 -11
  64. package/dist/release/ledger.d.ts.map +1 -1
  65. package/dist/release/ledger.js +43 -14
  66. package/dist/release/payload-digest.d.ts +2 -1
  67. package/dist/release/payload-digest.d.ts.map +1 -1
  68. package/dist/release/payload-digest.js +2 -1
  69. package/dist/release/release-plan.d.ts +3 -2
  70. package/dist/release/release-plan.d.ts.map +1 -1
  71. package/dist/release/release-plan.js +12 -19
  72. package/dist/release/workspace-config.d.ts +114 -34
  73. package/dist/release/workspace-config.d.ts.map +1 -1
  74. package/dist/release/workspace-config.js +322 -38
  75. package/dist/release/workspace-schema.d.ts +41 -0
  76. package/dist/release/workspace-schema.d.ts.map +1 -0
  77. package/dist/release/workspace-schema.js +77 -0
  78. package/dist/resolve-ref-sentinels.d.ts.map +1 -1
  79. package/dist/resolve-ref-sentinels.js +8 -5
  80. package/dist/resolve-throws-union.d.ts +25 -4
  81. package/dist/resolve-throws-union.d.ts.map +1 -1
  82. package/dist/resolve-throws-union.js +62 -32
  83. package/dist/resolve-zone-requirements.d.ts.map +1 -1
  84. package/dist/resolve-zone-requirements.js +2 -1
  85. package/dist/rewrite-synthetic-origins.d.ts +6 -1
  86. package/dist/rewrite-synthetic-origins.d.ts.map +1 -1
  87. package/dist/rewrite-synthetic-origins.js +107 -13
  88. package/dist/schema-compat.d.ts.map +1 -1
  89. package/dist/schema-compat.js +18 -5
  90. package/dist/schema-error-report.d.ts +7 -0
  91. package/dist/schema-error-report.d.ts.map +1 -1
  92. package/dist/schema-error-report.js +9 -4
  93. package/dist/schema-walk.d.ts +47 -13
  94. package/dist/schema-walk.d.ts.map +1 -1
  95. package/dist/schema-walk.js +150 -30
  96. package/dist/scope-declarations.d.ts +59 -0
  97. package/dist/scope-declarations.d.ts.map +1 -0
  98. package/dist/scope-declarations.js +45 -0
  99. package/dist/source-entries.d.ts +119 -0
  100. package/dist/source-entries.d.ts.map +1 -0
  101. package/dist/source-entries.js +349 -0
  102. package/dist/step-bodies.d.ts +24 -0
  103. package/dist/step-bodies.d.ts.map +1 -0
  104. package/dist/step-bodies.js +28 -0
  105. package/dist/telo-version.d.ts +1 -1
  106. package/dist/telo-version.js +1 -1
  107. package/dist/template-body.d.ts +10 -0
  108. package/dist/template-body.d.ts.map +1 -1
  109. package/dist/template-body.js +25 -0
  110. package/dist/validate-cel-context.d.ts +23 -8
  111. package/dist/validate-cel-context.d.ts.map +1 -1
  112. package/dist/validate-cel-context.js +51 -18
  113. package/dist/validate-exports.d.ts +28 -0
  114. package/dist/validate-exports.d.ts.map +1 -0
  115. package/dist/validate-exports.js +146 -0
  116. package/dist/validate-extends.d.ts.map +1 -1
  117. package/dist/validate-extends.js +37 -1
  118. package/dist/validate-module-artifact.d.ts +4 -2
  119. package/dist/validate-module-artifact.d.ts.map +1 -1
  120. package/dist/validate-module-artifact.js +43 -4
  121. package/dist/validate-native-entries.d.ts +15 -0
  122. package/dist/validate-native-entries.d.ts.map +1 -0
  123. package/dist/validate-native-entries.js +103 -0
  124. package/dist/validate-observed-state.d.ts +7 -1
  125. package/dist/validate-observed-state.d.ts.map +1 -1
  126. package/dist/validate-observed-state.js +24 -6
  127. package/dist/validate-provider-coherence.d.ts +4 -8
  128. package/dist/validate-provider-coherence.d.ts.map +1 -1
  129. package/dist/validate-provider-coherence.js +12 -123
  130. package/dist/validate-reference-forms.d.ts.map +1 -1
  131. package/dist/validate-reference-forms.js +2 -2
  132. package/dist/validate-references.d.ts.map +1 -1
  133. package/dist/validate-references.js +152 -65
  134. package/dist/validate-scope-reach.d.ts +31 -0
  135. package/dist/validate-scope-reach.d.ts.map +1 -0
  136. package/dist/validate-scope-reach.js +180 -0
  137. package/dist/validate-source-entries.d.ts +16 -0
  138. package/dist/validate-source-entries.d.ts.map +1 -0
  139. package/dist/validate-source-entries.js +90 -0
  140. package/dist/validate-template-body.d.ts +36 -0
  141. package/dist/validate-template-body.d.ts.map +1 -0
  142. package/dist/validate-template-body.js +246 -0
  143. package/dist/validate-throws-coverage.d.ts.map +1 -1
  144. package/dist/validate-throws-coverage.js +21 -39
  145. package/dist/value-type-keyword.d.ts +22 -5
  146. package/dist/value-type-keyword.d.ts.map +1 -1
  147. package/dist/value-type-keyword.js +16 -7
  148. package/package.json +4 -3
  149. package/src/analyzer.ts +97 -20
  150. package/src/artifact-axes.ts +24 -0
  151. package/src/artifact-layer-index.ts +9 -6
  152. package/src/artifact-selector.ts +110 -35
  153. package/src/builtins.ts +160 -113
  154. package/src/call-graph.ts +30 -0
  155. package/src/catch-scope.ts +1 -1
  156. package/src/cel-scope-query.ts +28 -9
  157. package/src/cel-scope.ts +1 -0
  158. package/src/eval-paths.ts +53 -6
  159. package/src/extends-resolution.ts +24 -0
  160. package/src/forwarded-declaration.ts +32 -0
  161. package/src/index.ts +37 -1
  162. package/src/kernel-globals.ts +28 -5
  163. package/src/migrations/CLAUDE.md +35 -0
  164. package/src/module-alias-scope.ts +17 -0
  165. package/src/module-file-claims.ts +63 -4
  166. package/src/module-named-files.ts +162 -0
  167. package/src/native-entries.ts +227 -0
  168. package/src/nearest-name.ts +47 -0
  169. package/src/normalize-inline-resources.ts +326 -70
  170. package/src/reference-field-map.ts +257 -52
  171. package/src/release/CLAUDE.md +32 -0
  172. package/src/release/destinations.ts +105 -0
  173. package/src/release/index.ts +33 -2
  174. package/src/release/ledger.ts +51 -21
  175. package/src/release/payload-digest.ts +2 -1
  176. package/src/release/release-plan.ts +16 -26
  177. package/src/release/workspace-config.ts +483 -47
  178. package/src/release/workspace-schema.ts +99 -0
  179. package/src/resolve-ref-sentinels.ts +7 -6
  180. package/src/resolve-throws-union.ts +87 -32
  181. package/src/resolve-zone-requirements.ts +2 -1
  182. package/src/rewrite-synthetic-origins.ts +107 -16
  183. package/src/schema-compat.ts +18 -4
  184. package/src/schema-error-report.ts +16 -4
  185. package/src/schema-walk.ts +162 -34
  186. package/src/scope-declarations.ts +98 -0
  187. package/src/source-entries.ts +502 -0
  188. package/src/step-bodies.ts +55 -0
  189. package/src/telo-version.ts +1 -1
  190. package/src/template-body.ts +25 -0
  191. package/src/validate-cel-context.ts +60 -18
  192. package/src/validate-exports.ts +185 -0
  193. package/src/validate-extends.ts +43 -0
  194. package/src/validate-module-artifact.ts +46 -3
  195. package/src/validate-native-entries.ts +147 -0
  196. package/src/validate-observed-state.ts +36 -7
  197. package/src/validate-provider-coherence.ts +17 -127
  198. package/src/validate-reference-forms.ts +2 -3
  199. package/src/validate-references.ts +151 -66
  200. package/src/validate-scope-reach.ts +213 -0
  201. package/src/validate-source-entries.ts +120 -0
  202. package/src/validate-template-body.ts +274 -0
  203. package/src/validate-throws-coverage.ts +24 -31
  204. package/src/value-type-keyword.ts +35 -9
  205. package/dist/validate-template-dispatch.d.ts +0 -27
  206. package/dist/validate-template-dispatch.d.ts.map +0 -1
  207. package/dist/validate-template-dispatch.js +0 -95
  208. package/src/validate-template-dispatch.ts +0 -99
@@ -1,4 +1,13 @@
1
- import { isRefEntry, isScopeEntry, isInlineResource } from "./reference-field-map.js";
1
+ import { inlineStepTargetName } from "@telorun/sdk";
2
+ import { isTaggedSentinel } from "@telorun/templating";
3
+ import { controllerBearingAncestor, hasOwnControllerOrTemplate, } from "./extends-resolution.js";
4
+ import { isForwardedDeclaration } from "./forwarded-declaration.js";
5
+ import { definitionInScope } from "./module-alias-scope.js";
6
+ import { isInlineResource, isRefEntry } from "./reference-field-map.js";
7
+ import { gatherPropertySchemas } from "./schema-walk.js";
8
+ import { declaredScopes, outsideScopesOf, scopeEncloses, scopeMembers, } from "./scope-declarations.js";
9
+ import { forEachStep, stepBodiesOf } from "./step-bodies.js";
10
+ import { readStepSlot } from "./step-slot.js";
2
11
  const SYSTEM_KINDS = new Set([
3
12
  "Telo.Definition",
4
13
  "Telo.Application",
@@ -44,95 +53,266 @@ function cloneForMutation(value) {
44
53
  /**
45
54
  * Phase 2 — Inline resource normalization.
46
55
  *
47
- * After all manifests and definitions are loaded, walks every non-system resource's
48
- * x-telo-ref slots. For each inline resource value (has keys beyond kind/name/metadata),
49
- * assigns a deterministic name, extracts it as a first-class manifest, and replaces
50
- * the inline value in-place with `{kind, name}`. Newly extracted resources are enqueued
51
- * so nested inlines are resolved in the same pass.
56
+ * Every inline declaration (a `{kind, …config}` with no `name`) is extracted as a
57
+ * first-class manifest under a deterministic name and replaced in place with
58
+ * `{kind, name}`. Two kinds of slot carry one:
52
59
  *
53
- * Naming scheme:
54
- * {parentName}_{pathSegment}[_{itemName|index}]_{fieldName}
55
- * e.g. TestBasicAddition_steps_AddTwoNumbers_invoke
56
- * TestBasicAddition_steps_0_invoke (when step has no name)
60
+ * - a REFERENCE slot, found through the kind's field map, named
61
+ * `{parentName}_{pathSegment}[_{itemName|index}]_{fieldName}`
62
+ * (`TestBasicAddition_steps_AddTwoNumbers_invoke`);
63
+ * - a STEP's dispatch target, at any nesting depth of a step body, named by
64
+ * `inlineStepTargetName` — the name the step engine has always registered it
65
+ * under, which is durable identity and so must not move with the extraction.
66
+ *
67
+ * Step slots are found through the kind's step-body annotation and walked with
68
+ * `walkStepArray`, never through the field map: that map is the kernel's Phase-5
69
+ * injection surface, and a step's target resolves at dispatch.
70
+ *
71
+ * Every extracted manifest is queued in turn, so an inline declaration nested in
72
+ * another's slots — a handler inside an inline step target — is extracted too.
73
+ * So is every member of an `x-telo-scope` array, which is a declaration of its
74
+ * own.
75
+ *
76
+ * WHERE an extraction is created:
77
+ *
78
+ * - a reference slot lying in a region of a scope its owner declares (a
79
+ * sequence's `targets:`) resolves against that scope, so its declaration
80
+ * joins the scope's array and is created per scope run;
81
+ * - a step target is created where its owner is — the module's top level, or
82
+ * the scope array holding a scope member — and never in a scope the owner
83
+ * declares, because that would make every step target of a sequence with a
84
+ * `with:` block a scoped resource and move its durable identity;
85
+ * - any other extraction is created where its owner is.
86
+ *
87
+ * A declaration written inside a scope's region and created outside it records
88
+ * the scope (`xTeloOrigin.outsideScopes`), and `validateScopedNameReach` reports
89
+ * a reference from it to a name that scope declares.
90
+ *
91
+ * An extraction out of a dependency's forwarded manifest is that dependency's
92
+ * code: it is stamped `forwardedInternal` (see `isForwardedDeclaration`) and
93
+ * carries the declaring module's `moduleGlobals`, as its parent does.
57
94
  *
58
95
  * Returns a new array of deep-cloned manifests (the rewrites land on the clones)
59
- * plus all extracted manifests. The caller's manifests — array and elements — are
60
- * never mutated; this is the analyzer's immutability boundary.
96
+ * plus every top-level extraction. The caller's manifests — array and elements —
97
+ * are never mutated; this is the analyzer's immutability boundary.
61
98
  */
62
99
  export function normalizeInlineResources(resources, registry, aliases, aliasesByModule) {
63
100
  // Deep-clone the input so this pass — and `resolveRefSentinels`, which runs on
64
- // this output — never mutate caller-owned manifests. `extractInlinesAtPath`
65
- // rewrites inline ref slots in place, so without cloning we'd corrupt shared
66
- // state such as the editor's `LoadedFile.manifests` parse cache (a reused
67
- // sentinel would be rewritten to `{kind, name}`, later misread as an authored
68
- // reference form). The clone is the analyzer's immutability boundary.
101
+ // this output — never mutate caller-owned manifests. The extractions rewrite
102
+ // slots in place, so without cloning we'd corrupt shared state such as the
103
+ // editor's `LoadedFile.manifests` parse cache (a reused sentinel would be
104
+ // rewritten to `{kind, name}`, later misread as an authored reference form).
69
105
  const result = resources.map(cloneForMutation);
70
- // Queue: all non-system resources with a name. Extracted resources are appended.
71
- // Filter the CLONES (not the originals) so traversal mutates copies.
72
106
  // System kinds join the queue too: their inline-accepting slots are filtered
73
107
  // per entry below, so a system document is walked but only its opted-in slots
74
108
  // are extracted from.
75
- const queue = result.filter((r) => typeof r.metadata?.name === "string" && !!r.kind);
76
- let i = 0;
77
- while (i < queue.length) {
78
- const resource = queue[i++];
109
+ const queue = result
110
+ .filter((r) => typeof r.metadata?.name === "string" && !!r.kind)
111
+ .map((manifest) => ({
112
+ manifest,
113
+ home: undefined,
114
+ outside: outsideScopesOf(manifest),
115
+ ...provenanceOf(manifest, undefined),
116
+ }));
117
+ const place = (manifest, into, module) => {
118
+ if (into)
119
+ into.push(manifest);
120
+ else
121
+ result.push(manifest);
122
+ queue.push({
123
+ manifest: manifest,
124
+ home: into,
125
+ outside: outsideScopesOf(manifest),
126
+ ...provenanceOf(manifest, module),
127
+ });
128
+ };
129
+ for (let i = 0; i < queue.length; i++) {
130
+ const current = queue[i];
131
+ const { manifest: resource, home, outside } = current;
132
+ // The registry reads a kind's alias table off `metadata.module`; a scope
133
+ // member is looked up through a view carrying its owner's.
134
+ const view = current.module !== undefined && moduleOf(resource) === undefined
135
+ ? { ...resource, metadata: { ...resource.metadata, module: current.module } }
136
+ : resource;
79
137
  // When aliasesByModule is available, use the expanded map so inline refs
80
138
  // hidden behind an x-telo-schema-from indirection (e.g. an encoder inside
81
139
  // an HttpDispatch.Outcomes/$defs/Returns sub-schema) reach extraction.
82
140
  const fieldMap = aliases && aliasesByModule
83
- ? registry.expandedFieldMapForResource(resource, aliases, aliasesByModule)
141
+ ? registry.expandedFieldMapForResource(view, aliases, aliasesByModule)
84
142
  : registry.getFieldMapForKind(resource.kind, aliases);
85
143
  if (!fieldMap)
86
144
  continue;
87
145
  const parentName = resource.metadata.name;
88
- const parentModule = resource.metadata.module;
89
- // Collect scope visibility prefixes so we can route extracted resources correctly.
90
- const scopePrefixes = [];
91
- for (const [, entry] of fieldMap) {
92
- if (!isScopeEntry(entry))
93
- continue;
94
- const paths = Array.isArray(entry.scope) ? entry.scope : [entry.scope];
95
- for (const p of paths) {
96
- scopePrefixes.push(p.replace(/^\//, "").replace(/\//g, "."));
146
+ const parentModule = moduleOf(view);
147
+ const inherit = {
148
+ module: parentModule,
149
+ forwarded: current.forwarded,
150
+ moduleGlobals: current.moduleGlobals,
151
+ };
152
+ const scopes = declaredScopes(resource, fieldMap);
153
+ // Queued BEFORE anything is extracted into these arrays: an extraction
154
+ // queues itself, and must not be walked twice. A member is created inside
155
+ // this resource's scope, which is itself created where this resource is.
156
+ for (const scope of scopes) {
157
+ for (const member of scopeMembers(scope)) {
158
+ queue.push({ manifest: member, home: scope.declarations, outside, ...inherit });
97
159
  }
98
160
  }
161
+ const outsideAt = (slotPath, createdIn) => [
162
+ ...outside,
163
+ ...scopes
164
+ .filter((scope) => scope !== createdIn && scopeEncloses(scope, slotPath))
165
+ .map((scope) => ({
166
+ ownerKind: resource.kind,
167
+ ownerName: parentName,
168
+ field: scope.path,
169
+ names: scopeMembers(scope).map((member) => member.metadata.name),
170
+ }))
171
+ .filter((scope) => scope.names.length > 0),
172
+ ];
99
173
  for (const [fieldPath, entry] of fieldMap) {
100
174
  if (!isRefEntry(entry))
101
175
  continue;
102
176
  if (!acceptsInline(resource.kind, entry))
103
177
  continue;
104
- const inScope = scopePrefixes.some((prefix) => fieldPath === prefix ||
105
- fieldPath.startsWith(prefix + ".") ||
106
- fieldPath.startsWith(prefix + "["));
107
- const invocationContext = isRefEntry(entry) ? entry.context : undefined;
108
- const extracted = extractInlinesAtPath(resource, fieldPath, parentName, resource.kind, parentModule, invocationContext);
109
- for (const manifest of extracted) {
110
- result.push(manifest);
111
- queue.push(manifest);
112
- // TODO Phase 5: when inScope, add to parent's scope array instead of outer set
113
- void inScope;
178
+ const scope = scopes.find((s) => scopeEncloses(s, fieldPath));
179
+ for (const manifest of extractInlinesAtPath(resource, fieldPath, parentName, resource.kind, inherit, outsideAt(fieldPath, scope), entry.context)) {
180
+ place(manifest, scope?.declarations ?? home, parentModule);
114
181
  }
115
182
  }
183
+ if (SYSTEM_KINDS.has(resource.kind))
184
+ continue;
185
+ extractStepTargets(resource, view, registry, aliases, aliasesByModule, inherit, outsideAt, (m) => place(m, home, parentModule));
116
186
  }
117
187
  return result;
118
188
  }
189
+ const moduleOf = (manifest) => {
190
+ const module = manifest.metadata?.module;
191
+ return typeof module === "string" ? module : undefined;
192
+ };
193
+ function provenanceOf(manifest, module) {
194
+ return {
195
+ module: moduleOf(manifest) ?? module,
196
+ forwarded: isForwardedDeclaration(manifest),
197
+ moduleGlobals: manifest.metadata?.moduleGlobals,
198
+ };
199
+ }
200
+ /**
201
+ * Extract every inline dispatch target of every step in `resource`'s step
202
+ * bodies, at any nesting depth, into a named manifest.
203
+ *
204
+ * The name is the step engine's, so it names what the RUNTIME owner passes it:
205
+ *
206
+ * - the owner kind is the kind whose CONTROLLER runs the body — the kind
207
+ * itself, or for an `extends` child that inherits its controller, the
208
+ * ancestor that supplies it;
209
+ * - the path's first segment is the field the controller reads its body from.
210
+ * For a `base:`-form child that is the PARENT's field the body is mapped onto,
211
+ * which is taken from a pure `self.<field>` mapping; a body `base:` reshapes any
212
+ * other way is left inline, for the runtime to name exactly as it always has;
213
+ * - an inline declaration stating its own `metadata.name` keeps it, as
214
+ * `ensureKindRef` always has.
215
+ */
216
+ function extractStepTargets(resource, view, registry, aliases, aliasesByModule, inherit, outsideAt, emit) {
217
+ const definition = definitionInScope(registry, view.kind, view.metadata, aliases, aliasesByModule);
218
+ if (!definition)
219
+ return;
220
+ const schema = registry.effectiveSchemaOf(definition);
221
+ if (!schema)
222
+ return;
223
+ const resolveDef = (kind, from) => definitionInScope(registry, kind, from?.metadata, aliases, aliasesByModule);
224
+ const runner = hasOwnControllerOrTemplate(definition)
225
+ ? definition
226
+ : (controllerBearingAncestor(definition, resolveDef) ?? definition);
227
+ const owner = { kind: runner.metadata.name, resourceName: resource.metadata.name };
228
+ const base = runner !== definition ? definition.base : undefined;
229
+ for (const body of stepBodiesOf(resource, schema)) {
230
+ const root = base === undefined ? body.field : mappedStepField(base, body.field, runner, registry);
231
+ if (root === undefined)
232
+ continue;
233
+ const outsideScopes = outsideAt(body.field);
234
+ forEachStep(body, schema, (step, stepPath) => {
235
+ const target = step[body.invokeField];
236
+ if (!target || typeof target !== "object" || Array.isArray(target))
237
+ return;
238
+ if (!isInlineResource(target))
239
+ return;
240
+ // The step grammar requires a name, and a target is named after it; a step
241
+ // without one is reported by schema validation and left as written.
242
+ if (typeof step.name !== "string")
243
+ return;
244
+ const inline = target;
245
+ const declared = inline.metadata?.name;
246
+ const name = typeof declared === "string"
247
+ ? declared
248
+ : inlineStepTargetName(owner, [root, ...stepPathSegments(stepPath).slice(1)], step.name);
249
+ step[body.invokeField] = { kind: inline.kind, name };
250
+ emit(buildManifest(inline, name, {
251
+ parentKind: resource.kind,
252
+ parentName: resource.metadata.name,
253
+ pathFromParent: `${stepPath}.${body.invokeField}`,
254
+ stepTarget: true,
255
+ ...(outsideScopes.length > 0 ? { outsideScopes } : {}),
256
+ }, inherit));
257
+ });
258
+ }
259
+ }
260
+ /** The runner's step field a `base:` mapping forwards `field` into, when it does
261
+ * so verbatim (`steps: !cel "self.<field>"`); undefined otherwise. */
262
+ function mappedStepField(base, field, runner, registry) {
263
+ if (!base || typeof base !== "object" || Array.isArray(base))
264
+ return undefined;
265
+ const runnerSchema = registry.effectiveSchemaOf(runner);
266
+ if (!runnerSchema)
267
+ return undefined;
268
+ const runnerSteps = new Set(gatherPropertySchemas(runnerSchema)
269
+ .filter(([, schema]) => readStepSlot(schema) !== undefined)
270
+ .map(([key]) => key));
271
+ for (const [target, value] of Object.entries(base)) {
272
+ if (runnerSteps.has(target) && pureSelfField(value) === field)
273
+ return target;
274
+ }
275
+ return undefined;
276
+ }
277
+ /** `f` for a CEL value that is exactly `self.f`, in any spelling it arrives in. */
278
+ function pureSelfField(value) {
279
+ let source;
280
+ if (isTaggedSentinel(value)) {
281
+ if (value.engine === "cel")
282
+ source = value.source;
283
+ }
284
+ else if (value && typeof value === "object" && value.__compiled) {
285
+ const compiled = value.source;
286
+ if (typeof compiled === "string")
287
+ source = compiled;
288
+ }
289
+ else if (typeof value === "string") {
290
+ source = /^\s*\$\{\{([\s\S]*)\}\}\s*$/.exec(value)?.[1];
291
+ }
292
+ return source === undefined ? undefined : /^self\.([A-Za-z_$][\w$]*)$/.exec(source.trim())?.[1];
293
+ }
294
+ /** `steps[1].cases.a[0]` → `["steps", "1", "cases", "a", "0"]`. Exact even for a
295
+ * case key holding punctuation: the name keeps only alphanumeric runs, so
296
+ * splitting inside a key cannot change it. */
297
+ function stepPathSegments(path) {
298
+ return path.split(/[.[\]]/).filter((segment) => segment.length > 0);
299
+ }
119
300
  /**
120
301
  * Walks `resource` following `fieldPath` (dot notation, `[]` = array traversal).
121
302
  * Mutates the resource in-place: replaces each inline value with `{kind, name}`.
122
303
  * Returns the extracted manifests.
123
- *
124
- * Each extracted manifest carries `metadata.xTeloOrigin` so downstream
125
- * diagnostics can be rerouted back to the parent doc's YAML position:
126
- * - `parentKind` / `parentName` — the resource that owned the inline slot
127
- * - `pathFromParent` — concrete dotted path with `[N]` indices, matching
128
- * `buildPositionIndex` keys (e.g. `routes[0].handler`)
129
304
  */
130
- function extractInlinesAtPath(resource, fieldPath, parentName, parentKind, parentModule, invocationContext) {
305
+ function extractInlinesAtPath(resource, fieldPath, parentName, parentKind, inherit, outsideScopes, invocationContext) {
131
306
  const extracted = [];
132
307
  const parts = fieldPath.split(".");
133
308
  function emit(inline, nameSegments, concretePath) {
134
309
  const name = sanitizeName([parentName, ...nameSegments].join("_"));
135
- extracted.push(buildManifest(inline, name, parentKind, parentName, concretePath, parentModule, invocationContext));
310
+ extracted.push(buildManifest(inline, name, {
311
+ parentKind,
312
+ parentName,
313
+ pathFromParent: concretePath,
314
+ ...(outsideScopes.length > 0 ? { outsideScopes } : {}),
315
+ }, inherit, invocationContext));
136
316
  return name;
137
317
  }
138
318
  function traverse(obj, partsLeft, nameParts, pathSoFar) {
@@ -207,7 +387,7 @@ function extractInlinesAtPath(resource, fieldPath, parentName, parentKind, paren
207
387
  traverse(resource, parts, [], "");
208
388
  return extracted;
209
389
  }
210
- function buildManifest(inline, name, parentKind, parentName, pathFromParent, parentModule, invocationContext) {
390
+ function buildManifest(inline, name, origin, inherit, invocationContext) {
211
391
  const existingMeta = inline.metadata && typeof inline.metadata === "object"
212
392
  ? inline.metadata
213
393
  : {};
@@ -217,9 +397,11 @@ function buildManifest(inline, name, parentKind, parentName, pathFromParent, par
217
397
  ...existingMeta,
218
398
  name,
219
399
  // Inherit parent module only if the inline doesn't already declare one
220
- ...(parentModule && !existingMeta.module ? { module: parentModule } : {}),
400
+ ...(inherit.module && !existingMeta.module ? { module: inherit.module } : {}),
401
+ ...(inherit.forwarded ? { forwardedInternal: true } : {}),
402
+ ...(inherit.moduleGlobals !== undefined ? { moduleGlobals: inherit.moduleGlobals } : {}),
221
403
  ...(invocationContext ? { xTeloInvocationContext: invocationContext } : {}),
222
- xTeloOrigin: { parentKind, parentName, pathFromParent },
404
+ xTeloOrigin: origin,
223
405
  },
224
406
  };
225
407
  }
@@ -1,4 +1,5 @@
1
- import { type RefUse, type RefUseCases } from "./ref-slot.js";
1
+ import { type RefSlot, type RefUse, type RefUseCases } from "./ref-slot.js";
2
+ import { type StepSlot } from "./step-slot.js";
2
3
  export { readRefSlot, isRefSlot, hasDeclaredUse } from "./ref-slot.js";
3
4
  export type { RefSlot, RefUse, RefUseCases } from "./ref-slot.js";
4
5
  /** An entry for a field that carries one or more x-telo-ref constraints. */
@@ -36,6 +37,39 @@ export interface RefFieldEntry {
36
37
  * an unconditional opt-in would rewrite the value into a valid shape before
37
38
  * the schema ever saw it. */
38
39
  inline?: boolean;
40
+ /** See {@link RefSlot.throwsThrough}. */
41
+ throwsThrough?: boolean;
42
+ }
43
+ /** The slot an entry records, as `readRefSlot` read it. */
44
+ export declare function refSlotOfEntry(entry: RefFieldEntry): RefSlot;
45
+ /** Everything a driven-slot map records at one field path. */
46
+ export interface DrivenPath {
47
+ /** Every reference slot declared here, by any branch. Kept apart rather than
48
+ * merged into one slot and read as a union: a branch that does not apply to a
49
+ * resource can only ADD what counts — more coverage demanded, never less — and
50
+ * one merged slot could not hold two case-map selectors or a branch that
51
+ * declares no use. */
52
+ refs: RefFieldEntry[];
53
+ /** Every step body declared here, by any branch. */
54
+ steps: StepSlot[];
55
+ /** Back-edges of a recursive schema: the schema here is also the one entered
56
+ * at each of these paths, so everything below them applies again below this
57
+ * one, as deep as a resource's data goes. Recorded BESIDE `refs`, never in
58
+ * place of them — a `!ref` here resolves as a reference, an inline object
59
+ * recurses. */
60
+ recurse: string[];
61
+ }
62
+ /** See {@link buildDrivenSlotMap}. */
63
+ export interface DrivenSlots {
64
+ paths: Map<string, DrivenPath>;
65
+ /** Per `{}` field path, the keys JSON Schema does NOT apply that
66
+ * `additionalProperties` to: those the same schema declares under
67
+ * `properties`, plus the resource envelope at the root. Where several schemas
68
+ * meet at one `{}` path, only keys every one of them declares are skipped. */
69
+ declaredKeys: Map<string, Set<string>>;
70
+ /** True when some path holds a step or reference slot. A map of back-edges
71
+ * alone drives nothing, so a walk over it is skipped. */
72
+ drives: boolean;
39
73
  }
40
74
  /** An entry for a field that declares an execution scope (x-telo-scope). */
41
75
  export interface ScopeFieldEntry {
@@ -139,4 +173,28 @@ export declare function collectRefs(node: Record<string, any>): string[];
139
173
  * inline normalization and Phase 5 injection see slots that the local field map
140
174
  * hid behind the schema-from indirection. */
141
175
  export declare function buildFieldMapAtPath(schema: Record<string, any>, pathPrefix: string): ReferenceFieldMap;
176
+ /**
177
+ * Every slot through which a resource of this schema DRIVES another — the
178
+ * reference field map's own traversal, plus what a dispatch analysis needs and
179
+ * the injection surface must not have:
180
+ *
181
+ * - local `$ref` is followed, resolved against the root. The injection map
182
+ * stops there so a step's `invoke` never becomes an injection site; this map
183
+ * stops AT a step body instead, which removes that reason. A reference back
184
+ * to a node already on the descent is recorded as a back-edge rather than
185
+ * unrolled, so a recursive shape stays finite here and is followed as deep as
186
+ * the data goes by `forEachDrivenSlot`;
187
+ * - a step body is recorded and not descended — the step traversal owns
188
+ * everything below it;
189
+ * - the root's own variant branches and `additionalProperties` are walked, not
190
+ * only its `properties`;
191
+ * - a path keeps EVERY slot any branch declares there, where the injection map
192
+ * keeps the last one written (see {@link DrivenPath.refs});
193
+ * - each `{}` path records the keys its `additionalProperties` does not cover.
194
+ *
195
+ * Shared by every throws question (a kind's `inherit` union, a scope list's
196
+ * denominator, catch-scope enclosure, and whether `inherit` is legal at all),
197
+ * so none can reach a slot another cannot. Memoized per schema object.
198
+ */
199
+ export declare function buildDrivenSlotMap(schema: Record<string, any>): DrivenSlots;
142
200
  //# sourceMappingURL=reference-field-map.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"reference-field-map.d.ts","sourceRoot":"","sources":["../src/reference-field-map.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"reference-field-map.d.ts","sourceRoot":"","sources":["../src/reference-field-map.ts"],"names":[],"mappings":"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"}