@obversa/api 0.1.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 (69) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +49 -0
  3. package/dist/accepted-result-support.d.ts +1 -0
  4. package/dist/accepted-result-support.js +5 -0
  5. package/dist/accepted-result-support.js.map +1 -0
  6. package/dist/action-decision.d.ts +15 -0
  7. package/dist/approval-support.d.ts +1 -0
  8. package/dist/approval-support.js +5 -0
  9. package/dist/approval-support.js.map +1 -0
  10. package/dist/artifacts/conformance.d.ts +20 -0
  11. package/dist/artifacts/store.d.ts +30 -0
  12. package/dist/budget.d.ts +36 -0
  13. package/dist/callback/approval.d.ts +80 -0
  14. package/dist/callback/client-contract.d.ts +81 -0
  15. package/dist/callback/gate.d.ts +49 -0
  16. package/dist/callback/stored-client.d.ts +22 -0
  17. package/dist/chunk-6NA4RDQ4.js +81 -0
  18. package/dist/chunk-6NA4RDQ4.js.map +1 -0
  19. package/dist/chunk-6NAMCSPJ.js +331 -0
  20. package/dist/chunk-6NAMCSPJ.js.map +1 -0
  21. package/dist/chunk-6ZP73HZN.js +293 -0
  22. package/dist/chunk-6ZP73HZN.js.map +1 -0
  23. package/dist/chunk-AJ353QD5.js +157 -0
  24. package/dist/chunk-AJ353QD5.js.map +1 -0
  25. package/dist/chunk-VWZKI7AG.js +552 -0
  26. package/dist/chunk-VWZKI7AG.js.map +1 -0
  27. package/dist/chunk-WGLWWKF3.js +135 -0
  28. package/dist/chunk-WGLWWKF3.js.map +1 -0
  29. package/dist/contracts.d.ts +122 -0
  30. package/dist/engine-conformance.d.ts +80 -0
  31. package/dist/environment.d.ts +53 -0
  32. package/dist/error.d.ts +36 -0
  33. package/dist/events/conformance.d.ts +20 -0
  34. package/dist/events/envelope.d.ts +26 -0
  35. package/dist/events/store.d.ts +15 -0
  36. package/dist/graph-commands.d.ts +23 -0
  37. package/dist/graph-contract.d.ts +48 -0
  38. package/dist/graph-executor.d.ts +61 -0
  39. package/dist/graph-kernel.d.ts +2 -0
  40. package/dist/graph-plan.d.ts +140 -0
  41. package/dist/graph-type.d.ts +45 -0
  42. package/dist/index.d.ts +33 -0
  43. package/dist/index.js +806 -0
  44. package/dist/index.js.map +1 -0
  45. package/dist/json.d.ts +14 -0
  46. package/dist/memory-conformance.d.ts +17 -0
  47. package/dist/memory-types.d.ts +127 -0
  48. package/dist/model-identity.d.ts +28 -0
  49. package/dist/node-data-context.d.ts +11 -0
  50. package/dist/preflight-result.d.ts +17 -0
  51. package/dist/proof/acceptance.d.ts +60 -0
  52. package/dist/proof/artifact.d.ts +2 -0
  53. package/dist/proof/cache.d.ts +46 -0
  54. package/dist/reasoning-record-contract.d.ts +52 -0
  55. package/dist/result-contract.d.ts +16 -0
  56. package/dist/result.d.ts +30 -0
  57. package/dist/run-definition-support.d.ts +1 -0
  58. package/dist/run-definition-support.js +5 -0
  59. package/dist/run-definition-support.js.map +1 -0
  60. package/dist/run-definition.d.ts +73 -0
  61. package/dist/storage/error.d.ts +7 -0
  62. package/dist/storage/id.d.ts +2 -0
  63. package/dist/testing.d.ts +5 -0
  64. package/dist/testing.js +1745 -0
  65. package/dist/testing.js.map +1 -0
  66. package/dist/workspace/conformance.d.ts +30 -0
  67. package/dist/workspace/policy.d.ts +6 -0
  68. package/dist/workspace/provider.d.ts +132 -0
  69. package/package.json +68 -0
@@ -0,0 +1,552 @@
1
+ import { validateStorageId, validateArtifactReference } from './chunk-WGLWWKF3.js';
2
+ import { cloneFrozenJson, JsonValueError, digestJson, canonicalJson, StorageError } from './chunk-AJ353QD5.js';
3
+
4
+ // src/graph-contract.ts
5
+ var GraphValidationError = class extends Error {
6
+ issues;
7
+ constructor(message, issues) {
8
+ super(message);
9
+ this.name = "GraphValidationError";
10
+ this.issues = Object.freeze(
11
+ issues.map((issue2) => Object.freeze({ ...issue2 }))
12
+ );
13
+ }
14
+ };
15
+
16
+ // src/graph-kernel.ts
17
+ var CONTROL_CHARACTER = /[\u0000-\u001f\u007f]/u;
18
+ function isRecord(value) {
19
+ return value !== null && typeof value === "object" && !Array.isArray(value);
20
+ }
21
+ function isId(value) {
22
+ return typeof value === "string" && value.length > 0 && value === value.trim() && !CONTROL_CHARACTER.test(value);
23
+ }
24
+ function issue(code, path, message) {
25
+ return { code, path, message };
26
+ }
27
+ function validateDefinition(value) {
28
+ const issues = [];
29
+ if (!isRecord(value)) {
30
+ throw new GraphValidationError("Graph definition is invalid.", [
31
+ issue("INVALID_DEFINITION", "", "The graph definition must be an object.")
32
+ ]);
33
+ }
34
+ if (!isId(value.id)) {
35
+ issues.push(
36
+ issue(
37
+ "INVALID_ID",
38
+ "/id",
39
+ "The graph id must be a non-empty trimmed string without control characters."
40
+ )
41
+ );
42
+ }
43
+ if (typeof value.definitionVersion !== "number" || !Number.isSafeInteger(value.definitionVersion) || value.definitionVersion < 1) {
44
+ issues.push(
45
+ issue(
46
+ "INVALID_VERSION",
47
+ "/definitionVersion",
48
+ "The definition version must be a positive safe integer."
49
+ )
50
+ );
51
+ }
52
+ if (!Object.hasOwn(value, "data")) {
53
+ issues.push(
54
+ issue("INVALID_DEFINITION", "/data", "The graph data field is required.")
55
+ );
56
+ }
57
+ const nodeIds = /* @__PURE__ */ new Set();
58
+ if (!Array.isArray(value.nodes)) {
59
+ issues.push(
60
+ issue("INVALID_DEFINITION", "/nodes", "Graph nodes must be an array.")
61
+ );
62
+ } else {
63
+ for (const [index, node] of value.nodes.entries()) {
64
+ const path = `/nodes/${index}`;
65
+ if (!isRecord(node)) {
66
+ issues.push(
67
+ issue("INVALID_DEFINITION", path, "Each graph node must be an object.")
68
+ );
69
+ continue;
70
+ }
71
+ if (!isId(node.id)) {
72
+ issues.push(
73
+ issue(
74
+ "INVALID_ID",
75
+ `${path}/id`,
76
+ "A node id must be a non-empty trimmed string without control characters."
77
+ )
78
+ );
79
+ } else if (nodeIds.has(node.id)) {
80
+ issues.push(
81
+ issue(
82
+ "DUPLICATE_NODE_ID",
83
+ `${path}/id`,
84
+ `Node id "${node.id}" is already declared.`
85
+ )
86
+ );
87
+ } else {
88
+ nodeIds.add(node.id);
89
+ }
90
+ if (!Object.hasOwn(node, "data")) {
91
+ issues.push(
92
+ issue("INVALID_DEFINITION", `${path}/data`, "Node data is required.")
93
+ );
94
+ }
95
+ }
96
+ }
97
+ const edgeIds = /* @__PURE__ */ new Set();
98
+ if (!Array.isArray(value.edges)) {
99
+ issues.push(
100
+ issue("INVALID_DEFINITION", "/edges", "Graph edges must be an array.")
101
+ );
102
+ } else {
103
+ for (const [index, edge] of value.edges.entries()) {
104
+ const path = `/edges/${index}`;
105
+ if (!isRecord(edge)) {
106
+ issues.push(
107
+ issue("INVALID_DEFINITION", path, "Each graph edge must be an object.")
108
+ );
109
+ continue;
110
+ }
111
+ if (!isId(edge.id)) {
112
+ issues.push(
113
+ issue(
114
+ "INVALID_ID",
115
+ `${path}/id`,
116
+ "An edge id must be a non-empty trimmed string without control characters."
117
+ )
118
+ );
119
+ } else if (edgeIds.has(edge.id)) {
120
+ issues.push(
121
+ issue(
122
+ "DUPLICATE_EDGE_ID",
123
+ `${path}/id`,
124
+ `Edge id "${edge.id}" is already declared.`
125
+ )
126
+ );
127
+ } else {
128
+ edgeIds.add(edge.id);
129
+ }
130
+ if (!isId(edge.source)) {
131
+ issues.push(
132
+ issue(
133
+ "INVALID_ID",
134
+ `${path}/source`,
135
+ "An edge source must be a valid node id."
136
+ )
137
+ );
138
+ } else if (!nodeIds.has(edge.source)) {
139
+ issues.push(
140
+ issue(
141
+ "UNKNOWN_SOURCE_NODE",
142
+ `${path}/source`,
143
+ `Source node "${edge.source}" is not declared.`
144
+ )
145
+ );
146
+ }
147
+ if (!isId(edge.target)) {
148
+ issues.push(
149
+ issue(
150
+ "INVALID_ID",
151
+ `${path}/target`,
152
+ "An edge target must be a valid node id."
153
+ )
154
+ );
155
+ } else if (!nodeIds.has(edge.target)) {
156
+ issues.push(
157
+ issue(
158
+ "UNKNOWN_TARGET_NODE",
159
+ `${path}/target`,
160
+ `Target node "${edge.target}" is not declared.`
161
+ )
162
+ );
163
+ }
164
+ if (!Object.hasOwn(edge, "data")) {
165
+ issues.push(
166
+ issue("INVALID_DEFINITION", `${path}/data`, "Edge data is required.")
167
+ );
168
+ }
169
+ }
170
+ }
171
+ if (issues.length > 0) {
172
+ throw new GraphValidationError("Graph definition is invalid.", issues);
173
+ }
174
+ }
175
+ function compileGraphDefinition(definition) {
176
+ let frozen;
177
+ try {
178
+ frozen = cloneFrozenJson(definition);
179
+ } catch (error) {
180
+ if (!(error instanceof JsonValueError)) throw error;
181
+ throw new GraphValidationError("Graph definition is invalid.", [
182
+ issue("INVALID_JSON_VALUE", error.path, error.message)
183
+ ]);
184
+ }
185
+ validateDefinition(frozen);
186
+ const value = frozen;
187
+ return Object.freeze({
188
+ value,
189
+ canonicalJson: canonicalJson(value),
190
+ digest: digestJson(value)
191
+ });
192
+ }
193
+
194
+ // src/events/envelope.ts
195
+ var NEW_EVENT_FIELDS = [
196
+ "causationId",
197
+ "correlationId",
198
+ "eventId",
199
+ "payload",
200
+ "timestamp",
201
+ "type",
202
+ "version"
203
+ ];
204
+ var ENVELOPE_FIELDS = [
205
+ ...NEW_EVENT_FIELDS,
206
+ "envelopeVersion",
207
+ "revision",
208
+ "streamId"
209
+ ].sort();
210
+ var SAFE_PATH_ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/u;
211
+ var UTC_TIMESTAMP = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/u;
212
+ var CONTROL_CHARACTER2 = /[\u0000-\u001f\u007f]/u;
213
+ function fail(message, path, code = "INVALID_STORED_VALUE") {
214
+ throw new StorageError(code, message, { path });
215
+ }
216
+ function jsonObject(value, path) {
217
+ let cloned;
218
+ try {
219
+ cloned = cloneFrozenJson(value);
220
+ } catch (error) {
221
+ if (!(error instanceof JsonValueError)) throw error;
222
+ fail(error.message, `${path}${error.path}`);
223
+ }
224
+ if (cloned === null || typeof cloned !== "object" || Array.isArray(cloned)) {
225
+ fail("Stored event value must be an object.", path);
226
+ }
227
+ return cloned;
228
+ }
229
+ function exactFields(value, expected, path) {
230
+ const actual = Object.keys(value).sort();
231
+ if (actual.length !== expected.length || actual.some((field, index) => field !== expected[index])) {
232
+ fail(
233
+ `Stored event must contain exactly ${expected.join(", ")}.`,
234
+ path
235
+ );
236
+ }
237
+ }
238
+ function validateDomainEventId(value, path) {
239
+ if (typeof value !== "string" || value.length === 0 || value !== value.trim() || Buffer.byteLength(value, "utf8") > 256 || CONTROL_CHARACTER2.test(value)) {
240
+ fail(
241
+ "Identifier must be a non-empty trimmed string of at most 256 UTF-8 bytes without control characters.",
242
+ path
243
+ );
244
+ }
245
+ return value;
246
+ }
247
+ function positiveVersion(value, path) {
248
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 1) {
249
+ fail("Version must be a positive safe integer.", path);
250
+ }
251
+ return value;
252
+ }
253
+ function timestamp(value, path) {
254
+ if (typeof value !== "string" || !UTC_TIMESTAMP.test(value) || Number.isNaN(Date.parse(value)) || new Date(value).toISOString() !== value) {
255
+ fail("Timestamp must be an exact UTC ISO 8601 timestamp.", path);
256
+ }
257
+ return value;
258
+ }
259
+ function validateNewEventObject(value) {
260
+ validateDomainEventId(value.eventId, "/eventId");
261
+ validateDomainEventId(value.type, "/type");
262
+ positiveVersion(value.version, "/version");
263
+ timestamp(value.timestamp, "/timestamp");
264
+ validateDomainEventId(value.correlationId, "/correlationId");
265
+ if (value.causationId !== null) validateDomainEventId(value.causationId, "/causationId");
266
+ return value;
267
+ }
268
+ function validateNewDomainEvent(value) {
269
+ const event = jsonObject(value, "");
270
+ exactFields(event, NEW_EVENT_FIELDS, "");
271
+ return validateNewEventObject(event);
272
+ }
273
+ function validateDomainEventEnvelope(value) {
274
+ const event = jsonObject(value, "");
275
+ exactFields(event, ENVELOPE_FIELDS, "");
276
+ if (event.envelopeVersion !== 1) {
277
+ fail(
278
+ "Envelope version is not supported.",
279
+ "/envelopeVersion",
280
+ "UNSUPPORTED_ENVELOPE_VERSION"
281
+ );
282
+ }
283
+ if (typeof event.streamId !== "string" || !SAFE_PATH_ID.test(event.streamId)) {
284
+ fail(
285
+ "Stream id must use 1 to 128 ASCII letters, digits, dots, underscores, or hyphens.",
286
+ "/streamId"
287
+ );
288
+ }
289
+ positiveVersion(event.revision, "/revision");
290
+ validateNewEventObject(event);
291
+ return event;
292
+ }
293
+
294
+ // src/run-definition.ts
295
+ var DIGEST = /^sha256:[0-9a-f]{64}$/u;
296
+ var CONTROL_CHARACTER3 = /[\u0000-\u001f\u007f]/u;
297
+ function fail2(path, message) {
298
+ throw new StorageError("INVALID_STORED_VALUE", message, { path });
299
+ }
300
+ function json(value, path) {
301
+ try {
302
+ return cloneFrozenJson(value);
303
+ } catch (error) {
304
+ if (!(error instanceof JsonValueError)) throw error;
305
+ fail2(`${path}${error.path}`, error.message);
306
+ }
307
+ }
308
+ function record(value, path, label) {
309
+ const parsed = json(value, path);
310
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
311
+ fail2(path, `${label} must be an object.`);
312
+ }
313
+ return parsed;
314
+ }
315
+ function exactFields2(value, fields, path) {
316
+ const expected = new Set(fields);
317
+ for (const field of fields) {
318
+ if (!Object.hasOwn(value, field)) {
319
+ fail2(`${path}/${field}`, `Required field "${field}" is missing.`);
320
+ }
321
+ }
322
+ for (const field of Object.keys(value)) {
323
+ if (!expected.has(field)) {
324
+ fail2(`${path}/${field}`, `Unknown field "${field}" is not allowed.`);
325
+ }
326
+ }
327
+ }
328
+ function text(value, path, label) {
329
+ if (typeof value !== "string" || value.length === 0 || value !== value.trim() || CONTROL_CHARACTER3.test(value)) {
330
+ fail2(path, `${label} must be a non-empty trimmed string without control characters.`);
331
+ }
332
+ return value;
333
+ }
334
+ function version(value, path, expected = 1) {
335
+ if (!Number.isSafeInteger(value) || value !== expected) {
336
+ fail2(path, `Version must be ${expected}.`);
337
+ }
338
+ return value;
339
+ }
340
+ function positiveLimit(value, path) {
341
+ if (!Number.isSafeInteger(value) || value < 1) {
342
+ fail2(path, "A storage limit must be a positive safe integer.");
343
+ }
344
+ return value;
345
+ }
346
+ function digest(value, path) {
347
+ if (typeof value !== "string" || !DIGEST.test(value)) {
348
+ fail2(path, "Digest must be lowercase sha256 followed by 64 hexadecimal characters.");
349
+ }
350
+ return value;
351
+ }
352
+ function validateProvider(value, path) {
353
+ const item = record(value, path, "Storage provider");
354
+ exactFields2(item, ["schemaVersion", "name", "version", "configDigest"], path);
355
+ return Object.freeze({
356
+ schemaVersion: version(item.schemaVersion, `${path}/schemaVersion`),
357
+ name: text(item.name, `${path}/name`, "Provider name"),
358
+ version: text(item.version, `${path}/version`, "Provider version"),
359
+ configDigest: digest(item.configDigest, `${path}/configDigest`)
360
+ });
361
+ }
362
+ function validatePolicy(value, path) {
363
+ const item = record(value, path, "Storage policy");
364
+ exactFields2(item, [
365
+ "schemaVersion",
366
+ "maxEventPayloadBytes",
367
+ "maxAppendBatchBytes",
368
+ "maxArtifactBytes",
369
+ "maxTotalArtifactBytesPerRun",
370
+ "retention",
371
+ "sensitiveContent"
372
+ ], path);
373
+ const sensitive = record(
374
+ item.sensitiveContent,
375
+ `${path}/sensitiveContent`,
376
+ "Sensitive-content policy"
377
+ );
378
+ exactFields2(sensitive, ["marked", "exact", "freeText"], `${path}/sensitiveContent`);
379
+ if (sensitive.marked !== "reject") {
380
+ fail2(`${path}/sensitiveContent/marked`, "Marked-sensitive content must be rejected.");
381
+ }
382
+ if (sensitive.exact !== "reject") {
383
+ fail2(`${path}/sensitiveContent/exact`, "Exact content must reject known secrets.");
384
+ }
385
+ if (sensitive.freeText !== "redact-before-hash") {
386
+ fail2(`${path}/sensitiveContent/freeText`, "Free text must redact before hashing.");
387
+ }
388
+ const maxEventPayloadBytes = positiveLimit(
389
+ item.maxEventPayloadBytes,
390
+ `${path}/maxEventPayloadBytes`
391
+ );
392
+ const maxAppendBatchBytes = positiveLimit(
393
+ item.maxAppendBatchBytes,
394
+ `${path}/maxAppendBatchBytes`
395
+ );
396
+ const maxArtifactBytes = positiveLimit(
397
+ item.maxArtifactBytes,
398
+ `${path}/maxArtifactBytes`
399
+ );
400
+ const maxTotalArtifactBytesPerRun = positiveLimit(
401
+ item.maxTotalArtifactBytesPerRun,
402
+ `${path}/maxTotalArtifactBytesPerRun`
403
+ );
404
+ if (maxAppendBatchBytes < maxEventPayloadBytes) {
405
+ fail2(path, "The append-batch limit cannot be smaller than the event-payload limit.");
406
+ }
407
+ if (maxTotalArtifactBytesPerRun < maxArtifactBytes) {
408
+ fail2(path, "The per-run artifact limit cannot be smaller than the single-artifact limit.");
409
+ }
410
+ if (item.retention !== "until-run-delete") {
411
+ fail2(`${path}/retention`, "D3 artifacts must be retained until their run is deleted.");
412
+ }
413
+ return Object.freeze({
414
+ schemaVersion: version(item.schemaVersion, `${path}/schemaVersion`),
415
+ maxEventPayloadBytes,
416
+ maxAppendBatchBytes,
417
+ maxArtifactBytes,
418
+ maxTotalArtifactBytesPerRun,
419
+ retention: "until-run-delete",
420
+ sensitiveContent: Object.freeze({
421
+ marked: "reject",
422
+ exact: "reject",
423
+ freeText: "redact-before-hash"
424
+ })
425
+ });
426
+ }
427
+ function validateRunStoragePolicy(value) {
428
+ return validatePolicy(value, "");
429
+ }
430
+ function validateRunStorageRecord(value) {
431
+ const item = record(value, "", "Run storage record");
432
+ exactFields2(item, [
433
+ "schemaVersion",
434
+ "namespace",
435
+ "eventStore",
436
+ "artifactStore",
437
+ "policy"
438
+ ], "");
439
+ return Object.freeze({
440
+ schemaVersion: version(item.schemaVersion, "/schemaVersion"),
441
+ namespace: validateStorageId(item.namespace, "/namespace"),
442
+ eventStore: validateProvider(item.eventStore, "/eventStore"),
443
+ artifactStore: validateProvider(item.artifactStore, "/artifactStore"),
444
+ policy: validatePolicy(item.policy, "/policy")
445
+ });
446
+ }
447
+ function validateCompiledDefinition(value) {
448
+ const item = record(value, "/graphDefinition", "Compiled graph definition");
449
+ exactFields2(item, ["value", "canonicalJson", "digest"], "/graphDefinition");
450
+ let rebuilt;
451
+ try {
452
+ rebuilt = compileGraphDefinition(item.value);
453
+ } catch (error) {
454
+ fail2("/graphDefinition/value", error instanceof Error ? error.message : String(error));
455
+ }
456
+ if (item.canonicalJson !== rebuilt.canonicalJson) {
457
+ fail2("/graphDefinition/canonicalJson", "Graph definition bytes do not match its value.");
458
+ }
459
+ if (item.digest !== rebuilt.digest) {
460
+ fail2("/graphDefinition/digest", "Graph definition digest does not match its value.");
461
+ }
462
+ return rebuilt;
463
+ }
464
+ function artifactReference(value, path, purpose) {
465
+ let reference;
466
+ try {
467
+ reference = validateArtifactReference(value);
468
+ } catch (error) {
469
+ if (!(error instanceof StorageError)) throw error;
470
+ fail2(path, error.message);
471
+ }
472
+ if (reference.purpose !== purpose) {
473
+ fail2(`${path}/purpose`, `Artifact purpose must be "${purpose}".`);
474
+ }
475
+ return reference;
476
+ }
477
+ function validateRunDefinition(value) {
478
+ const item = record(value, "", "Run definition");
479
+ exactFields2(item, [
480
+ "schemaVersion",
481
+ "runId",
482
+ "graphDefinition",
483
+ "resolvedPlan",
484
+ "resolvedInputs",
485
+ "storage",
486
+ "workspaceBinding",
487
+ "hostBinding"
488
+ ], "");
489
+ const resolvedPlan = artifactReference(
490
+ item.resolvedPlan,
491
+ "/resolvedPlan",
492
+ "resolved-plan"
493
+ );
494
+ if (resolvedPlan.mediaType !== "application/json") {
495
+ fail2("/resolvedPlan/mediaType", "The resolved plan must use application/json.");
496
+ }
497
+ const resolvedInputs = json(item.resolvedInputs, "/resolvedInputs");
498
+ if (resolvedInputs === null || typeof resolvedInputs !== "object" || Array.isArray(resolvedInputs)) {
499
+ fail2("/resolvedInputs", "Resolved inputs must be an object.");
500
+ }
501
+ const workspaceBinding = item.workspaceBinding === null ? null : record(item.workspaceBinding, "/workspaceBinding", "Workspace binding");
502
+ const hostBinding = item.hostBinding === null ? null : artifactReference(item.hostBinding, "/hostBinding", "host-binding");
503
+ return Object.freeze({
504
+ schemaVersion: version(item.schemaVersion, "/schemaVersion"),
505
+ runId: validateStorageId(item.runId, "/runId"),
506
+ graphDefinition: validateCompiledDefinition(item.graphDefinition),
507
+ resolvedPlan,
508
+ resolvedInputs,
509
+ storage: validateRunStorageRecord(item.storage),
510
+ workspaceBinding,
511
+ hostBinding
512
+ });
513
+ }
514
+ function validateRunStartRecord(value) {
515
+ const envelope = validateDomainEventEnvelope(value);
516
+ if (envelope.type !== "graph:run-started" || envelope.version !== 1) {
517
+ fail2("/type", "The run-start record must be graph:run-started version 1.");
518
+ }
519
+ if (envelope.revision !== 1) {
520
+ fail2("/revision", "The run-start record must be the first stream event.");
521
+ }
522
+ const payload = record(envelope.payload, "/payload", "Run-start payload");
523
+ exactFields2(payload, ["definition"], "/payload");
524
+ const definition = validateRunDefinition(payload.definition);
525
+ if (envelope.streamId !== definition.runId) {
526
+ fail2("/streamId", "The run-start stream must match the run id.");
527
+ }
528
+ if (envelope.correlationId !== definition.runId) {
529
+ fail2("/correlationId", "The run-start correlation id must match the run id.");
530
+ }
531
+ if (envelope.causationId !== null) {
532
+ fail2("/causationId", "The run-start event cannot have a cause.");
533
+ }
534
+ return cloneFrozenJson({
535
+ ...envelope,
536
+ type: "graph:run-started",
537
+ version: 1,
538
+ payload: { definition }
539
+ });
540
+ }
541
+ var runDefinitionSupport = Object.freeze({
542
+ fail: fail2,
543
+ json,
544
+ record,
545
+ text,
546
+ digest,
547
+ validateCompiledDefinition
548
+ });
549
+
550
+ export { GraphValidationError, compileGraphDefinition, runDefinitionSupport, validateDomainEventEnvelope, validateDomainEventId, validateNewDomainEvent, validateRunDefinition, validateRunStartRecord, validateRunStoragePolicy, validateRunStorageRecord };
551
+ //# sourceMappingURL=chunk-VWZKI7AG.js.map
552
+ //# sourceMappingURL=chunk-VWZKI7AG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/graph-contract.ts","../src/graph-kernel.ts","../src/events/envelope.ts","../src/run-definition.ts"],"names":["issue","CONTROL_CHARACTER","fail","exactFields"],"mappings":"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","file":"chunk-VWZKI7AG.js","sourcesContent":["import type { JsonObject, JsonValue, Sha256Digest } from './json.js';\n\nexport type RunBrief = JsonObject;\n\nexport interface GraphValidationIssue {\n readonly code: string;\n readonly path: string;\n readonly message: string;\n}\n\nexport class GraphValidationError extends Error {\n readonly issues: readonly GraphValidationIssue[];\n\n constructor(message: string, issues: readonly GraphValidationIssue[]) {\n super(message);\n this.name = 'GraphValidationError';\n this.issues = Object.freeze(\n issues.map((issue) => Object.freeze({ ...issue })),\n );\n }\n}\n\nexport type GraphId = string;\nexport type NodeId = string;\nexport type EdgeId = string;\n\nexport interface GraphNode<Data extends JsonValue = JsonValue>\n extends JsonObject {\n readonly id: NodeId;\n readonly data: Data;\n}\n\nexport interface GraphEdge<Data extends JsonValue = JsonValue>\n extends JsonObject {\n readonly id: EdgeId;\n readonly source: NodeId;\n readonly target: NodeId;\n readonly data: Data;\n}\n\nexport interface GraphDefinition<\n NodeData extends JsonValue = JsonValue,\n EdgeData extends JsonValue = JsonValue,\n GraphData extends JsonValue = JsonValue,\n> extends JsonObject {\n readonly id: GraphId;\n readonly definitionVersion: number;\n readonly data: GraphData;\n readonly nodes: readonly GraphNode<NodeData>[];\n readonly edges: readonly GraphEdge<EdgeData>[];\n}\n\nexport interface CompiledGraphDefinition<\n Definition extends GraphDefinition = GraphDefinition,\n> extends JsonObject {\n readonly value: Definition;\n readonly canonicalJson: string;\n readonly digest: Sha256Digest;\n}\n\ntype DefinitionNode<Definition extends GraphDefinition> =\n Definition['nodes'][number];\ntype DefinitionEdge<Definition extends GraphDefinition> =\n Definition['edges'][number];\n\nexport interface GraphKernel<\n Definition extends GraphDefinition = GraphDefinition,\n> {\n readonly definition: CompiledGraphDefinition<Definition>;\n node(id: NodeId): DefinitionNode<Definition> | undefined;\n edge(id: EdgeId): DefinitionEdge<Definition> | undefined;\n predecessors(id: NodeId): readonly NodeId[];\n successors(id: NodeId): readonly NodeId[];\n inboundEdges(id: NodeId): readonly DefinitionEdge<Definition>[];\n outboundEdges(id: NodeId): readonly DefinitionEdge<Definition>[];\n}\n","import { GraphValidationError, type GraphValidationIssue, type GraphDefinition, type CompiledGraphDefinition } from './graph-contract.js';\nimport { JsonValueError, canonicalJson, cloneFrozenJson, digestJson, type JsonObject, type JsonValue } from './json.js';\n\nconst CONTROL_CHARACTER = /[\\u0000-\\u001f\\u007f]/u;\n\nfunction isRecord(value: JsonValue | undefined): value is JsonObject {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction isId(value: JsonValue | undefined): value is string {\n return (\n typeof value === 'string' &&\n value.length > 0 &&\n value === value.trim() &&\n !CONTROL_CHARACTER.test(value)\n );\n}\n\nfunction issue(\n code: string,\n path: string,\n message: string,\n): GraphValidationIssue {\n return { code, path, message };\n}\n\nfunction validateDefinition(value: JsonValue): asserts value is GraphDefinition {\n const issues: GraphValidationIssue[] = [];\n if (!isRecord(value)) {\n throw new GraphValidationError('Graph definition is invalid.', [\n issue('INVALID_DEFINITION', '', 'The graph definition must be an object.'),\n ]);\n }\n\n if (!isId(value.id)) {\n issues.push(\n issue(\n 'INVALID_ID',\n '/id',\n 'The graph id must be a non-empty trimmed string without control characters.',\n ),\n );\n }\n\n if (\n typeof value.definitionVersion !== 'number' ||\n !Number.isSafeInteger(value.definitionVersion) ||\n value.definitionVersion < 1\n ) {\n issues.push(\n issue(\n 'INVALID_VERSION',\n '/definitionVersion',\n 'The definition version must be a positive safe integer.',\n ),\n );\n }\n\n if (!Object.hasOwn(value, 'data')) {\n issues.push(\n issue('INVALID_DEFINITION', '/data', 'The graph data field is required.'),\n );\n }\n\n const nodeIds = new Set<string>();\n if (!Array.isArray(value.nodes)) {\n issues.push(\n issue('INVALID_DEFINITION', '/nodes', 'Graph nodes must be an array.'),\n );\n } else {\n for (const [index, node] of value.nodes.entries()) {\n const path = `/nodes/${index}`;\n if (!isRecord(node)) {\n issues.push(\n issue('INVALID_DEFINITION', path, 'Each graph node must be an object.'),\n );\n continue;\n }\n\n if (!isId(node.id)) {\n issues.push(\n issue(\n 'INVALID_ID',\n `${path}/id`,\n 'A node id must be a non-empty trimmed string without control characters.',\n ),\n );\n } else if (nodeIds.has(node.id)) {\n issues.push(\n issue(\n 'DUPLICATE_NODE_ID',\n `${path}/id`,\n `Node id \"${node.id}\" is already declared.`,\n ),\n );\n } else {\n nodeIds.add(node.id);\n }\n\n if (!Object.hasOwn(node, 'data')) {\n issues.push(\n issue('INVALID_DEFINITION', `${path}/data`, 'Node data is required.'),\n );\n }\n }\n }\n\n const edgeIds = new Set<string>();\n if (!Array.isArray(value.edges)) {\n issues.push(\n issue('INVALID_DEFINITION', '/edges', 'Graph edges must be an array.'),\n );\n } else {\n for (const [index, edge] of value.edges.entries()) {\n const path = `/edges/${index}`;\n if (!isRecord(edge)) {\n issues.push(\n issue('INVALID_DEFINITION', path, 'Each graph edge must be an object.'),\n );\n continue;\n }\n\n if (!isId(edge.id)) {\n issues.push(\n issue(\n 'INVALID_ID',\n `${path}/id`,\n 'An edge id must be a non-empty trimmed string without control characters.',\n ),\n );\n } else if (edgeIds.has(edge.id)) {\n issues.push(\n issue(\n 'DUPLICATE_EDGE_ID',\n `${path}/id`,\n `Edge id \"${edge.id}\" is already declared.`,\n ),\n );\n } else {\n edgeIds.add(edge.id);\n }\n\n if (!isId(edge.source)) {\n issues.push(\n issue(\n 'INVALID_ID',\n `${path}/source`,\n 'An edge source must be a valid node id.',\n ),\n );\n } else if (!nodeIds.has(edge.source)) {\n issues.push(\n issue(\n 'UNKNOWN_SOURCE_NODE',\n `${path}/source`,\n `Source node \"${edge.source}\" is not declared.`,\n ),\n );\n }\n\n if (!isId(edge.target)) {\n issues.push(\n issue(\n 'INVALID_ID',\n `${path}/target`,\n 'An edge target must be a valid node id.',\n ),\n );\n } else if (!nodeIds.has(edge.target)) {\n issues.push(\n issue(\n 'UNKNOWN_TARGET_NODE',\n `${path}/target`,\n `Target node \"${edge.target}\" is not declared.`,\n ),\n );\n }\n\n if (!Object.hasOwn(edge, 'data')) {\n issues.push(\n issue('INVALID_DEFINITION', `${path}/data`, 'Edge data is required.'),\n );\n }\n }\n }\n\n if (issues.length > 0) {\n throw new GraphValidationError('Graph definition is invalid.', issues);\n }\n}\n\nexport function compileGraphDefinition<Definition extends GraphDefinition>(\n definition: Definition,\n): CompiledGraphDefinition<Definition> {\n let frozen: JsonValue;\n try {\n frozen = cloneFrozenJson(definition);\n } catch (error) {\n if (!(error instanceof JsonValueError)) throw error;\n throw new GraphValidationError('Graph definition is invalid.', [\n issue('INVALID_JSON_VALUE', error.path, error.message),\n ]);\n }\n\n validateDefinition(frozen);\n const value = frozen as Definition;\n return Object.freeze({\n value,\n canonicalJson: canonicalJson(value),\n digest: digestJson(value),\n });\n}\n","import {\n cloneFrozenJson,\n JsonValueError,\n type JsonObject,\n type JsonValue,\n} from '../json.js';\nimport { StorageError } from '../storage/error.js';\n\nexport type DomainEventId = string;\nexport type EventStreamId = string;\nexport type StorageNamespace = string;\nexport type StreamRevision = number;\n\nexport interface EventStreamRef {\n readonly namespace: StorageNamespace;\n readonly streamId: EventStreamId;\n}\n\nexport interface NewDomainEvent<\n Type extends string = string,\n Version extends number = number,\n Payload extends JsonValue = JsonValue,\n> {\n readonly eventId: DomainEventId;\n readonly type: Type;\n readonly version: Version;\n readonly timestamp: string;\n readonly correlationId: string;\n readonly causationId: DomainEventId | null;\n readonly payload: Payload;\n}\n\nexport interface DomainEventEnvelope<\n Type extends string = string,\n Version extends number = number,\n Payload extends JsonValue = JsonValue,\n> extends NewDomainEvent<Type, Version, Payload> {\n readonly envelopeVersion: 1;\n readonly streamId: EventStreamId;\n readonly revision: StreamRevision;\n}\n\nconst NEW_EVENT_FIELDS = [\n 'causationId',\n 'correlationId',\n 'eventId',\n 'payload',\n 'timestamp',\n 'type',\n 'version',\n] as const;\n\nconst ENVELOPE_FIELDS = [\n ...NEW_EVENT_FIELDS,\n 'envelopeVersion',\n 'revision',\n 'streamId',\n].sort();\n\nconst SAFE_PATH_ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/u;\nconst UTC_TIMESTAMP = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$/u;\nconst CONTROL_CHARACTER = /[\\u0000-\\u001f\\u007f]/u;\n\nfunction fail(\n message: string,\n path: string,\n code: 'INVALID_STORED_VALUE' | 'UNSUPPORTED_ENVELOPE_VERSION' = 'INVALID_STORED_VALUE',\n): never {\n throw new StorageError(code, message, { path });\n}\n\nfunction jsonObject(value: unknown, path: string): JsonObject {\n let cloned: JsonValue;\n try {\n cloned = cloneFrozenJson(value as JsonValue);\n } catch (error) {\n if (!(error instanceof JsonValueError)) throw error;\n fail(error.message, `${path}${error.path}`);\n }\n if (cloned === null || typeof cloned !== 'object' || Array.isArray(cloned)) {\n fail('Stored event value must be an object.', path);\n }\n return cloned as JsonObject;\n}\n\nfunction exactFields(\n value: JsonObject,\n expected: readonly string[],\n path: string,\n): void {\n const actual = Object.keys(value).sort();\n if (\n actual.length !== expected.length\n || actual.some((field, index) => field !== expected[index])\n ) {\n fail(\n `Stored event must contain exactly ${expected.join(', ')}.`,\n path,\n );\n }\n}\n\nexport function validateDomainEventId(value: unknown, path: string): string {\n if (\n typeof value !== 'string'\n || value.length === 0\n || value !== value.trim()\n || Buffer.byteLength(value, 'utf8') > 256\n || CONTROL_CHARACTER.test(value)\n ) {\n fail(\n 'Identifier must be a non-empty trimmed string of at most 256 UTF-8 bytes without control characters.',\n path,\n );\n }\n return value;\n}\n\nfunction positiveVersion(value: JsonValue | undefined, path: string): number {\n if (typeof value !== 'number' || !Number.isSafeInteger(value) || value < 1) {\n fail('Version must be a positive safe integer.', path);\n }\n return value;\n}\n\nfunction timestamp(value: JsonValue | undefined, path: string): string {\n if (\n typeof value !== 'string'\n || !UTC_TIMESTAMP.test(value)\n || Number.isNaN(Date.parse(value))\n || new Date(value).toISOString() !== value\n ) {\n fail('Timestamp must be an exact UTC ISO 8601 timestamp.', path);\n }\n return value;\n}\n\nfunction validateNewEventObject(value: JsonObject): NewDomainEvent {\n validateDomainEventId(value.eventId, '/eventId');\n validateDomainEventId(value.type, '/type');\n positiveVersion(value.version, '/version');\n timestamp(value.timestamp, '/timestamp');\n validateDomainEventId(value.correlationId, '/correlationId');\n if (value.causationId !== null) validateDomainEventId(value.causationId, '/causationId');\n return value as unknown as NewDomainEvent;\n}\n\nexport function validateNewDomainEvent(value: unknown): NewDomainEvent {\n const event = jsonObject(value, '');\n exactFields(event, NEW_EVENT_FIELDS, '');\n return validateNewEventObject(event);\n}\n\nexport function validateDomainEventEnvelope(\n value: unknown,\n): DomainEventEnvelope {\n const event = jsonObject(value, '');\n exactFields(event, ENVELOPE_FIELDS, '');\n if (event.envelopeVersion !== 1) {\n fail(\n 'Envelope version is not supported.',\n '/envelopeVersion',\n 'UNSUPPORTED_ENVELOPE_VERSION',\n );\n }\n if (typeof event.streamId !== 'string' || !SAFE_PATH_ID.test(event.streamId)) {\n fail(\n 'Stream id must use 1 to 128 ASCII letters, digits, dots, underscores, or hyphens.',\n '/streamId',\n );\n }\n positiveVersion(event.revision, '/revision');\n validateNewEventObject(event);\n return event as unknown as DomainEventEnvelope;\n}\n","import { compileGraphDefinition } from './graph-kernel.js';\nimport type { CompiledGraphDefinition, GraphDefinition, RunBrief } from './graph-contract.js';\nimport { cloneFrozenJson, JsonValueError, type JsonObject, type JsonValue, type Sha256Digest } from './json.js';\nimport { validateArtifactReference, type ArtifactReference, type ArtifactStore } from './artifacts/store.js';\nimport { validateDomainEventEnvelope, type DomainEventEnvelope, type NewDomainEvent } from './events/envelope.js';\nimport type { EventStore } from './events/store.js';\nimport { StorageError } from './storage/error.js';\nimport { validateStorageId } from './storage/id.js';\n\nexport interface StorageProviderRecord extends JsonObject {\n readonly schemaVersion: 1;\n readonly name: string;\n readonly version: string;\n readonly configDigest: Sha256Digest;\n}\n\nexport interface SensitiveContentPolicy extends JsonObject {\n readonly marked: 'reject';\n readonly exact: 'reject';\n readonly freeText: 'redact-before-hash';\n}\n\nexport interface RunStoragePolicy extends JsonObject {\n readonly schemaVersion: 1;\n readonly maxEventPayloadBytes: number;\n readonly maxAppendBatchBytes: number;\n readonly maxArtifactBytes: number;\n readonly maxTotalArtifactBytesPerRun: number;\n readonly retention: 'until-run-delete';\n readonly sensitiveContent: SensitiveContentPolicy;\n}\n\nexport interface RunStorageRecord extends JsonObject {\n readonly schemaVersion: 1;\n readonly namespace: string;\n readonly eventStore: StorageProviderRecord;\n readonly artifactStore: StorageProviderRecord;\n readonly policy: RunStoragePolicy;\n}\n\nexport interface RunDefinition extends JsonObject {\n readonly schemaVersion: 1;\n readonly runId: string;\n readonly graphDefinition: CompiledGraphDefinition;\n readonly resolvedPlan: ArtifactReference<'resolved-plan'>;\n readonly resolvedInputs: RunBrief;\n readonly storage: RunStorageRecord;\n readonly workspaceBinding: JsonObject | null;\n readonly hostBinding: ArtifactReference<'host-binding'> | null;\n}\n\nexport interface RunStartedPayload extends JsonObject {\n readonly definition: RunDefinition;\n}\n\nexport type NewRunStartedEvent = NewDomainEvent<\n 'graph:run-started',\n 1,\n RunStartedPayload\n>;\n\nexport type RunStartRecord = DomainEventEnvelope<\n 'graph:run-started',\n 1,\n RunStartedPayload\n>;\n\nexport interface RunStorageBinding {\n readonly record: RunStorageRecord;\n readonly eventStore: EventStore;\n readonly artifactStore: ArtifactStore;\n readonly knownSecrets: readonly string[];\n}\n\ntype RecordValue = Readonly<Record<string, JsonValue>>;\n\nconst DIGEST = /^sha256:[0-9a-f]{64}$/u;\nconst CONTROL_CHARACTER = /[\\u0000-\\u001f\\u007f]/u;\n\nfunction fail(path: string, message: string): never {\n throw new StorageError('INVALID_STORED_VALUE', message, { path });\n}\n\nfunction json(value: unknown, path: string): JsonValue {\n try {\n return cloneFrozenJson(value as JsonValue);\n } catch (error) {\n if (!(error instanceof JsonValueError)) throw error;\n fail(`${path}${error.path}`, error.message);\n }\n}\n\nfunction record(value: unknown, path: string, label: string): RecordValue {\n const parsed = json(value, path);\n if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {\n fail(path, `${label} must be an object.`);\n }\n return parsed as RecordValue;\n}\n\nfunction exactFields(\n value: RecordValue,\n fields: readonly string[],\n path: string,\n): void {\n const expected = new Set(fields);\n for (const field of fields) {\n if (!Object.hasOwn(value, field)) {\n fail(`${path}/${field}`, `Required field \"${field}\" is missing.`);\n }\n }\n for (const field of Object.keys(value)) {\n if (!expected.has(field)) {\n fail(`${path}/${field}`, `Unknown field \"${field}\" is not allowed.`);\n }\n }\n}\n\nfunction text(value: unknown, path: string, label: string): string {\n if (\n typeof value !== 'string'\n || value.length === 0\n || value !== value.trim()\n || CONTROL_CHARACTER.test(value)\n ) {\n fail(path, `${label} must be a non-empty trimmed string without control characters.`);\n }\n return value;\n}\n\nfunction version(value: unknown, path: string, expected = 1): number {\n if (!Number.isSafeInteger(value) || value !== expected) {\n fail(path, `Version must be ${expected}.`);\n }\n return value as number;\n}\n\nfunction positiveLimit(value: unknown, path: string): number {\n if (!Number.isSafeInteger(value) || (value as number) < 1) {\n fail(path, 'A storage limit must be a positive safe integer.');\n }\n return value as number;\n}\n\nfunction digest(value: unknown, path: string): Sha256Digest {\n if (typeof value !== 'string' || !DIGEST.test(value)) {\n fail(path, 'Digest must be lowercase sha256 followed by 64 hexadecimal characters.');\n }\n return value as Sha256Digest;\n}\n\nfunction validateProvider(value: unknown, path: string): StorageProviderRecord {\n const item = record(value, path, 'Storage provider');\n exactFields(item, ['schemaVersion', 'name', 'version', 'configDigest'], path);\n return Object.freeze({\n schemaVersion: version(item.schemaVersion, `${path}/schemaVersion`) as 1,\n name: text(item.name, `${path}/name`, 'Provider name'),\n version: text(item.version, `${path}/version`, 'Provider version'),\n configDigest: digest(item.configDigest, `${path}/configDigest`),\n });\n}\n\nfunction validatePolicy(value: unknown, path: string): RunStoragePolicy {\n const item = record(value, path, 'Storage policy');\n exactFields(item, [\n 'schemaVersion',\n 'maxEventPayloadBytes',\n 'maxAppendBatchBytes',\n 'maxArtifactBytes',\n 'maxTotalArtifactBytesPerRun',\n 'retention',\n 'sensitiveContent',\n ], path);\n\n const sensitive = record(\n item.sensitiveContent,\n `${path}/sensitiveContent`,\n 'Sensitive-content policy',\n );\n exactFields(sensitive, ['marked', 'exact', 'freeText'], `${path}/sensitiveContent`);\n if (sensitive.marked !== 'reject') {\n fail(`${path}/sensitiveContent/marked`, 'Marked-sensitive content must be rejected.');\n }\n if (sensitive.exact !== 'reject') {\n fail(`${path}/sensitiveContent/exact`, 'Exact content must reject known secrets.');\n }\n if (sensitive.freeText !== 'redact-before-hash') {\n fail(`${path}/sensitiveContent/freeText`, 'Free text must redact before hashing.');\n }\n\n const maxEventPayloadBytes = positiveLimit(\n item.maxEventPayloadBytes,\n `${path}/maxEventPayloadBytes`,\n );\n const maxAppendBatchBytes = positiveLimit(\n item.maxAppendBatchBytes,\n `${path}/maxAppendBatchBytes`,\n );\n const maxArtifactBytes = positiveLimit(\n item.maxArtifactBytes,\n `${path}/maxArtifactBytes`,\n );\n const maxTotalArtifactBytesPerRun = positiveLimit(\n item.maxTotalArtifactBytesPerRun,\n `${path}/maxTotalArtifactBytesPerRun`,\n );\n if (maxAppendBatchBytes < maxEventPayloadBytes) {\n fail(path, 'The append-batch limit cannot be smaller than the event-payload limit.');\n }\n if (maxTotalArtifactBytesPerRun < maxArtifactBytes) {\n fail(path, 'The per-run artifact limit cannot be smaller than the single-artifact limit.');\n }\n if (item.retention !== 'until-run-delete') {\n fail(`${path}/retention`, 'D3 artifacts must be retained until their run is deleted.');\n }\n\n return Object.freeze({\n schemaVersion: version(item.schemaVersion, `${path}/schemaVersion`) as 1,\n maxEventPayloadBytes,\n maxAppendBatchBytes,\n maxArtifactBytes,\n maxTotalArtifactBytesPerRun,\n retention: 'until-run-delete',\n sensitiveContent: Object.freeze({\n marked: 'reject',\n exact: 'reject',\n freeText: 'redact-before-hash',\n }),\n });\n}\n\nexport function validateRunStoragePolicy(value: unknown): RunStoragePolicy {\n return validatePolicy(value, '');\n}\n\nexport function validateRunStorageRecord(value: unknown): RunStorageRecord {\n const item = record(value, '', 'Run storage record');\n exactFields(item, [\n 'schemaVersion',\n 'namespace',\n 'eventStore',\n 'artifactStore',\n 'policy',\n ], '');\n\n return Object.freeze({\n schemaVersion: version(item.schemaVersion, '/schemaVersion') as 1,\n namespace: validateStorageId(item.namespace, '/namespace'),\n eventStore: validateProvider(item.eventStore, '/eventStore'),\n artifactStore: validateProvider(item.artifactStore, '/artifactStore'),\n policy: validatePolicy(item.policy, '/policy'),\n });\n}\n\nfunction validateCompiledDefinition(value: unknown): CompiledGraphDefinition {\n const item = record(value, '/graphDefinition', 'Compiled graph definition');\n exactFields(item, ['value', 'canonicalJson', 'digest'], '/graphDefinition');\n\n let rebuilt: CompiledGraphDefinition;\n try {\n rebuilt = compileGraphDefinition(item.value as GraphDefinition);\n } catch (error) {\n fail('/graphDefinition/value', error instanceof Error ? error.message : String(error));\n }\n\n if (item.canonicalJson !== rebuilt.canonicalJson) {\n fail('/graphDefinition/canonicalJson', 'Graph definition bytes do not match its value.');\n }\n if (item.digest !== rebuilt.digest) {\n fail('/graphDefinition/digest', 'Graph definition digest does not match its value.');\n }\n return rebuilt;\n}\n\nfunction artifactReference<Purpose extends string>(\n value: unknown,\n path: string,\n purpose: Purpose,\n): ArtifactReference<Purpose> {\n let reference: ArtifactReference;\n try {\n reference = validateArtifactReference(value);\n } catch (error) {\n if (!(error instanceof StorageError)) throw error;\n fail(path, error.message);\n }\n if (reference.purpose !== purpose) {\n fail(`${path}/purpose`, `Artifact purpose must be \"${purpose}\".`);\n }\n return reference as ArtifactReference<Purpose>;\n}\n\nexport function validateRunDefinition(value: unknown): RunDefinition {\n const item = record(value, '', 'Run definition');\n exactFields(item, [\n 'schemaVersion',\n 'runId',\n 'graphDefinition',\n 'resolvedPlan',\n 'resolvedInputs',\n 'storage',\n 'workspaceBinding',\n 'hostBinding',\n ], '');\n\n const resolvedPlan = artifactReference(\n item.resolvedPlan,\n '/resolvedPlan',\n 'resolved-plan',\n );\n if (resolvedPlan.mediaType !== 'application/json') {\n fail('/resolvedPlan/mediaType', 'The resolved plan must use application/json.');\n }\n\n const resolvedInputs = json(item.resolvedInputs, '/resolvedInputs');\n if (\n resolvedInputs === null\n || typeof resolvedInputs !== 'object'\n || Array.isArray(resolvedInputs)\n ) {\n fail('/resolvedInputs', 'Resolved inputs must be an object.');\n }\n\n const workspaceBinding = item.workspaceBinding === null\n ? null\n : record(item.workspaceBinding, '/workspaceBinding', 'Workspace binding');\n const hostBinding = item.hostBinding === null\n ? null\n : artifactReference(item.hostBinding, '/hostBinding', 'host-binding');\n\n return Object.freeze({\n schemaVersion: version(item.schemaVersion, '/schemaVersion') as 1,\n runId: validateStorageId(item.runId, '/runId'),\n graphDefinition: validateCompiledDefinition(item.graphDefinition),\n resolvedPlan,\n resolvedInputs: resolvedInputs as RunBrief,\n storage: validateRunStorageRecord(item.storage),\n workspaceBinding: workspaceBinding as JsonObject | null,\n hostBinding,\n });\n}\n\nexport function validateRunStartRecord(value: unknown): RunStartRecord {\n const envelope = validateDomainEventEnvelope(value);\n if (envelope.type !== 'graph:run-started' || envelope.version !== 1) {\n fail('/type', 'The run-start record must be graph:run-started version 1.');\n }\n if (envelope.revision !== 1) {\n fail('/revision', 'The run-start record must be the first stream event.');\n }\n\n const payload = record(envelope.payload, '/payload', 'Run-start payload');\n exactFields(payload, ['definition'], '/payload');\n const definition = validateRunDefinition(payload.definition);\n if (envelope.streamId !== definition.runId) {\n fail('/streamId', 'The run-start stream must match the run id.');\n }\n if (envelope.correlationId !== definition.runId) {\n fail('/correlationId', 'The run-start correlation id must match the run id.');\n }\n if (envelope.causationId !== null) {\n fail('/causationId', 'The run-start event cannot have a cause.');\n }\n\n return cloneFrozenJson({\n ...envelope,\n type: 'graph:run-started',\n version: 1,\n payload: { definition },\n }) as RunStartRecord;\n}\n\nexport const runDefinitionSupport = Object.freeze({\n fail,\n json,\n record,\n text,\n digest,\n validateCompiledDefinition,\n});\n"]}