@telorun/kernel 0.49.0 → 0.51.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 (199) hide show
  1. package/dist/controller-loader.d.ts +6 -1
  2. package/dist/controller-loader.d.ts.map +1 -1
  3. package/dist/controller-loader.js +2 -0
  4. package/dist/controller-loader.js.map +1 -1
  5. package/dist/controller-loaders/bundle-builder.d.ts +2 -1
  6. package/dist/controller-loaders/bundle-builder.d.ts.map +1 -1
  7. package/dist/controller-loaders/bundle-builder.js +14 -9
  8. package/dist/controller-loaders/bundle-builder.js.map +1 -1
  9. package/dist/controller-loaders/npm-loader.d.ts +8 -2
  10. package/dist/controller-loaders/npm-loader.d.ts.map +1 -1
  11. package/dist/controller-loaders/npm-loader.js +19 -10
  12. package/dist/controller-loaders/npm-loader.js.map +1 -1
  13. package/dist/controllers/logging/console-sink-controller.d.ts +15 -0
  14. package/dist/controllers/logging/console-sink-controller.d.ts.map +1 -0
  15. package/dist/controllers/logging/console-sink-controller.js +40 -0
  16. package/dist/controllers/logging/console-sink-controller.js.map +1 -0
  17. package/dist/controllers/logging/file-sink-controller.d.ts +11 -0
  18. package/dist/controllers/logging/file-sink-controller.d.ts.map +1 -0
  19. package/dist/controllers/logging/file-sink-controller.js +33 -0
  20. package/dist/controllers/logging/file-sink-controller.js.map +1 -0
  21. package/dist/controllers/logging/sink-identity.d.ts +37 -0
  22. package/dist/controllers/logging/sink-identity.d.ts.map +1 -0
  23. package/dist/controllers/logging/sink-identity.js +40 -0
  24. package/dist/controllers/logging/sink-identity.js.map +1 -0
  25. package/dist/controllers/module/import-controller.d.ts.map +1 -1
  26. package/dist/controllers/module/import-controller.js +25 -0
  27. package/dist/controllers/module/import-controller.js.map +1 -1
  28. package/dist/controllers/resource-definition/resource-definition-controller.d.ts.map +1 -1
  29. package/dist/controllers/resource-definition/resource-definition-controller.js +1 -0
  30. package/dist/controllers/resource-definition/resource-definition-controller.js.map +1 -1
  31. package/dist/evaluation-context.d.ts +27 -1
  32. package/dist/evaluation-context.d.ts.map +1 -1
  33. package/dist/evaluation-context.js +84 -16
  34. package/dist/evaluation-context.js.map +1 -1
  35. package/dist/index.d.ts +4 -0
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +5 -0
  38. package/dist/index.js.map +1 -1
  39. package/dist/internal-context.d.ts +4 -0
  40. package/dist/internal-context.d.ts.map +1 -1
  41. package/dist/kernel.d.ts +26 -0
  42. package/dist/kernel.d.ts.map +1 -1
  43. package/dist/kernel.js +78 -5
  44. package/dist/kernel.js.map +1 -1
  45. package/dist/logging/bootstrap-writer.d.ts +23 -0
  46. package/dist/logging/bootstrap-writer.d.ts.map +1 -0
  47. package/dist/logging/bootstrap-writer.js +31 -0
  48. package/dist/logging/bootstrap-writer.js.map +1 -0
  49. package/dist/logging/color-precedence.d.ts +27 -0
  50. package/dist/logging/color-precedence.d.ts.map +1 -0
  51. package/dist/logging/color-precedence.js +47 -0
  52. package/dist/logging/color-precedence.js.map +1 -0
  53. package/dist/logging/console-sink.d.ts +45 -0
  54. package/dist/logging/console-sink.d.ts.map +1 -0
  55. package/dist/logging/console-sink.js +56 -0
  56. package/dist/logging/console-sink.js.map +1 -0
  57. package/dist/logging/debug-wire-sink.d.ts +38 -0
  58. package/dist/logging/debug-wire-sink.d.ts.map +1 -0
  59. package/dist/logging/debug-wire-sink.js +85 -0
  60. package/dist/logging/debug-wire-sink.js.map +1 -0
  61. package/dist/logging/drop-accounting.d.ts +34 -0
  62. package/dist/logging/drop-accounting.d.ts.map +1 -0
  63. package/dist/logging/drop-accounting.js +98 -0
  64. package/dist/logging/drop-accounting.js.map +1 -0
  65. package/dist/logging/encode-json.d.ts +28 -0
  66. package/dist/logging/encode-json.d.ts.map +1 -0
  67. package/dist/logging/encode-json.js +86 -0
  68. package/dist/logging/encode-json.js.map +1 -0
  69. package/dist/logging/encode-pretty.d.ts +7 -0
  70. package/dist/logging/encode-pretty.d.ts.map +1 -0
  71. package/dist/logging/encode-pretty.js +104 -0
  72. package/dist/logging/encode-pretty.js.map +1 -0
  73. package/dist/logging/file-sink.d.ts +33 -0
  74. package/dist/logging/file-sink.d.ts.map +1 -0
  75. package/dist/logging/file-sink.js +72 -0
  76. package/dist/logging/file-sink.js.map +1 -0
  77. package/dist/logging/index.d.ts +39 -0
  78. package/dist/logging/index.d.ts.map +1 -0
  79. package/dist/logging/index.js +27 -0
  80. package/dist/logging/index.js.map +1 -0
  81. package/dist/logging/kernel-logging.d.ts +110 -0
  82. package/dist/logging/kernel-logging.d.ts.map +1 -0
  83. package/dist/logging/kernel-logging.js +199 -0
  84. package/dist/logging/kernel-logging.js.map +1 -0
  85. package/dist/logging/log-sink.d.ts +9 -0
  86. package/dist/logging/log-sink.d.ts.map +1 -0
  87. package/dist/logging/log-sink.js +8 -0
  88. package/dist/logging/log-sink.js.map +1 -0
  89. package/dist/logging/logging-host.d.ts +14 -0
  90. package/dist/logging/logging-host.d.ts.map +1 -0
  91. package/dist/logging/logging-host.js +27 -0
  92. package/dist/logging/logging-host.js.map +1 -0
  93. package/dist/logging/logging-pipeline.d.ts +89 -0
  94. package/dist/logging/logging-pipeline.d.ts.map +1 -0
  95. package/dist/logging/logging-pipeline.js +349 -0
  96. package/dist/logging/logging-pipeline.js.map +1 -0
  97. package/dist/logging/normalize-attributes.d.ts +48 -0
  98. package/dist/logging/normalize-attributes.d.ts.map +1 -0
  99. package/dist/logging/normalize-attributes.js +140 -0
  100. package/dist/logging/normalize-attributes.js.map +1 -0
  101. package/dist/logging/record-buffer.d.ts +24 -0
  102. package/dist/logging/record-buffer.d.ts.map +1 -0
  103. package/dist/logging/record-buffer.js +78 -0
  104. package/dist/logging/record-buffer.js.map +1 -0
  105. package/dist/logging/redact-attributes.d.ts +45 -0
  106. package/dist/logging/redact-attributes.d.ts.map +1 -0
  107. package/dist/logging/redact-attributes.js +152 -0
  108. package/dist/logging/redact-attributes.js.map +1 -0
  109. package/dist/logging/sampler.d.ts +34 -0
  110. package/dist/logging/sampler.d.ts.map +1 -0
  111. package/dist/logging/sampler.js +52 -0
  112. package/dist/logging/sampler.js.map +1 -0
  113. package/dist/logging/scope-config.d.ts +32 -0
  114. package/dist/logging/scope-config.d.ts.map +1 -0
  115. package/dist/logging/scope-config.js +2 -0
  116. package/dist/logging/scope-config.js.map +1 -0
  117. package/dist/logging/span-id.d.ts +24 -0
  118. package/dist/logging/span-id.d.ts.map +1 -0
  119. package/dist/logging/span-id.js +85 -0
  120. package/dist/logging/span-id.js.map +1 -0
  121. package/dist/logging/to-error-value.d.ts +3 -0
  122. package/dist/logging/to-error-value.d.ts.map +1 -0
  123. package/dist/logging/to-error-value.js +79 -0
  124. package/dist/logging/to-error-value.js.map +1 -0
  125. package/dist/logging/trace-parent.d.ts +54 -0
  126. package/dist/logging/trace-parent.d.ts.map +1 -0
  127. package/dist/logging/trace-parent.js +92 -0
  128. package/dist/logging/trace-parent.js.map +1 -0
  129. package/dist/manifest-schemas.d.ts +1 -1
  130. package/dist/manifest-schemas.d.ts.map +1 -1
  131. package/dist/manifest-schemas.js +12 -0
  132. package/dist/manifest-schemas.js.map +1 -1
  133. package/dist/module-context.d.ts +16 -0
  134. package/dist/module-context.d.ts.map +1 -1
  135. package/dist/module-context.js +6 -0
  136. package/dist/module-context.js.map +1 -1
  137. package/dist/resource-context.d.ts +15 -1
  138. package/dist/resource-context.d.ts.map +1 -1
  139. package/dist/resource-context.js +45 -0
  140. package/dist/resource-context.js.map +1 -1
  141. package/dist/schema-compiled-values.d.ts.map +1 -1
  142. package/dist/schema-compiled-values.js +7 -0
  143. package/dist/schema-compiled-values.js.map +1 -1
  144. package/dist/schema-validator.d.ts +8 -1
  145. package/dist/schema-validator.d.ts.map +1 -1
  146. package/dist/schema-validator.js +13 -3
  147. package/dist/schema-validator.js.map +1 -1
  148. package/dist/transports/oci/oci-transport.d.ts +2 -0
  149. package/dist/transports/oci/oci-transport.d.ts.map +1 -1
  150. package/dist/transports/oci/oci-transport.js +15 -1
  151. package/dist/transports/oci/oci-transport.js.map +1 -1
  152. package/dist/transports/registry-transport.d.ts +2 -0
  153. package/dist/transports/registry-transport.d.ts.map +1 -1
  154. package/dist/transports/registry-transport.js +13 -0
  155. package/dist/transports/registry-transport.js.map +1 -1
  156. package/dist/transports/transport.d.ts +15 -0
  157. package/dist/transports/transport.d.ts.map +1 -1
  158. package/package.json +17 -3
  159. package/src/controller-loader.ts +7 -1
  160. package/src/controller-loaders/bundle-builder.ts +18 -10
  161. package/src/controller-loaders/npm-loader.ts +32 -11
  162. package/src/controllers/logging/console-sink-controller.ts +46 -0
  163. package/src/controllers/logging/file-sink-controller.ts +40 -0
  164. package/src/controllers/logging/sink-identity.ts +53 -0
  165. package/src/controllers/module/import-controller.ts +27 -0
  166. package/src/controllers/resource-definition/resource-definition-controller.ts +1 -0
  167. package/src/evaluation-context.ts +93 -15
  168. package/src/index.ts +54 -0
  169. package/src/internal-context.ts +4 -0
  170. package/src/kernel.ts +98 -8
  171. package/src/logging/bootstrap-writer.ts +38 -0
  172. package/src/logging/color-precedence.ts +62 -0
  173. package/src/logging/console-sink.ts +86 -0
  174. package/src/logging/debug-wire-sink.ts +85 -0
  175. package/src/logging/drop-accounting.ts +108 -0
  176. package/src/logging/encode-json.ts +98 -0
  177. package/src/logging/encode-pretty.ts +117 -0
  178. package/src/logging/file-sink.ts +87 -0
  179. package/src/logging/index.ts +65 -0
  180. package/src/logging/kernel-logging.ts +266 -0
  181. package/src/logging/log-sink.ts +18 -0
  182. package/src/logging/logging-host.ts +33 -0
  183. package/src/logging/logging-pipeline.ts +465 -0
  184. package/src/logging/normalize-attributes.ts +228 -0
  185. package/src/logging/record-buffer.ts +72 -0
  186. package/src/logging/redact-attributes.ts +168 -0
  187. package/src/logging/sampler.ts +76 -0
  188. package/src/logging/scope-config.ts +32 -0
  189. package/src/logging/span-id.ts +84 -0
  190. package/src/logging/to-error-value.ts +89 -0
  191. package/src/logging/trace-parent.ts +110 -0
  192. package/src/manifest-schemas.ts +12 -0
  193. package/src/module-context.ts +23 -0
  194. package/src/resource-context.ts +48 -0
  195. package/src/schema-compiled-values.ts +6 -0
  196. package/src/schema-validator.ts +20 -5
  197. package/src/transports/oci/oci-transport.ts +16 -0
  198. package/src/transports/registry-transport.ts +14 -0
  199. package/src/transports/transport.ts +17 -0
@@ -1,4 +1,5 @@
1
1
  import { executeInvokeStep, getRefIdentity, RuntimeError } from "@telorun/sdk";
2
+ import type { ScopeConfig } from "./logging/scope-config.js";
2
3
  import type {
3
4
  BootTarget,
4
5
  ControllerPolicy,
@@ -128,6 +129,20 @@ export class ModuleContext extends EvaluationContext implements IModuleContext {
128
129
  */
129
130
  private _controllerPolicy: ControllerPolicy | undefined;
130
131
 
132
+ /**
133
+ * The effective logging configuration for this module context — threshold,
134
+ * redaction, sampling, and the dotted import-alias path that identifies it.
135
+ *
136
+ * Stamped by the parent `Telo.Import` controller, which merges the import's
137
+ * own `logging:` block over its parent's *once*, when the import graph is
138
+ * built. Resolution therefore happens at load and the result is a plain value:
139
+ * there is no per-record lookup and no walk up the import chain at emit time,
140
+ * and it is the same scalar a guest runtime caches across an FFI boundary, so
141
+ * scoping and the FFI threshold cache are one mechanism rather than two.
142
+ * See kernel/specs/logging.md §12.2 and §9.
143
+ */
144
+ private _loggingConfig: ScopeConfig | undefined;
145
+
131
146
  constructor(
132
147
  source: string,
133
148
  variables: Record<string, unknown> = {},
@@ -192,6 +207,14 @@ export class ModuleContext extends EvaluationContext implements IModuleContext {
192
207
  return this._controllerPolicy;
193
208
  }
194
209
 
210
+ setLoggingConfig(config: ScopeConfig | undefined): void {
211
+ this._loggingConfig = config;
212
+ }
213
+
214
+ getLoggingConfig(): ScopeConfig | undefined {
215
+ return this._loggingConfig;
216
+ }
217
+
195
218
  protected override onResourceSnapshotted(name: string, snap: Record<string, unknown>): void {
196
219
  this.setResource(name, snap);
197
220
  }
@@ -12,6 +12,7 @@ import {
12
12
  type InvokeContext,
13
13
  type LoadOptions,
14
14
  type ModuleContext,
15
+ type Logger,
15
16
  type OpenSpan,
16
17
  type OpenSpanOptions,
17
18
  type ParsedArgs,
@@ -19,6 +20,14 @@ import {
19
20
  } from "@telorun/sdk";
20
21
  import { isRefSentinel } from "@telorun/templating";
21
22
  import { hostEnv } from "./host-env.js";
23
+ import type { LoggingHost } from "./logging/logging-host.js";
24
+ import type { ScopeConfig } from "./logging/scope-config.js";
25
+
26
+ /** The kernel's `ModuleContext` as far as logging is concerned. Declared
27
+ * structurally rather than imported to avoid a module cycle. */
28
+ interface KernelModuleContext {
29
+ getLoggingConfig?(): ScopeConfig | undefined;
30
+ }
22
31
  import { stripCompiledValues } from "./schema-compiled-values.js";
23
32
  import AjvModule from "ajv";
24
33
  import addFormats from "ajv-formats";
@@ -44,6 +53,45 @@ export class ResourceContextImpl implements ResourceContext {
44
53
  * and stamps the owner on the child context it registers them into. */
45
54
  readonly ownerPrefix: string;
46
55
 
56
+ /** Built lazily: most resources never log, and constructing the scoped logger
57
+ * eagerly for every context would allocate per resource for nothing. */
58
+ #log: Logger | undefined;
59
+
60
+ /**
61
+ * The resource's structured logger, stamped with its identity, module, and
62
+ * import-alias scope so a record identifies *which instance* emitted it — the
63
+ * distinction `module` alone cannot make when the same library is imported
64
+ * twice (§7.3).
65
+ */
66
+ get log(): Logger {
67
+ if (!this.#log) {
68
+ const kind = this.metadata?.kind as string | undefined;
69
+ const name = this.metadata?.metadata?.name as string | undefined;
70
+ const resource =
71
+ kind && name
72
+ ? { kind, name, id: `${this.ownerPrefix}${kind}.${name}` }
73
+ : undefined;
74
+ // The runtime value is always the kernel's `ModuleContext`, which carries
75
+ // the resolved per-scope config; the field is typed as the SDK's narrower
76
+ // interface, which deliberately does not expose kernel-internal state.
77
+ const scope = (
78
+ this.moduleContext as unknown as KernelModuleContext
79
+ ).getLoggingConfig?.();
80
+ this.#log = this.kernel.logging.createLogger(scope, resource);
81
+ }
82
+ return this.#log;
83
+ }
84
+
85
+ /** The sink-facing half of the pipeline. Only the built-in sink controllers
86
+ * reach for it; every other controller uses {@link log}. */
87
+ get logging(): LoggingHost {
88
+ return this.kernel.logging.host;
89
+ }
90
+
91
+ kernelLoggingRootScope(): ScopeConfig {
92
+ return this.kernel.logging.rootScope;
93
+ }
94
+
47
95
  constructor(
48
96
  readonly kernel: Kernel,
49
97
  readonly moduleContext: ModuleContext,
@@ -3,6 +3,12 @@ import { isCompiledValue } from "@telorun/sdk";
3
3
  /** Returns a schema-appropriate placeholder value for a CompiledValue field. */
4
4
  function placeholderForSchema(schema: Record<string, unknown>): unknown {
5
5
  if (schema.default !== undefined) return schema.default;
6
+ // An enum-constrained field needs a placeholder drawn from the enum: the
7
+ // type-based fallbacks below satisfy `type` but violate `enum`, so any CEL
8
+ // expression feeding an enum field would fail validation against a value the
9
+ // author never wrote. Mirrors `celPlaceholderForSchema` in the analyzer, which
10
+ // performs the same substitution for the static half.
11
+ if (Array.isArray(schema.enum) && schema.enum.length > 0) return schema.enum[0];
6
12
  switch (schema.type) {
7
13
  case "integer":
8
14
  case "number":
@@ -1,5 +1,5 @@
1
1
  import { evaluate } from "@marcbachmann/cel-js";
2
- import { DataValidator, isCompiledValue, RuntimeError, TypeRule } from "@telorun/sdk";
2
+ import { DataValidator, isCompiledValue, NOOP_LOGGER, RuntimeError, TypeRule, type Logger } from "@telorun/sdk";
3
3
  import AjvModule, { type ValidateFunction } from "ajv";
4
4
  import standaloneCodeMod from "ajv/dist/standalone/index.js";
5
5
  import addFormats from "ajv-formats";
@@ -148,6 +148,16 @@ export class SchemaValidator {
148
148
  * process — `compiledValidators` is keyed by object identity and would
149
149
  * miss those cases. */
150
150
  private hashCache = new Map<string, DataValidator>();
151
+ /** Where cache-failure diagnostics go. Injected rather than reached for
152
+ * globally: this class is constructed outside the kernel's stdio scope, and
153
+ * §13.1 forbids the kernel writing to `process.stderr` directly. Defaults to
154
+ * a no-op so a standalone construction (tests, tooling) stays silent. */
155
+ private log: Logger = NOOP_LOGGER;
156
+
157
+ /** Route cache diagnostics through the kernel's logger. */
158
+ setLogger(log: Logger): void {
159
+ this.log = log;
160
+ }
151
161
 
152
162
  constructor() {
153
163
  this.ajv = new Ajv({
@@ -172,6 +182,7 @@ export class SchemaValidator {
172
182
  "x-telo-step-context",
173
183
  "x-telo-widget",
174
184
  "x-telo-type",
185
+ "x-telo-inline",
175
186
  ]) {
176
187
  this.ajv.addKeyword(kw);
177
188
  }
@@ -342,8 +353,10 @@ export class SchemaValidator {
342
353
  // stale file with a fresh hash header.
343
354
  } catch (err) {
344
355
  if ((err as NodeJS.ErrnoException)?.code !== "ENOENT") {
345
- process.stderr.write(
346
- `[telo:kernel] validator cache load failed (${hash}): ${err instanceof Error ? err.message : String(err)}\n`,
356
+ this.log.warn(
357
+ "validator cache load failed",
358
+ { "telo.validator.hash": hash },
359
+ { error: err },
347
360
  );
348
361
  }
349
362
  }
@@ -358,8 +371,10 @@ export class SchemaValidator {
358
371
  fs.mkdirSync(cacheDir, { recursive: true });
359
372
  fs.writeFileSync(path.join(cacheDir, `${hash}.cjs`), payload, "utf-8");
360
373
  } catch (err) {
361
- process.stderr.write(
362
- `[telo:kernel] validator cache write failed (${hash}): ${err instanceof Error ? err.message : String(err)}\n`,
374
+ this.log.warn(
375
+ "validator cache write failed",
376
+ { "telo.validator.hash": hash },
377
+ { error: err },
363
378
  );
364
379
  }
365
380
  }
@@ -2,6 +2,7 @@ import {
2
2
  DEFAULT_MANIFEST_FILENAME,
3
3
  IntegrityError,
4
4
  sha256Base64Url,
5
+ splitIntegrity,
5
6
  verifyIntegrity,
6
7
  type ManifestSource,
7
8
  } from "@telorun/analyzer";
@@ -126,6 +127,21 @@ export class OciTransport implements Transport {
126
127
  return tags;
127
128
  }
128
129
 
130
+ refVersion(ref: string): string | null {
131
+ // The reference (tag or `sha256:` digest) is what `@` separates. An implicit
132
+ // `latest` (no `@`) is not an upgradeable pin, so return null there; a digest
133
+ // reference flows through raw and the caller's SemVer check skips it.
134
+ const { base } = splitIntegrity(ref);
135
+ if (!base.startsWith(OCI_SCHEME)) return null;
136
+ const at = base.lastIndexOf("@");
137
+ return at > 0 ? base.slice(at + 1) : null;
138
+ }
139
+
140
+ withVersion(ref: string, version: string): string {
141
+ const { host, repo } = parseOciRef(ref);
142
+ return `${OCI_SCHEME}${host}/${repo}@${version}`;
143
+ }
144
+
129
145
  async digest(ref: string): Promise<string | null> {
130
146
  const { host, repo, reference } = parseOciRef(ref);
131
147
  return new OciClient(host, repo).headManifest(reference);
@@ -173,6 +173,20 @@ export class RegistryTransport implements Transport {
173
173
  return Array.isArray(body.versions) ? body.versions : [];
174
174
  }
175
175
 
176
+ refVersion(ref: string): string | null {
177
+ // Only bare `namespace/name@version` refs carry an upgradeable version — a
178
+ // direct `https://` URL has no version segment to bump.
179
+ if (!isRegistryRef(ref)) return null;
180
+ const { base } = splitIntegrity(ref);
181
+ const at = base.lastIndexOf("@");
182
+ return at > 0 ? base.slice(at + 1) : null;
183
+ }
184
+
185
+ withVersion(ref: string, version: string): string {
186
+ const { modulePath } = parseModuleRef(ref);
187
+ return `${modulePath}@${version}`;
188
+ }
189
+
176
190
  /** Mirrors the sources' fetch-URL derivation: a direct URL points at (or
177
191
  * contains) the YAML file; a bare registry ref folds into the registry
178
192
  * layout. `null` when this transport does not own the ref's shape. */
@@ -83,6 +83,23 @@ export interface Transport {
83
83
  * by `telo upgrade`. */
84
84
  listVersions(ref: string): Promise<string[] | null>;
85
85
 
86
+ /** The version segment currently named in `ref` — a registry `@version`, an
87
+ * OCI tag, or an OCI digest reference (`sha256:…`), returned raw (the caller
88
+ * applies its own SemVer validation). Returns `null` when the ref carries no
89
+ * upgradeable version at all — a bare `https://` URL, or an OCI ref with no
90
+ * explicit reference. The integrity fragment is ignored. Used by `telo
91
+ * upgrade` to read the current pin. Paired with {@link withVersion}, which
92
+ * owns the scheme-specific reconstruction, so `upgrade` never branches on
93
+ * ref shape. */
94
+ refVersion(ref: string): string | null;
95
+
96
+ /** `ref` rewritten to name `version`, dropping any integrity fragment (the
97
+ * caller re-pins the result). Scheme-specific reconstruction — registry
98
+ * `<ns>/<name>@version`, OCI `oci://host/repo@version`. Only called for refs
99
+ * {@link refVersion} classified as versioned, so it may assume a parseable
100
+ * ref. Used by `telo upgrade`. */
101
+ withVersion(ref: string, version: string): string;
102
+
86
103
  /** Retrieve the full artifact for `ref` — the `telo.yaml` and its `files:`
87
104
  * payload — verifying the manifest against the inline hash and the payload
88
105
  * against the manifest's `filesIntegrity`. Used by `telo install`; subsumes