owlrunkit 0.15.0 → 0.16.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 (76) hide show
  1. package/CHANGELOG.md +100 -0
  2. package/README.md +274 -66
  3. package/integrations/codex/skills/owlcoda-runkit/SKILL.md +223 -117
  4. package/integrations/codex/skills/owlcoda-runkit/assets/templates/config.json +3 -3
  5. package/integrations/codex/skills/owlcoda-runkit/assets/templates/ready-for-commit-request.json +2 -2
  6. package/package.json +2 -2
  7. package/packages/attest/distribution-manifest-v1.json +10 -0
  8. package/packages/attest/src/quick.mjs +10 -0
  9. package/registry-release-policy-v1.json +8 -2
  10. package/sbom.spdx.json +5 -5
  11. package/scripts/runkit-contract/assurance-router.mjs +119 -0
  12. package/scripts/runkit-contract/core-contract.mjs +250 -115
  13. package/scripts/runkit-contract/core-successor.mjs +2043 -0
  14. package/scripts/runkit-contract/deployment-workflow.mjs +2040 -0
  15. package/scripts/runkit-contract/finalize.mjs +242 -21
  16. package/scripts/runkit-contract/fleet-discovery.mjs +456 -0
  17. package/scripts/runkit-contract/formal-workflow.mjs +850 -0
  18. package/scripts/runkit-contract/human-status.mjs +553 -0
  19. package/scripts/runkit-contract/inspect-presentation.mjs +25 -8
  20. package/scripts/runkit-contract/install-codex-skill.mjs +73 -30
  21. package/scripts/runkit-contract/lease-lifecycle.mjs +8 -2
  22. package/scripts/runkit-contract/lifecycle-orchestration.mjs +135 -12
  23. package/scripts/runkit-contract/onboarding-doctor.mjs +43 -90
  24. package/scripts/runkit-contract/owner-authority-trust.mjs +230 -0
  25. package/scripts/runkit-contract/owner-deployment-decision.mjs +385 -0
  26. package/scripts/runkit-contract/profile-onboarding.mjs +841 -13
  27. package/scripts/runkit-contract/project-cli-resolver.mjs +701 -0
  28. package/scripts/runkit-contract/project-control-parser.mjs +830 -0
  29. package/scripts/runkit-contract/project-control-state.mjs +28 -0
  30. package/scripts/runkit-contract/provenance-common.mjs +19 -2
  31. package/scripts/runkit-contract/ready-for-commit.mjs +330 -18
  32. package/scripts/runkit-contract/remote-deployment.mjs +1596 -0
  33. package/scripts/runkit-contract/remote-process-adapter.mjs +177 -0
  34. package/scripts/runkit-contract/runkit-bootstrap.mjs +131 -0
  35. package/scripts/runkit-contract/runkit-cli.mjs +1097 -21
  36. package/scripts/runkit-contract/schemas/assurance-route-v1.schema.json +26 -0
  37. package/scripts/runkit-contract/schemas/core-successor-batch-receipt-v1.schema.json +126 -0
  38. package/scripts/runkit-contract/schemas/core-successor-plan-v1.schema.json +155 -0
  39. package/scripts/runkit-contract/schemas/core-successor-project-success-receipt-v1.schema.json +72 -0
  40. package/scripts/runkit-contract/schemas/deployment-execute-request-v1.schema.json +63 -0
  41. package/scripts/runkit-contract/schemas/deployment-lineage-v1.schema.json +292 -0
  42. package/scripts/runkit-contract/schemas/deployment-prepare-receipt-v1.schema.json +140 -0
  43. package/scripts/runkit-contract/schemas/fleet-discovery-v1.schema.json +31 -0
  44. package/scripts/runkit-contract/schemas/fleet-manifest-v1.schema.json +20 -0
  45. package/scripts/runkit-contract/schemas/fleet-root-registry-v1.schema.json +34 -0
  46. package/scripts/runkit-contract/schemas/human-status-v1.schema.json +102 -0
  47. package/scripts/runkit-contract/schemas/owner-authority-trust-v1.schema.json +66 -0
  48. package/scripts/runkit-contract/schemas/owner-deployment-authority-v1.schema.json +46 -0
  49. package/scripts/runkit-contract/schemas/owner-deployment-authority-v2.schema.json +94 -0
  50. package/scripts/runkit-contract/schemas/owner-deployment-decision-v1.schema.json +102 -0
  51. package/scripts/runkit-contract/schemas/owner-migration-authority-v1.schema.json +33 -0
  52. package/scripts/runkit-contract/schemas/owner-migration-authority-v2.schema.json +67 -0
  53. package/scripts/runkit-contract/schemas/profile-apply-receipt-v1.schema.json +32 -0
  54. package/scripts/runkit-contract/schemas/profile-detection-v2.schema.json +145 -0
  55. package/scripts/runkit-contract/schemas/ready-for-commit-v2.schema.json +37 -0
  56. package/scripts/runkit-contract/schemas/remote-deployment-manifest-v1.schema.json +379 -0
  57. package/scripts/runkit-contract/schemas/remote-deployment-result-v1.schema.json +153 -0
  58. package/scripts/runkit-contract/schemas/remote-deployment-stage-journal-v1.schema.json +183 -0
  59. package/scripts/runkit-contract/schemas/remote-target-v1.schema.json +32 -0
  60. package/scripts/runkit-contract/schemas/source-candidate-v2.schema.json +152 -0
  61. package/scripts/runkit-contract/schemas/verification-receipt-v2.schema.json +13 -0
  62. package/scripts/runkit-contract/snapshot.mjs +1 -1
  63. package/scripts/runkit-contract/source-candidate.mjs +1382 -0
  64. package/scripts/runkit-contract/ssh-remote-adapter.mjs +1184 -0
  65. package/scripts/runkit-contract/sync-core016-release-identity.mjs +161 -0
  66. package/scripts/runkit-contract/templates/assurance-request.json +13 -0
  67. package/scripts/runkit-contract/templates/core-successor-owner-authority.json +15 -0
  68. package/scripts/runkit-contract/templates/deployment-execute-request.json +39 -0
  69. package/scripts/runkit-contract/templates/deployment-owner-authority.json +23 -0
  70. package/scripts/runkit-contract/templates/deployment-owner-decision.json +26 -0
  71. package/scripts/runkit-contract/templates/fleet-manifest.json +8 -0
  72. package/scripts/runkit-contract/templates/fleet-root-registry.json +8 -0
  73. package/scripts/runkit-contract/templates/owner-authority-trust.json +16 -0
  74. package/scripts/runkit-contract/templates/ready-for-commit-request.json +2 -2
  75. package/scripts/runkit-contract/templates/remote-deployment-manifest.json +108 -0
  76. package/scripts/runkit-contract/verification-receipt-gate.mjs +28 -0
@@ -0,0 +1,2040 @@
1
+ import {
2
+ appendFileSync,
3
+ existsSync,
4
+ lstatSync,
5
+ mkdirSync,
6
+ readFileSync,
7
+ readdirSync,
8
+ realpathSync,
9
+ rmSync,
10
+ } from "node:fs";
11
+ import path from "node:path";
12
+
13
+ import {
14
+ assertAllowedKeys,
15
+ relativeToWorkspace,
16
+ safeIdentifier,
17
+ safeRelativePath,
18
+ sha256,
19
+ writeJsonExclusiveAtomically,
20
+ } from "./provenance-common.mjs";
21
+ import {
22
+ RUNTIME_ROOT,
23
+ acceptedCloseoutVerificationIssues,
24
+ createCoreArtifact,
25
+ currentCoreIdentity,
26
+ validateCoreArtifact,
27
+ validateExecutionPin,
28
+ } from "./core-contract.mjs";
29
+ import { collapseByteIdenticalDeliveryCandidates } from "./delivery-selection.mjs";
30
+ import {
31
+ acquireLeaseWithinControlTransaction,
32
+ listLeaseArtifacts,
33
+ releaseLeaseWithinControlTransaction,
34
+ withControlTransaction,
35
+ } from "./lease-lifecycle.mjs";
36
+ import {
37
+ ownerAuthorityArtifactSha256V1,
38
+ verifyTrustedOwnerAuthorityV1,
39
+ } from "./owner-authority-trust.mjs";
40
+ import {
41
+ compileOwnerDeploymentDecisionV1,
42
+ createDeploymentSupersessionStatusV1,
43
+ ownerDeploymentDecisionBindingV1,
44
+ validateOwnerDeploymentDecisionBindingV1,
45
+ validateOwnerDeploymentDecisionV1,
46
+ } from "./owner-deployment-decision.mjs";
47
+ import {
48
+ canonicalRemoteDeploymentIntentSha256,
49
+ validateRemoteTarget,
50
+ } from "./remote-deployment.mjs";
51
+ import {
52
+ buildResourcePreflight,
53
+ summarizeResourcePreflight,
54
+ } from "./resource-preflight.mjs";
55
+ import { verifyDeliveryPacket } from "./source-fingerprint.mjs";
56
+ import { verifySourceCandidateV2 } from "./source-candidate.mjs";
57
+
58
+ const SHA256 = /^[a-f0-9]{64}$/;
59
+ const SHA256_REF = /^sha256:[a-f0-9]{64}$/;
60
+ const PREPARE_INPUT_KEYS = [
61
+ "prepareRunId",
62
+ "prepareGoal",
63
+ "trustedAcceptedCloseout",
64
+ "deliveryPacket",
65
+ "sourceArtifact",
66
+ "artifact",
67
+ "ownerDecision",
68
+ ];
69
+ const GOAL_KEYS = ["path", "sha256"];
70
+ const CLOSEOUT_KEYS = [
71
+ "trusted",
72
+ "decision",
73
+ "runId",
74
+ "path",
75
+ "sha256",
76
+ "gateInputSha256",
77
+ "sourceFingerprint",
78
+ "sourceArtifact",
79
+ "authorizationGranted",
80
+ ];
81
+ const PACKET_KEYS = ["runId", "path", "sha256", "sourceFingerprint"];
82
+ const SOURCE_ARTIFACT_KEYS = [
83
+ "kind",
84
+ "runId",
85
+ "path",
86
+ "sha256",
87
+ "sourceFingerprint",
88
+ ];
89
+ const ARTIFACT_KEYS = ["path", "sha256", "size", "mediaType"];
90
+ const EXECUTE_REQUEST_KEYS = [
91
+ "schemaVersion",
92
+ "executeRunId",
93
+ "executeGoal",
94
+ "prepareReceiptSha256",
95
+ "target",
96
+ "ownerAuthority",
97
+ "ownerDecision",
98
+ "ownerDecisionSnapshot",
99
+ "workItemId",
100
+ "profileId",
101
+ "resourcePreflight",
102
+ "deploy",
103
+ "destructive",
104
+ ];
105
+ const AUTHORITY_KEYS = [
106
+ "authorityId",
107
+ "path",
108
+ "sha256",
109
+ "signerKeyId",
110
+ "trustStoreSha256",
111
+ "remoteManifestFileSha256",
112
+ "remoteDeploymentIntentSha256",
113
+ "targetSha256",
114
+ "artifactSha256",
115
+ "ownerDecisionId",
116
+ "ownerDecisionSha256",
117
+ "permissions",
118
+ ];
119
+ const AUTHORITY_DESCRIPTOR_KEYS = ["path", "sha256"];
120
+ const OWNER_DEPLOYMENT_AUTHORITY_KEYS = [
121
+ "schemaVersion",
122
+ "authorityId",
123
+ "decision",
124
+ "scope",
125
+ "executeRunId",
126
+ "prepareReceiptSha256",
127
+ "targetSha256",
128
+ "artifactSha256",
129
+ "remoteManifestFileSha256",
130
+ "remoteDeploymentIntentSha256",
131
+ "ownerDecisionId",
132
+ "ownerDecisionSha256",
133
+ "signerKeyId",
134
+ "signatureAlgorithm",
135
+ "permissions",
136
+ "authorizationGranted",
137
+ "authoritySha256",
138
+ "signature",
139
+ ];
140
+ const PERMISSION_KEYS = ["deploy", "destructive"];
141
+ const OWNER_DECISION_DESCRIPTOR_KEYS = ["path", "sha256"];
142
+
143
+ function canonicalJson(value) {
144
+ if (Array.isArray(value)) return `[${value.map(canonicalJson).join(",")}]`;
145
+ if (value && typeof value === "object") {
146
+ return `{${Object.keys(value).sort()
147
+ .map(key => `${JSON.stringify(key)}:${canonicalJson(value[key])}`)
148
+ .join(",")}}`;
149
+ }
150
+ const encoded = JSON.stringify(value);
151
+ if (encoded === undefined) throw new Error("Deployment workflow value is not canonical JSON.");
152
+ return encoded;
153
+ }
154
+
155
+ function hashObject(value) {
156
+ return sha256(Buffer.from(canonicalJson(value), "utf8"));
157
+ }
158
+
159
+ function canonicalWorkspaceRoot(workspaceRoot) {
160
+ if (typeof workspaceRoot !== "string" || workspaceRoot.length === 0) {
161
+ throw new Error("Deployment prepare workspaceRoot is required.");
162
+ }
163
+ const requested = path.resolve(workspaceRoot);
164
+ const stat = lstatSync(requested);
165
+ if (stat.isSymbolicLink() || !stat.isDirectory()) {
166
+ throw new Error("Deployment prepare workspace must be a regular directory.");
167
+ }
168
+ return realpathSync(requested);
169
+ }
170
+
171
+ function within(root, candidate) {
172
+ const relative = path.relative(root, candidate);
173
+ return relative === ""
174
+ || (
175
+ relative !== ".."
176
+ && !relative.startsWith(`..${path.sep}`)
177
+ && !path.isAbsolute(relative)
178
+ );
179
+ }
180
+
181
+ function readRegularFile(root, relativePath, label) {
182
+ const safePath = safeRelativePath(relativePath, `${label} path`);
183
+ const absolutePath = path.resolve(root, safePath);
184
+ if (!within(root, absolutePath)) throw new Error(`${label} escapes the workspace.`);
185
+ let current = root;
186
+ for (const segment of safePath.split("/")) {
187
+ current = path.join(current, segment);
188
+ const stat = lstatSync(current);
189
+ if (stat.isSymbolicLink()) throw new Error(`${label} must not traverse a symlink.`);
190
+ }
191
+ const stat = lstatSync(absolutePath);
192
+ if (!stat.isFile() || realpathSync(absolutePath) !== absolutePath) {
193
+ throw new Error(`${label} must be a regular file.`);
194
+ }
195
+ return {
196
+ absolutePath,
197
+ relativePath: safePath,
198
+ bytes: readFileSync(absolutePath),
199
+ size: stat.size,
200
+ };
201
+ }
202
+
203
+ function readJsonFile(root, relativePath, label) {
204
+ const file = readRegularFile(root, relativePath, label);
205
+ try {
206
+ return { ...file, value: JSON.parse(file.bytes.toString("utf8")) };
207
+ } catch {
208
+ throw new Error(`${label} must contain valid JSON.`);
209
+ }
210
+ }
211
+
212
+ function loadOwnerDeploymentDecision(root, descriptorValue) {
213
+ assertAllowedKeys(
214
+ descriptorValue,
215
+ "Owner deployment decision descriptor",
216
+ OWNER_DECISION_DESCRIPTOR_KEYS,
217
+ );
218
+ const decisionPath = safeRelativePath(
219
+ descriptorValue.path,
220
+ "Owner deployment decision path",
221
+ );
222
+ if (
223
+ decisionPath === RUNTIME_ROOT
224
+ || decisionPath.startsWith(`${RUNTIME_ROOT}/`)
225
+ ) {
226
+ throw new Error(
227
+ "Owner deployment decision must be independent from RunKit control state.",
228
+ );
229
+ }
230
+ const file = readJsonFile(root, decisionPath, "Owner deployment decision");
231
+ const fileSha256 = assertHash(
232
+ descriptorValue.sha256,
233
+ "Owner deployment decision file",
234
+ );
235
+ if (sha256(file.bytes) !== fileSha256) {
236
+ throw new Error("owner_decision_file_hash_mismatch");
237
+ }
238
+ return {
239
+ path: decisionPath,
240
+ sha256: fileSha256,
241
+ value: validateOwnerDeploymentDecisionV1(file.value),
242
+ };
243
+ }
244
+
245
+ export function inspectDeploymentOwnerDecisionStateV1({
246
+ workspaceRoot,
247
+ descriptor,
248
+ expectedDecisionSha256,
249
+ }) {
250
+ const root = canonicalWorkspaceRoot(workspaceRoot);
251
+ const decisionPath = safeRelativePath(
252
+ descriptor?.path,
253
+ "Owner deployment decision path",
254
+ );
255
+ const file = readJsonFile(root, decisionPath, "Owner deployment decision");
256
+ const current = validateOwnerDeploymentDecisionV1(file.value);
257
+ const expectedFileSha256 = assertHash(
258
+ descriptor?.sha256,
259
+ "Owner deployment decision file",
260
+ );
261
+ const actualFileSha256 = sha256(file.bytes);
262
+ if (
263
+ actualFileSha256 === expectedFileSha256
264
+ && current.decisionSha256 === expectedDecisionSha256
265
+ ) {
266
+ return {
267
+ status: "current",
268
+ decision: current,
269
+ fileSha256: actualFileSha256,
270
+ };
271
+ }
272
+ if (current.supersedesDecisionSha256 === expectedDecisionSha256) {
273
+ return {
274
+ status: "superseded",
275
+ decision: current,
276
+ fileSha256: actualFileSha256,
277
+ };
278
+ }
279
+ throw new Error("owner_decision_file_hash_mismatch");
280
+ }
281
+
282
+ function trustedAcceptedCloseout(root, runId) {
283
+ const executionRoot = `${RUNTIME_ROOT}/executions/${runId}`;
284
+ const closeout = readJsonFile(
285
+ root,
286
+ `${executionRoot}/closeout-receipt.json`,
287
+ "Deployment prepare closeout",
288
+ );
289
+ const pin = readJsonFile(
290
+ root,
291
+ `${executionRoot}/engine-pin.json`,
292
+ "Deployment prepare engine pin",
293
+ );
294
+ const gate = validateCoreArtifact(closeout.value.artifact);
295
+ const payload = closeout.value.artifact?.payload;
296
+ const issues = [
297
+ ...gate.issues,
298
+ ...(gate.valid
299
+ && closeout.value.acceptanceSha256 !== gate.acceptanceSha256
300
+ ? ["closeout acceptanceSha256 mismatch"]
301
+ : []),
302
+ ...(gate.valid
303
+ && closeout.value.artifactSha256 !== gate.artifactSha256
304
+ ? ["closeout artifactSha256 mismatch"]
305
+ : []),
306
+ ...(gate.valid ? acceptedCloseoutVerificationIssues(closeout.value.artifact) : []),
307
+ ...(gate.valid
308
+ && validateExecutionPin({
309
+ expected: pin.value,
310
+ actual: closeout.value.artifact.core,
311
+ }).status !== "valid"
312
+ ? ["closeout engine pin mismatch"]
313
+ : []),
314
+ ];
315
+ if (
316
+ issues.length > 0
317
+ || payload?.runId !== runId
318
+ || payload?.decision !== "accepted"
319
+ || payload?.authorizationGranted !== false
320
+ ) {
321
+ throw new Error(
322
+ `Deployment prepare requires a trusted accepted closeout: ${issues.join("; ")}`,
323
+ );
324
+ }
325
+ return {
326
+ trusted: true,
327
+ decision: "accepted",
328
+ runId,
329
+ path: closeout.relativePath,
330
+ sha256: sha256(closeout.bytes),
331
+ gateInputSha256: payload.verification.gateInputSha256,
332
+ sourceFingerprint: payload.verification.sourceFingerprint,
333
+ ...(payload.verification.sourceArtifact === undefined
334
+ ? {}
335
+ : {
336
+ sourceArtifact: structuredClone(
337
+ payload.verification.sourceArtifact,
338
+ ),
339
+ }),
340
+ authorizationGranted: false,
341
+ };
342
+ }
343
+
344
+ function selectDeliveryPacket(root, runId, sourceFingerprint) {
345
+ const directoryRelative =
346
+ `${RUNTIME_ROOT}/executions/${runId}/delivery-packets`;
347
+ const directory = path.resolve(root, directoryRelative);
348
+ const directoryStat = lstatSync(directory);
349
+ if (
350
+ directoryStat.isSymbolicLink()
351
+ || !directoryStat.isDirectory()
352
+ || realpathSync(directory) !== directory
353
+ ) {
354
+ throw new Error("Deployment prepare delivery packet directory is invalid.");
355
+ }
356
+ const candidates = [];
357
+ for (const entry of readdirSync(directory, { withFileTypes: true })
358
+ .sort((left, right) => left.name.localeCompare(right.name))) {
359
+ if (!entry.isFile() || entry.isSymbolicLink() || !entry.name.endsWith(".json")) {
360
+ throw new Error("Deployment prepare delivery packet directory contains an unsafe entry.");
361
+ }
362
+ const relativePath = `${directoryRelative}/${entry.name}`;
363
+ const file = readJsonFile(root, relativePath, "Deployment prepare delivery packet");
364
+ const gate = verifyDeliveryPacket({
365
+ workspaceRoot: root,
366
+ packet: file.value,
367
+ });
368
+ if (
369
+ file.value.runId === runId
370
+ && gate.status === "valid"
371
+ && gate.recomputedFingerprint === sourceFingerprint
372
+ ) {
373
+ candidates.push({
374
+ path: file.absolutePath,
375
+ relativePath,
376
+ packet: file.value,
377
+ sourceFingerprint: gate.recomputedFingerprint,
378
+ });
379
+ }
380
+ }
381
+ const selected = collapseByteIdenticalDeliveryCandidates(candidates);
382
+ if (selected.length !== 1) {
383
+ throw new Error(
384
+ "Deployment prepare requires exactly one byte-distinct fresh DeliveryPacket matching the accepted closeout.",
385
+ );
386
+ }
387
+ return {
388
+ runId,
389
+ path: selected[0].relativePath,
390
+ sha256: selected[0].packetFileSha256,
391
+ sourceFingerprint,
392
+ };
393
+ }
394
+
395
+ function assertHash(value, label) {
396
+ if (typeof value !== "string" || !SHA256.test(value)) {
397
+ throw new Error(`${label} must be a lowercase SHA-256 digest.`);
398
+ }
399
+ return value;
400
+ }
401
+
402
+ function assertHashRef(value, label) {
403
+ if (typeof value !== "string" || !SHA256_REF.test(value)) {
404
+ throw new Error(`${label} must be a sha256:<lowercase digest> reference.`);
405
+ }
406
+ return value;
407
+ }
408
+
409
+ function sourceArtifactDescriptor(value, label = "Source artifact") {
410
+ assertAllowedKeys(value, label, SOURCE_ARTIFACT_KEYS);
411
+ const artifact = {
412
+ kind: value.kind,
413
+ runId: safeIdentifier(value.runId, `${label} runId`),
414
+ path: safeRelativePath(value.path, `${label} path`),
415
+ sha256: assertHash(value.sha256, label),
416
+ sourceFingerprint: assertHash(
417
+ value.sourceFingerprint,
418
+ `${label} source fingerprint`,
419
+ ),
420
+ };
421
+ if (!new Set(["delivery_packet_v1", "source_candidate_v2"])
422
+ .has(artifact.kind)) {
423
+ throw new Error(`${label} kind is invalid.`);
424
+ }
425
+ return artifact;
426
+ }
427
+
428
+ function selectSourceArtifact(root, runId, closeout) {
429
+ const artifact = sourceArtifactDescriptor(
430
+ closeout.sourceArtifact,
431
+ "Accepted closeout source artifact",
432
+ );
433
+ if (
434
+ artifact.runId !== runId
435
+ || artifact.sourceFingerprint !== closeout.sourceFingerprint
436
+ ) {
437
+ throw new Error(
438
+ "Accepted closeout source artifact does not match its run or fingerprint.",
439
+ );
440
+ }
441
+ const expectedRoot = `${RUNTIME_ROOT}/executions/${runId}/${
442
+ artifact.kind === "source_candidate_v2"
443
+ ? "source-candidates"
444
+ : "delivery-packets"
445
+ }/`;
446
+ if (!artifact.path.startsWith(expectedRoot)) {
447
+ throw new Error(
448
+ "Accepted closeout source artifact is outside its execution source directory.",
449
+ );
450
+ }
451
+ const file = readJsonFile(
452
+ root,
453
+ artifact.path,
454
+ "Accepted closeout source artifact",
455
+ );
456
+ if (sha256(file.bytes) !== artifact.sha256) {
457
+ throw new Error("Accepted closeout source artifact bytes changed.");
458
+ }
459
+ if (artifact.kind === "source_candidate_v2") {
460
+ const gate = verifySourceCandidateV2({
461
+ workspaceRoot: root,
462
+ candidatePath: artifact.path,
463
+ });
464
+ if (
465
+ file.value.schemaVersion !== "OwlCodaRunKitSourceCandidateV2"
466
+ || file.value.runId !== runId
467
+ || gate.status !== "valid"
468
+ || gate.sourceFingerprint !== artifact.sourceFingerprint
469
+ ) {
470
+ throw new Error(
471
+ "Accepted closeout SourceCandidate V2 is not current and valid.",
472
+ );
473
+ }
474
+ } else {
475
+ const gate = verifyDeliveryPacket({
476
+ workspaceRoot: root,
477
+ packet: file.value,
478
+ });
479
+ if (
480
+ file.value.runId !== runId
481
+ || gate.status !== "valid"
482
+ || gate.recomputedFingerprint !== artifact.sourceFingerprint
483
+ ) {
484
+ throw new Error(
485
+ "Accepted closeout DeliveryPacket is not current and valid.",
486
+ );
487
+ }
488
+ }
489
+ return artifact;
490
+ }
491
+
492
+ function descriptor(value, label) {
493
+ assertAllowedKeys(value, label, GOAL_KEYS);
494
+ return {
495
+ path: safeRelativePath(value.path, `${label} path`),
496
+ sha256: assertHash(value.sha256, label),
497
+ };
498
+ }
499
+
500
+ function artifactDescriptor(value) {
501
+ assertAllowedKeys(value, "Deployment artifact", ARTIFACT_KEYS);
502
+ const artifact = {
503
+ path: safeRelativePath(value.path, "Deployment artifact path"),
504
+ sha256: assertHash(value.sha256, "Deployment artifact"),
505
+ size: value.size,
506
+ mediaType: value.mediaType,
507
+ };
508
+ if (!Number.isInteger(artifact.size) || artifact.size < 0) {
509
+ throw new Error("Deployment artifact size must be a non-negative integer.");
510
+ }
511
+ if (typeof artifact.mediaType !== "string"
512
+ || !/^[A-Za-z0-9.+-]+\/[A-Za-z0-9.+-]+$/.test(artifact.mediaType)) {
513
+ throw new Error("Deployment artifact mediaType is invalid.");
514
+ }
515
+ return artifact;
516
+ }
517
+
518
+ function validatePrepareReceipt(receipt) {
519
+ if (receipt?.schemaVersion !== "OwlCodaRunKitDeploymentPrepareReceiptV1") {
520
+ throw new Error("Unsupported deployment prepare receipt schemaVersion.");
521
+ }
522
+ if (receipt.receiptSha256 !== hashObject((({ receiptSha256, ...body }) => body)(receipt))) {
523
+ throw new Error("Deployment prepare receipt hash does not match its contents.");
524
+ }
525
+ if (receipt.permissions?.deploy !== false
526
+ || receipt.permissions?.destructive !== false
527
+ || receipt.authorizationGranted !== false) {
528
+ throw new Error("Deployment prepare receipt must not grant deployment authority.");
529
+ }
530
+ const hasDeliveryPacket = receipt.deliveryPacket !== undefined;
531
+ const hasSourceArtifact = receipt.sourceArtifact !== undefined;
532
+ if (hasDeliveryPacket === hasSourceArtifact) {
533
+ throw new Error(
534
+ "Deployment prepare receipt requires exactly one sourceArtifact or legacy DeliveryPacket.",
535
+ );
536
+ }
537
+ if (
538
+ hasSourceArtifact
539
+ && sourceArtifactDescriptor(receipt.sourceArtifact).sourceFingerprint
540
+ !== receipt.closeout?.sourceFingerprint
541
+ ) {
542
+ throw new Error(
543
+ "Deployment prepare source artifact and closeout fingerprints differ.",
544
+ );
545
+ }
546
+ if (receipt.ownerDecision !== undefined) {
547
+ validateOwnerDeploymentDecisionBindingV1(receipt.ownerDecision);
548
+ }
549
+ return receipt;
550
+ }
551
+
552
+ export function createDeploymentPrepareReceipt(input) {
553
+ assertAllowedKeys(input, "Deployment prepare input", PREPARE_INPUT_KEYS);
554
+ const prepareRunId = safeIdentifier(input.prepareRunId, "prepareRunId");
555
+ const prepareGoal = descriptor(input.prepareGoal, "Prepare goal");
556
+ assertAllowedKeys(
557
+ input.trustedAcceptedCloseout,
558
+ "Trusted accepted closeout",
559
+ CLOSEOUT_KEYS,
560
+ );
561
+ const closeout = {
562
+ trusted: input.trustedAcceptedCloseout.trusted,
563
+ decision: input.trustedAcceptedCloseout.decision,
564
+ runId: safeIdentifier(input.trustedAcceptedCloseout.runId, "Closeout runId"),
565
+ path: safeRelativePath(input.trustedAcceptedCloseout.path, "Closeout path"),
566
+ sha256: assertHash(input.trustedAcceptedCloseout.sha256, "Closeout"),
567
+ gateInputSha256: assertHash(
568
+ input.trustedAcceptedCloseout.gateInputSha256,
569
+ "Closeout gate input",
570
+ ),
571
+ sourceFingerprint: assertHash(
572
+ input.trustedAcceptedCloseout.sourceFingerprint,
573
+ "Closeout source fingerprint",
574
+ ),
575
+ ...(input.trustedAcceptedCloseout.sourceArtifact === undefined
576
+ ? {}
577
+ : {
578
+ sourceArtifact: sourceArtifactDescriptor(
579
+ input.trustedAcceptedCloseout.sourceArtifact,
580
+ "Closeout source artifact",
581
+ ),
582
+ }),
583
+ authorizationGranted: input.trustedAcceptedCloseout.authorizationGranted,
584
+ };
585
+ if (closeout.trusted !== true
586
+ || closeout.decision !== "accepted"
587
+ || closeout.runId !== prepareRunId) {
588
+ throw new Error("Deployment prepare requires a trusted accepted closeout for the same run.");
589
+ }
590
+ if (closeout.authorizationGranted !== false) {
591
+ throw new Error("Trusted accepted closeout must not grant deployment authority.");
592
+ }
593
+ const hasDeliveryPacket = input.deliveryPacket !== undefined;
594
+ const hasSourceArtifact = input.sourceArtifact !== undefined;
595
+ if (hasDeliveryPacket === hasSourceArtifact) {
596
+ throw new Error(
597
+ "Deployment prepare requires exactly one sourceArtifact or legacy DeliveryPacket.",
598
+ );
599
+ }
600
+ let sourceBinding;
601
+ if (hasSourceArtifact) {
602
+ const sourceArtifact = sourceArtifactDescriptor(input.sourceArtifact);
603
+ if (
604
+ sourceArtifact.kind !== "source_candidate_v2"
605
+ || sourceArtifact.runId !== prepareRunId
606
+ || sourceArtifact.sourceFingerprint !== closeout.sourceFingerprint
607
+ || canonicalJson(sourceArtifact)
608
+ !== canonicalJson(closeout.sourceArtifact)
609
+ ) {
610
+ throw new Error(
611
+ "Deployment prepare source artifact must exactly match the accepted closeout.",
612
+ );
613
+ }
614
+ sourceBinding = { sourceArtifact };
615
+ } else {
616
+ assertAllowedKeys(
617
+ input.deliveryPacket,
618
+ "DeliveryPacket descriptor",
619
+ PACKET_KEYS,
620
+ );
621
+ const deliveryPacket = {
622
+ runId: safeIdentifier(input.deliveryPacket.runId, "DeliveryPacket runId"),
623
+ path: safeRelativePath(input.deliveryPacket.path, "DeliveryPacket path"),
624
+ sha256: assertHash(input.deliveryPacket.sha256, "DeliveryPacket"),
625
+ sourceFingerprint: assertHash(
626
+ input.deliveryPacket.sourceFingerprint,
627
+ "DeliveryPacket source fingerprint",
628
+ ),
629
+ };
630
+ if (deliveryPacket.runId !== prepareRunId) {
631
+ throw new Error("Deployment prepare DeliveryPacket must belong to the prepare run.");
632
+ }
633
+ if (deliveryPacket.sourceFingerprint !== closeout.sourceFingerprint) {
634
+ throw new Error("Deployment prepare DeliveryPacket and accepted closeout source fingerprints differ.");
635
+ }
636
+ sourceBinding = { deliveryPacket };
637
+ }
638
+ const artifact = artifactDescriptor(input.artifact);
639
+ const ownerDecision = input.ownerDecision === undefined
640
+ ? null
641
+ : validateOwnerDeploymentDecisionBindingV1(input.ownerDecision);
642
+ const body = {
643
+ schemaVersion: "OwlCodaRunKitDeploymentPrepareReceiptV1",
644
+ prepareRunId,
645
+ prepareGoal,
646
+ closeout,
647
+ ...sourceBinding,
648
+ artifact,
649
+ ...(ownerDecision === null ? {} : { ownerDecision }),
650
+ permissions: {
651
+ deploy: false,
652
+ destructive: false,
653
+ },
654
+ authorizationGranted: false,
655
+ };
656
+ return { ...body, receiptSha256: hashObject(body) };
657
+ }
658
+
659
+ export function createDeploymentPrepareReceiptFromClosedRun({
660
+ workspaceRoot,
661
+ prepareRunId,
662
+ artifactPath,
663
+ mediaType,
664
+ ownerDecision,
665
+ } = {}) {
666
+ const root = canonicalWorkspaceRoot(workspaceRoot);
667
+ const runId = safeIdentifier(prepareRunId, "prepareRunId");
668
+ const closeout = trustedAcceptedCloseout(root, runId);
669
+ const goal = readRegularFile(
670
+ root,
671
+ `${RUNTIME_ROOT}/executions/${runId}/goal-contract.json`,
672
+ "Deployment prepare goal",
673
+ );
674
+ const artifact = readRegularFile(
675
+ root,
676
+ safeRelativePath(artifactPath, "Deployment artifact path"),
677
+ "Deployment artifact",
678
+ );
679
+ return createDeploymentPrepareReceipt({
680
+ prepareRunId: runId,
681
+ prepareGoal: {
682
+ path: goal.relativePath,
683
+ sha256: sha256(goal.bytes),
684
+ },
685
+ trustedAcceptedCloseout: closeout,
686
+ ...(closeout.sourceArtifact?.kind !== "source_candidate_v2"
687
+ ? {
688
+ deliveryPacket: selectDeliveryPacket(
689
+ root,
690
+ runId,
691
+ closeout.sourceFingerprint,
692
+ ),
693
+ }
694
+ : {
695
+ sourceArtifact: selectSourceArtifact(root, runId, closeout),
696
+ }),
697
+ artifact: {
698
+ path: artifact.relativePath,
699
+ sha256: sha256(artifact.bytes),
700
+ size: artifact.size,
701
+ mediaType,
702
+ },
703
+ ...(ownerDecision === undefined
704
+ ? {}
705
+ : { ownerDecision: ownerDeploymentDecisionBindingV1(ownerDecision) }),
706
+ });
707
+ }
708
+
709
+ function deploymentChildPaths(root, runId) {
710
+ const executionRoot = path.join(root, RUNTIME_ROOT, "executions", runId);
711
+ const deploymentRoot = path.join(root, RUNTIME_ROOT, "deployments", runId);
712
+ return {
713
+ executionRoot,
714
+ deploymentRoot,
715
+ goalPath: path.join(executionRoot, "goal-contract.json"),
716
+ planPath: path.join(executionRoot, "execution-plan.json"),
717
+ pinPath: path.join(executionRoot, "engine-pin.json"),
718
+ eventsPath: path.join(executionRoot, "events.jsonl"),
719
+ profilePath: path.join(executionRoot, "deployment-profile.json"),
720
+ verificationPlanPath: path.join(
721
+ executionRoot,
722
+ "verification-plans/deployment-execute-plan.json",
723
+ ),
724
+ resourcePreflightPath: path.join(
725
+ executionRoot,
726
+ "resource-preflights/deployment-execute-preflight.json",
727
+ ),
728
+ requestPath: path.join(deploymentRoot, "execute-request.json"),
729
+ decisionSnapshotPath: path.join(
730
+ deploymentRoot,
731
+ "owner-decision-snapshot.json",
732
+ ),
733
+ lineagePath: path.join(deploymentRoot, "lineage.json"),
734
+ resultPath: path.join(deploymentRoot, "result.json"),
735
+ };
736
+ }
737
+
738
+ function childGoal({
739
+ prepareReceipt,
740
+ runId,
741
+ target,
742
+ destructive,
743
+ ownerDecision,
744
+ }) {
745
+ return {
746
+ schemaVersion: "OwlCodaRunKitGoalContractV1",
747
+ objective: "Execute one exact remote deployment from an accepted prepare receipt.",
748
+ nonGoals: [
749
+ "Change the prepared artifact.",
750
+ "Grant Git, publish, or destructive authority beyond the signed Owner decision.",
751
+ ],
752
+ authorization: {
753
+ git: false,
754
+ publish: false,
755
+ deploy: true,
756
+ destructive,
757
+ },
758
+ deployment: {
759
+ phase: "execute",
760
+ prepareRunId: prepareReceipt.prepareRunId,
761
+ prepareReceiptSha256: prepareReceipt.receiptSha256,
762
+ targetSha256: hashObject(target),
763
+ ownerDecision: ownerDeploymentDecisionBindingV1(ownerDecision),
764
+ },
765
+ authorizationGranted: false,
766
+ };
767
+ }
768
+
769
+ function deploymentProfile(artifactPath) {
770
+ return {
771
+ schemaVersion: "OwlCodaRunKitProfilesV1",
772
+ profiles: [{
773
+ id: "deployment-execute",
774
+ paths: [artifactPath],
775
+ role: "primary",
776
+ primary: true,
777
+ requiresProfileIds: [],
778
+ commands: [],
779
+ }],
780
+ };
781
+ }
782
+
783
+ function deploymentVerificationPlan({
784
+ runId,
785
+ profileSha256,
786
+ prepareReceipt,
787
+ }) {
788
+ return {
789
+ schemaVersion: "OwlCodaRunKitVerificationPlanV1",
790
+ runId,
791
+ planId: "deployment-execute-plan",
792
+ status: "ready_to_finalize",
793
+ drift: {
794
+ leasedSourceDrift: [],
795
+ declaredDependencyDrift: [],
796
+ unrelatedDirtyTreeDrift: [],
797
+ globalGateFailures: [],
798
+ },
799
+ profileImpact: {
800
+ decision: "targeted_profiles",
801
+ primaryProfileId: "deployment-execute",
802
+ directProfileIds: ["deployment-execute"],
803
+ transitiveProfileIds: [],
804
+ supportingProfileIds: [],
805
+ selectedProfileIds: ["deployment-execute"],
806
+ uncoveredPaths: [],
807
+ warnings: [],
808
+ },
809
+ evidence: {
810
+ reusableReceiptIds: [],
811
+ invalidatedReceipts: [],
812
+ },
813
+ commands: {
814
+ requiredCommandIds: [],
815
+ reusedCommandIds: [],
816
+ pendingCommandIds: [],
817
+ unmappedProfileIds: [],
818
+ pendingCommands: [],
819
+ },
820
+ acceptance: {
821
+ blocked: false,
822
+ reasons: [],
823
+ },
824
+ authorizationGranted: false,
825
+ verificationContextFingerprint: hashObject({
826
+ runId,
827
+ prepareReceiptSha256: prepareReceipt.receiptSha256,
828
+ profileSha256,
829
+ }),
830
+ };
831
+ }
832
+
833
+ function deploymentResourcePreflight({
834
+ runId,
835
+ verificationPlan,
836
+ verificationPlanPath,
837
+ verificationPlanSha256,
838
+ }) {
839
+ const request = {
840
+ schemaVersion: "OwlCodaRunKitResourcePreflightRequestV1",
841
+ preflightId: "deployment-execute-preflight",
842
+ verificationPlanPath,
843
+ verificationPlanSha256,
844
+ policy: {
845
+ gateMode: "model_optional",
846
+ maxObservationAgeMs: 60_000,
847
+ unknownHandling: {
848
+ availability: "fail_closed",
849
+ quota: "fail_closed",
850
+ resetTime: "fail_closed",
851
+ pricing: "fail_closed",
852
+ },
853
+ limits: {
854
+ maxCalls: 0,
855
+ maxTotalTokens: 0,
856
+ maxElapsedMs: 0,
857
+ maxCostUsd: 0,
858
+ },
859
+ },
860
+ observations: [{
861
+ providerId: "local",
862
+ modelId: "none",
863
+ adapter: {
864
+ id: "builtin-remote-deployment",
865
+ kind: "project_declared",
866
+ evidenceRef: "local:deployment",
867
+ evidenceSha256: hashObject({
868
+ runId,
869
+ verificationPlanSha256,
870
+ }),
871
+ observedAt: new Date().toISOString(),
872
+ },
873
+ availability: { status: "available" },
874
+ quota: {
875
+ remainingCalls: { status: "known", value: 0 },
876
+ remainingTokens: { status: "known", value: 0 },
877
+ resetAt: { status: "known", value: "9999-12-31T23:59:59.999Z" },
878
+ },
879
+ pricing: {
880
+ status: "known",
881
+ currency: "USD",
882
+ inputPerMillion: 0,
883
+ outputPerMillion: 0,
884
+ },
885
+ }],
886
+ workloads: [],
887
+ };
888
+ return buildResourcePreflight({
889
+ runId,
890
+ request,
891
+ verificationPlan,
892
+ requestSha256: hashObject(request),
893
+ evaluatedAt: request.observations[0].adapter.observedAt,
894
+ });
895
+ }
896
+
897
+ export function createDeploymentExecuteChildRun({
898
+ workspaceRoot,
899
+ prepareReceipt,
900
+ remoteManifest,
901
+ ownerDecision,
902
+ ownerAuthority,
903
+ }) {
904
+ const root = canonicalWorkspaceRoot(workspaceRoot);
905
+ validatePrepareReceipt(prepareReceipt);
906
+ const runId = safeIdentifier(remoteManifest?.deploymentId, "executeRunId");
907
+ const target = validateRemoteTarget(remoteManifest?.target);
908
+ if (
909
+ remoteManifest?.deploymentLineageSha256 !== null
910
+ || canonicalJson(remoteManifest?.artifact)
911
+ !== canonicalJson(prepareReceipt.artifact)
912
+ ) {
913
+ throw new Error(
914
+ "Deployment execute manifest must bind the prepared artifact and start without lineage.",
915
+ );
916
+ }
917
+ const decisionArtifact = loadOwnerDeploymentDecision(root, ownerDecision);
918
+ const decisionBinding = ownerDeploymentDecisionBindingV1(
919
+ decisionArtifact.value,
920
+ );
921
+ if (
922
+ canonicalJson(prepareReceipt.ownerDecision)
923
+ !== canonicalJson(decisionBinding)
924
+ ) {
925
+ throw new Error("owner_decision_conflict:prepare_receipt_binding");
926
+ }
927
+ assertAllowedKeys(
928
+ ownerAuthority,
929
+ "Owner authority descriptor",
930
+ AUTHORITY_DESCRIPTOR_KEYS,
931
+ );
932
+ const authorityPath = safeRelativePath(
933
+ ownerAuthority.path,
934
+ "Owner authority artifact path",
935
+ );
936
+ if (
937
+ authorityPath === RUNTIME_ROOT
938
+ || authorityPath.startsWith(`${RUNTIME_ROOT}/`)
939
+ ) {
940
+ throw new Error("Owner authority artifact must be independent from RunKit control state.");
941
+ }
942
+ const authorityFile = readJsonFile(
943
+ root,
944
+ authorityPath,
945
+ "Owner authority artifact",
946
+ );
947
+ const authoritySha256 = assertHash(
948
+ ownerAuthority.sha256,
949
+ "Owner authority artifact",
950
+ );
951
+ if (sha256(authorityFile.bytes) !== authoritySha256) {
952
+ throw new Error("Owner authority artifact hash does not match its exact bytes.");
953
+ }
954
+ const destructive = authorityFile.value?.permissions?.destructive;
955
+ if (
956
+ authorityFile.value?.schemaVersion
957
+ !== "OwlCodaRunKitOwnerDeploymentAuthorityV2"
958
+ || authorityFile.value.executeRunId !== runId
959
+ || authorityFile.value.permissions?.deploy !== true
960
+ || typeof destructive !== "boolean"
961
+ || authorityFile.value.ownerDecisionId
962
+ !== decisionArtifact.value.decisionId
963
+ || authorityFile.value.ownerDecisionSha256
964
+ !== decisionArtifact.value.decisionSha256
965
+ ) {
966
+ throw new Error(
967
+ "Signed Owner authority must name the child run and exact deployment permissions.",
968
+ );
969
+ }
970
+ const prospectiveGoal = childGoal({
971
+ prepareReceipt,
972
+ runId,
973
+ target,
974
+ destructive,
975
+ ownerDecision: decisionArtifact.value,
976
+ });
977
+ const decisionCompilation = compileOwnerDeploymentDecisionV1({
978
+ decision: decisionArtifact.value,
979
+ prepareReceipt,
980
+ goal: prospectiveGoal,
981
+ remoteManifest,
982
+ authority: authorityFile.value,
983
+ expected: {
984
+ targetSha256: hashObject(target),
985
+ artifactSha256: prepareReceipt.artifact.sha256,
986
+ remoteDeploymentIntentSha256:
987
+ canonicalRemoteDeploymentIntentSha256(remoteManifest),
988
+ },
989
+ });
990
+ const paths = deploymentChildPaths(root, runId);
991
+ mkdirSync(path.join(root, RUNTIME_ROOT, "executions"), { recursive: true });
992
+ return withControlTransaction(root, () => {
993
+ if (
994
+ existsSync(paths.executionRoot)
995
+ || existsSync(paths.deploymentRoot)
996
+ ) {
997
+ throw new Error(
998
+ `Deployment execute child or deployment control already exists: ${runId}`,
999
+ );
1000
+ }
1001
+ mkdirSync(path.join(paths.executionRoot, "leases"), { recursive: true });
1002
+ mkdirSync(path.join(paths.executionRoot, "delivery-packets"));
1003
+ mkdirSync(path.join(paths.executionRoot, "verification-receipts"));
1004
+ try {
1005
+ const enginePin = currentCoreIdentity();
1006
+ const goal = prospectiveGoal;
1007
+ writeJsonExclusiveAtomically(
1008
+ paths.decisionSnapshotPath,
1009
+ decisionArtifact.value,
1010
+ );
1011
+ const decisionSnapshot = {
1012
+ path: relativeToWorkspace(root, paths.decisionSnapshotPath),
1013
+ sha256: sha256(readFileSync(paths.decisionSnapshotPath)),
1014
+ };
1015
+ writeJsonExclusiveAtomically(paths.pinPath, enginePin);
1016
+ writeJsonExclusiveAtomically(paths.goalPath, goal);
1017
+ const goalSha256 = sha256(readFileSync(paths.goalPath));
1018
+ writeJsonExclusiveAtomically(paths.planPath, {
1019
+ schemaVersion: "OwlCodaRunKitExecutionPlanV1",
1020
+ runId,
1021
+ state: "planned",
1022
+ enginePin,
1023
+ goalContractSha256: goalSha256,
1024
+ ownerDecisionSha256: decisionArtifact.value.decisionSha256,
1025
+ ownerDecisionSnapshot: decisionSnapshot,
1026
+ ownerDecisionCompilationSha256:
1027
+ decisionCompilation.compilationSha256,
1028
+ authorizationGranted: false,
1029
+ });
1030
+ appendFileSync(
1031
+ paths.eventsPath,
1032
+ `${JSON.stringify({
1033
+ sequence: 1,
1034
+ type: "execution_planned",
1035
+ runId,
1036
+ authorizationGranted: false,
1037
+ ownerDecisionSha256: decisionArtifact.value.decisionSha256,
1038
+ })}\n`,
1039
+ );
1040
+ const lease = acquireLeaseWithinControlTransaction({
1041
+ workspaceRoot: root,
1042
+ runId,
1043
+ workItemId: "deployment-execute",
1044
+ ownedPaths: [prepareReceipt.artifact.path],
1045
+ });
1046
+ if (lease.status !== "lease_acquired") {
1047
+ throw new Error(`Deployment execute lease was not acquired: ${lease.status}`);
1048
+ }
1049
+ const profile = deploymentProfile(prepareReceipt.artifact.path);
1050
+ writeJsonExclusiveAtomically(paths.profilePath, profile);
1051
+ const profileSha256 = sha256(readFileSync(paths.profilePath));
1052
+ const verificationPlan = deploymentVerificationPlan({
1053
+ runId,
1054
+ profileSha256,
1055
+ prepareReceipt,
1056
+ });
1057
+ writeJsonExclusiveAtomically(paths.verificationPlanPath, verificationPlan);
1058
+ const verificationPlanSha256 = sha256(
1059
+ readFileSync(paths.verificationPlanPath),
1060
+ );
1061
+ const resourcePreflight = deploymentResourcePreflight({
1062
+ runId,
1063
+ verificationPlan,
1064
+ verificationPlanPath:
1065
+ relativeToWorkspace(root, paths.verificationPlanPath),
1066
+ verificationPlanSha256,
1067
+ });
1068
+ writeJsonExclusiveAtomically(
1069
+ paths.resourcePreflightPath,
1070
+ resourcePreflight,
1071
+ );
1072
+ const executeRequest = {
1073
+ schemaVersion: "OwlCodaRunKitDeploymentExecuteRequestV1",
1074
+ executeRunId: runId,
1075
+ executeGoal: {
1076
+ path: relativeToWorkspace(root, paths.goalPath),
1077
+ sha256: goalSha256,
1078
+ },
1079
+ prepareReceiptSha256: prepareReceipt.receiptSha256,
1080
+ target,
1081
+ ownerAuthority: {
1082
+ path: authorityPath,
1083
+ sha256: authoritySha256,
1084
+ },
1085
+ ownerDecision: {
1086
+ path: decisionArtifact.path,
1087
+ sha256: decisionArtifact.sha256,
1088
+ },
1089
+ ownerDecisionSnapshot: decisionSnapshot,
1090
+ workItemId: "deployment-execute",
1091
+ profileId: "deployment-execute",
1092
+ resourcePreflight: {
1093
+ path: relativeToWorkspace(root, paths.resourcePreflightPath),
1094
+ sha256: sha256(readFileSync(paths.resourcePreflightPath)),
1095
+ },
1096
+ deploy: true,
1097
+ destructive,
1098
+ };
1099
+ writeJsonExclusiveAtomically(paths.requestPath, executeRequest);
1100
+ return {
1101
+ runId,
1102
+ executeRequest,
1103
+ executeRequestPath: relativeToWorkspace(root, paths.requestPath),
1104
+ lineagePath: relativeToWorkspace(root, paths.lineagePath),
1105
+ resultPath: relativeToWorkspace(root, paths.resultPath),
1106
+ };
1107
+ } catch (error) {
1108
+ rmSync(paths.executionRoot, { recursive: true, force: true });
1109
+ rmSync(paths.deploymentRoot, { recursive: true, force: true });
1110
+ throw error;
1111
+ }
1112
+ });
1113
+ }
1114
+
1115
+ function validateRemoteManifestBinding({
1116
+ remoteManifest,
1117
+ remoteManifestBytes,
1118
+ prepareReceipt,
1119
+ executeRunId,
1120
+ target,
1121
+ }) {
1122
+ if (
1123
+ !Buffer.isBuffer(remoteManifestBytes)
1124
+ && !(remoteManifestBytes instanceof Uint8Array)
1125
+ ) {
1126
+ throw new Error("Deployment execute requires the exact remote manifest bytes.");
1127
+ }
1128
+ let parsed;
1129
+ try {
1130
+ parsed = JSON.parse(Buffer.from(remoteManifestBytes).toString("utf8"));
1131
+ } catch {
1132
+ throw new Error("Deployment execute remote manifest bytes must contain valid JSON.");
1133
+ }
1134
+ if (canonicalJson(parsed) !== canonicalJson(remoteManifest)) {
1135
+ throw new Error(
1136
+ "Deployment execute remote manifest object does not match its exact bytes.",
1137
+ );
1138
+ }
1139
+ if (
1140
+ remoteManifest?.deploymentLineageSha256 !== null
1141
+ || remoteManifest?.deploymentId !== executeRunId
1142
+ || canonicalJson(remoteManifest.target) !== canonicalJson(target)
1143
+ || canonicalJson(remoteManifest.artifact)
1144
+ !== canonicalJson(prepareReceipt.artifact)
1145
+ ) {
1146
+ throw new Error(
1147
+ "Deployment execute remote manifest does not bind the exact child, target, and artifact.",
1148
+ );
1149
+ }
1150
+ return {
1151
+ fileSha256: sha256(Buffer.from(remoteManifestBytes)),
1152
+ intentSha256: canonicalRemoteDeploymentIntentSha256(remoteManifest),
1153
+ };
1154
+ }
1155
+
1156
+ function validateOwnerAuthority(ownerAuthority, request, remoteManifestBinding) {
1157
+ assertAllowedKeys(ownerAuthority, "Owner authority", AUTHORITY_KEYS);
1158
+ safeIdentifier(ownerAuthority.authorityId, "Owner authorityId");
1159
+ const authorityPath = safeRelativePath(
1160
+ ownerAuthority.path,
1161
+ "Owner authority path",
1162
+ );
1163
+ if (
1164
+ authorityPath === RUNTIME_ROOT
1165
+ || authorityPath.startsWith(`${RUNTIME_ROOT}/`)
1166
+ ) {
1167
+ throw new Error("Owner authority must be independent from RunKit control state.");
1168
+ }
1169
+ const authorityHash = assertHash(ownerAuthority.sha256, "Owner authority");
1170
+ const signerKeyId = safeIdentifier(
1171
+ ownerAuthority.signerKeyId,
1172
+ "Owner authority signerKeyId",
1173
+ );
1174
+ const trustStoreSha256 = assertHashRef(
1175
+ ownerAuthority.trustStoreSha256,
1176
+ "Owner authority trust store",
1177
+ );
1178
+ const remoteManifestFileSha256 = assertHash(
1179
+ ownerAuthority.remoteManifestFileSha256,
1180
+ "Owner authority remote manifest file",
1181
+ );
1182
+ const remoteDeploymentIntentSha256 = assertHash(
1183
+ ownerAuthority.remoteDeploymentIntentSha256,
1184
+ "Owner authority remote deployment intent",
1185
+ );
1186
+ const targetSha256 = ownerAuthority.targetSha256 === undefined
1187
+ ? null
1188
+ : assertHash(ownerAuthority.targetSha256, "Owner authority target");
1189
+ const artifactSha256 = ownerAuthority.artifactSha256 === undefined
1190
+ ? null
1191
+ : assertHash(ownerAuthority.artifactSha256, "Owner authority artifact");
1192
+ const ownerDecisionId = ownerAuthority.ownerDecisionId === undefined
1193
+ ? null
1194
+ : safeIdentifier(
1195
+ ownerAuthority.ownerDecisionId,
1196
+ "Owner authority decisionId",
1197
+ );
1198
+ const ownerDecisionSha256 = ownerAuthority.ownerDecisionSha256 === undefined
1199
+ ? null
1200
+ : assertHash(
1201
+ ownerAuthority.ownerDecisionSha256,
1202
+ "Owner authority decision",
1203
+ );
1204
+ if (
1205
+ remoteManifestFileSha256 !== remoteManifestBinding.fileSha256
1206
+ || remoteDeploymentIntentSha256 !== remoteManifestBinding.intentSha256
1207
+ ) {
1208
+ throw new Error(
1209
+ "Owner authority does not bind the exact remote manifest bytes and canonical intent.",
1210
+ );
1211
+ }
1212
+ assertAllowedKeys(ownerAuthority.permissions, "Owner authority permissions", PERMISSION_KEYS);
1213
+ if (ownerAuthority.permissions.deploy !== true
1214
+ || typeof ownerAuthority.permissions.destructive !== "boolean") {
1215
+ throw new Error("Owner authority must explicitly grant deploy and state destructive permission.");
1216
+ }
1217
+ if (request.deploy !== true
1218
+ || typeof request.destructive !== "boolean"
1219
+ || request.destructive !== ownerAuthority.permissions.destructive) {
1220
+ throw new Error("Deployment execute permissions must exactly match Owner authority.");
1221
+ }
1222
+ return {
1223
+ authorityId: ownerAuthority.authorityId,
1224
+ path: authorityPath,
1225
+ sha256: authorityHash,
1226
+ signerKeyId,
1227
+ trustStoreSha256,
1228
+ remoteManifestFileSha256,
1229
+ remoteDeploymentIntentSha256,
1230
+ ...(targetSha256 === null ? {} : { targetSha256, artifactSha256 }),
1231
+ ...(ownerDecisionId === null
1232
+ ? {}
1233
+ : { ownerDecisionId, ownerDecisionSha256 }),
1234
+ permissions: structuredClone(ownerAuthority.permissions),
1235
+ };
1236
+ }
1237
+
1238
+ function loadOwnerDeploymentAuthority({
1239
+ root,
1240
+ descriptor: authorityDescriptor,
1241
+ prepareReceipt,
1242
+ executeRequest,
1243
+ remoteManifestBinding,
1244
+ ownerDecision,
1245
+ verifyOwnerAuthority,
1246
+ }) {
1247
+ assertAllowedKeys(
1248
+ authorityDescriptor,
1249
+ "Owner authority descriptor",
1250
+ AUTHORITY_DESCRIPTOR_KEYS,
1251
+ );
1252
+ const descriptorPath = safeRelativePath(
1253
+ authorityDescriptor.path,
1254
+ "Owner authority artifact path",
1255
+ );
1256
+ if (
1257
+ descriptorPath === RUNTIME_ROOT
1258
+ || descriptorPath.startsWith(`${RUNTIME_ROOT}/`)
1259
+ ) {
1260
+ throw new Error("Owner authority artifact must be independent from RunKit control state.");
1261
+ }
1262
+ const descriptorSha256 = assertHash(
1263
+ authorityDescriptor.sha256,
1264
+ "Owner authority artifact",
1265
+ );
1266
+ const file = readJsonFile(root, descriptorPath, "Owner authority artifact");
1267
+ if (sha256(file.bytes) !== descriptorSha256) {
1268
+ throw new Error("Owner authority artifact hash does not match its exact bytes.");
1269
+ }
1270
+ const authority = file.value;
1271
+ assertAllowedKeys(
1272
+ authority,
1273
+ "Owner deployment authority",
1274
+ OWNER_DEPLOYMENT_AUTHORITY_KEYS,
1275
+ );
1276
+ const authorityId = safeIdentifier(
1277
+ authority.authorityId,
1278
+ "Owner authorityId",
1279
+ );
1280
+ if (authority.schemaVersion === "OwlCodaRunKitOwnerDeploymentAuthorityV1") {
1281
+ throw new Error("deployment_owner_authority_untrusted");
1282
+ }
1283
+ assertAllowedKeys(
1284
+ authority.permissions,
1285
+ "Owner authority permissions",
1286
+ PERMISSION_KEYS,
1287
+ );
1288
+ if (
1289
+ authority.remoteManifestFileSha256
1290
+ !== remoteManifestBinding.fileSha256
1291
+ || authority.remoteDeploymentIntentSha256
1292
+ !== remoteManifestBinding.intentSha256
1293
+ ) {
1294
+ throw new Error(
1295
+ "Owner authority does not bind the exact remote manifest bytes and canonical intent.",
1296
+ );
1297
+ }
1298
+ if (
1299
+ authority.schemaVersion
1300
+ !== "OwlCodaRunKitOwnerDeploymentAuthorityV2"
1301
+ || authority.decision !== "approved"
1302
+ || authority.scope !== "execute_exact_remote_deployment"
1303
+ || authority.executeRunId !== executeRequest.executeRunId
1304
+ || authority.prepareReceiptSha256 !== prepareReceipt.receiptSha256
1305
+ || authority.targetSha256
1306
+ !== hashObject(validateRemoteTarget(executeRequest.target))
1307
+ || authority.artifactSha256 !== prepareReceipt.artifact.sha256
1308
+ || authority.ownerDecisionId !== ownerDecision.decisionId
1309
+ || authority.ownerDecisionSha256 !== ownerDecision.decisionSha256
1310
+ || authority.permissions.deploy !== true
1311
+ || typeof authority.permissions.destructive !== "boolean"
1312
+ || authority.permissions.destructive !== executeRequest.destructive
1313
+ || executeRequest.deploy !== true
1314
+ || authority.authorizationGranted !== false
1315
+ || authority.signatureAlgorithm !== "ed25519"
1316
+ || typeof authority.signerKeyId !== "string"
1317
+ || typeof authority.signature !== "string"
1318
+ || !SHA256_REF.test(authority.authoritySha256)
1319
+ || authority.authoritySha256
1320
+ !== ownerAuthorityArtifactSha256V1(authority)
1321
+ ) {
1322
+ throw new Error(
1323
+ "Owner authority artifact does not grant the exact deployment scope.",
1324
+ );
1325
+ }
1326
+ let trustedAuthority;
1327
+ try {
1328
+ trustedAuthority = verifyOwnerAuthority({ authority });
1329
+ } catch {
1330
+ throw new Error("deployment_owner_authority_untrusted");
1331
+ }
1332
+ if (
1333
+ trustedAuthority?.status !== "trusted"
1334
+ || trustedAuthority.signerKeyId !== authority.signerKeyId
1335
+ || trustedAuthority.authoritySha256 !== authority.authoritySha256
1336
+ || !SHA256_REF.test(trustedAuthority.trustStoreSha256)
1337
+ ) {
1338
+ throw new Error("deployment_owner_authority_untrusted");
1339
+ }
1340
+ return {
1341
+ authorityId,
1342
+ path: descriptorPath,
1343
+ sha256: descriptorSha256,
1344
+ signerKeyId: trustedAuthority.signerKeyId,
1345
+ trustStoreSha256: trustedAuthority.trustStoreSha256,
1346
+ remoteManifestFileSha256: authority.remoteManifestFileSha256,
1347
+ remoteDeploymentIntentSha256:
1348
+ authority.remoteDeploymentIntentSha256,
1349
+ targetSha256: authority.targetSha256,
1350
+ artifactSha256: authority.artifactSha256,
1351
+ ownerDecisionId: authority.ownerDecisionId,
1352
+ ownerDecisionSha256: authority.ownerDecisionSha256,
1353
+ permissions: structuredClone(authority.permissions),
1354
+ };
1355
+ }
1356
+
1357
+ export function createDeploymentExecuteLineage({
1358
+ prepareReceipt,
1359
+ executeRequest,
1360
+ executionBinding = null,
1361
+ remoteManifest,
1362
+ remoteManifestBytes,
1363
+ ownerDecision = null,
1364
+ decisionGoal = null,
1365
+ }) {
1366
+ validatePrepareReceipt(prepareReceipt);
1367
+ assertAllowedKeys(executeRequest, "Deployment execute request", EXECUTE_REQUEST_KEYS);
1368
+ if (executeRequest.schemaVersion !== "OwlCodaRunKitDeploymentExecuteRequestV1") {
1369
+ throw new Error("Unsupported deployment execute request schemaVersion.");
1370
+ }
1371
+ if (executeRequest.prepareReceiptSha256 !== prepareReceipt.receiptSha256) {
1372
+ throw new Error("Deployment execute request does not bind the prepare receipt.");
1373
+ }
1374
+ const executeRunId = safeIdentifier(executeRequest.executeRunId, "executeRunId");
1375
+ if (executeRunId === prepareReceipt.prepareRunId) {
1376
+ throw new Error("Deployment execute requires a new child run.");
1377
+ }
1378
+ const executeGoal = descriptor(executeRequest.executeGoal, "Execute goal");
1379
+ if (executeGoal.path === prepareReceipt.prepareGoal.path
1380
+ || executeGoal.sha256 === prepareReceipt.prepareGoal.sha256) {
1381
+ throw new Error("Deployment execute requires a new goal.");
1382
+ }
1383
+ const target = validateRemoteTarget(executeRequest.target);
1384
+ const remoteManifestBinding = validateRemoteManifestBinding({
1385
+ remoteManifest,
1386
+ remoteManifestBytes,
1387
+ prepareReceipt,
1388
+ executeRunId,
1389
+ target,
1390
+ });
1391
+ const ownerAuthority = validateOwnerAuthority(
1392
+ executeRequest.ownerAuthority,
1393
+ executeRequest,
1394
+ remoteManifestBinding,
1395
+ );
1396
+ const decisionCompilation = ownerDecision === null
1397
+ ? null
1398
+ : compileOwnerDeploymentDecisionV1({
1399
+ decision: ownerDecision,
1400
+ prepareReceipt,
1401
+ goal: decisionGoal,
1402
+ remoteManifest,
1403
+ authority: ownerAuthority,
1404
+ expected: {
1405
+ targetSha256: hashObject(target),
1406
+ artifactSha256: prepareReceipt.artifact.sha256,
1407
+ remoteDeploymentIntentSha256: remoteManifestBinding.intentSha256,
1408
+ },
1409
+ });
1410
+ const sourceArtifact = prepareReceipt.sourceArtifact ?? null;
1411
+ const sourceArtifactSha256 = sourceArtifact?.sha256
1412
+ ?? prepareReceipt.deliveryPacket.sha256;
1413
+ const upstreamHashes = new Set([
1414
+ prepareReceipt.receiptSha256,
1415
+ prepareReceipt.prepareGoal.sha256,
1416
+ prepareReceipt.closeout.sha256,
1417
+ prepareReceipt.closeout.gateInputSha256,
1418
+ sourceArtifactSha256,
1419
+ prepareReceipt.artifact.sha256,
1420
+ executeGoal.sha256,
1421
+ ]);
1422
+ if (upstreamHashes.has(ownerAuthority.sha256)) {
1423
+ throw new Error("Deployment execute requires an independent Owner authority hash.");
1424
+ }
1425
+ const body = {
1426
+ schemaVersion: "OwlCodaRunKitDeploymentLineageV1",
1427
+ parent: {
1428
+ prepareRunId: prepareReceipt.prepareRunId,
1429
+ prepareGoal: structuredClone(prepareReceipt.prepareGoal),
1430
+ prepareReceiptSha256: prepareReceipt.receiptSha256,
1431
+ acceptedCloseoutSha256: prepareReceipt.closeout.sha256,
1432
+ ...(sourceArtifact === null
1433
+ ? { deliveryPacketSha256: prepareReceipt.deliveryPacket.sha256 }
1434
+ : { sourceArtifact: structuredClone(sourceArtifact) }),
1435
+ artifact: structuredClone(prepareReceipt.artifact),
1436
+ },
1437
+ child: {
1438
+ executeRunId,
1439
+ executeGoal,
1440
+ ...(executionBinding === null
1441
+ ? {}
1442
+ : { control: structuredClone(executionBinding) }),
1443
+ },
1444
+ ...(decisionCompilation === null
1445
+ ? {}
1446
+ : {
1447
+ ownerDecision: {
1448
+ ...ownerDeploymentDecisionBindingV1(ownerDecision),
1449
+ compilationSha256: decisionCompilation.compilationSha256,
1450
+ },
1451
+ }),
1452
+ target: {
1453
+ value: target,
1454
+ sha256: hashObject(target),
1455
+ },
1456
+ authority: {
1457
+ source: "owner",
1458
+ authorityId: ownerAuthority.authorityId,
1459
+ path: ownerAuthority.path,
1460
+ sha256: ownerAuthority.sha256,
1461
+ signerKeyId: ownerAuthority.signerKeyId,
1462
+ trustStoreSha256: ownerAuthority.trustStoreSha256,
1463
+ remoteManifestFileSha256:
1464
+ ownerAuthority.remoteManifestFileSha256,
1465
+ remoteDeploymentIntentSha256:
1466
+ ownerAuthority.remoteDeploymentIntentSha256,
1467
+ ...(ownerAuthority.ownerDecisionId === undefined
1468
+ ? {}
1469
+ : {
1470
+ ownerDecisionId: ownerAuthority.ownerDecisionId,
1471
+ ownerDecisionSha256: ownerAuthority.ownerDecisionSha256,
1472
+ }),
1473
+ inheritedFromPrepare: false,
1474
+ },
1475
+ permissions: {
1476
+ deploy: executeRequest.deploy,
1477
+ destructive: executeRequest.destructive,
1478
+ },
1479
+ authorizationGranted: false,
1480
+ };
1481
+ return { ...body, lineageSha256: hashObject(body) };
1482
+ }
1483
+
1484
+ function validateChildGoal({
1485
+ goal,
1486
+ prepareReceipt,
1487
+ executeRequest,
1488
+ ownerDecision,
1489
+ }) {
1490
+ if (
1491
+ goal?.schemaVersion !== "OwlCodaRunKitGoalContractV1"
1492
+ || goal.authorization?.deploy !== true
1493
+ || goal.authorization?.destructive !== executeRequest.destructive
1494
+ || goal.deployment?.phase !== "execute"
1495
+ || goal.deployment?.prepareRunId !== prepareReceipt.prepareRunId
1496
+ || goal.deployment?.prepareReceiptSha256 !== prepareReceipt.receiptSha256
1497
+ || goal.deployment?.targetSha256
1498
+ !== hashObject(validateRemoteTarget(executeRequest.target))
1499
+ || canonicalJson(goal.deployment?.ownerDecision)
1500
+ !== canonicalJson(ownerDeploymentDecisionBindingV1(ownerDecision))
1501
+ ) {
1502
+ throw new Error(
1503
+ "Deployment execute child Goal does not bind the exact parent, target, and permissions.",
1504
+ );
1505
+ }
1506
+ }
1507
+
1508
+ function loadDeploymentChildControl({
1509
+ root,
1510
+ prepareReceipt,
1511
+ executeRequest,
1512
+ ownerDecision,
1513
+ }) {
1514
+ const runId = safeIdentifier(executeRequest.executeRunId, "executeRunId");
1515
+ const executionRoot = path.join(root, RUNTIME_ROOT, "executions", runId);
1516
+ const expectedGoalPath = `${RUNTIME_ROOT}/executions/${runId}/goal-contract.json`;
1517
+ const executeGoal = descriptor(executeRequest.executeGoal, "Execute goal");
1518
+ if (executeGoal.path !== expectedGoalPath) {
1519
+ throw new Error("Deployment execute Goal must belong to the real child execution.");
1520
+ }
1521
+ const enginePin = readJsonFile(
1522
+ root,
1523
+ `${RUNTIME_ROOT}/executions/${runId}/engine-pin.json`,
1524
+ "Deployment execute engine pin",
1525
+ );
1526
+ const pinGate = validateExecutionPin({
1527
+ expected: enginePin.value,
1528
+ actual: currentCoreIdentity(),
1529
+ });
1530
+ if (pinGate.status !== "valid") {
1531
+ throw new Error("Deployment execute child engine pin does not match the active Core.");
1532
+ }
1533
+ const goal = readJsonFile(
1534
+ root,
1535
+ expectedGoalPath,
1536
+ "Deployment execute Goal",
1537
+ );
1538
+ if (sha256(goal.bytes) !== executeGoal.sha256) {
1539
+ throw new Error("Deployment execute Goal hash does not match its exact bytes.");
1540
+ }
1541
+ validateChildGoal({
1542
+ goal: goal.value,
1543
+ prepareReceipt,
1544
+ executeRequest,
1545
+ ownerDecision,
1546
+ });
1547
+ const decisionSnapshot = descriptor(
1548
+ executeRequest.ownerDecisionSnapshot,
1549
+ "Owner deployment decision snapshot",
1550
+ );
1551
+ const expectedSnapshotPath =
1552
+ `${RUNTIME_ROOT}/deployments/${runId}/owner-decision-snapshot.json`;
1553
+ if (decisionSnapshot.path !== expectedSnapshotPath) {
1554
+ throw new Error("Owner deployment decision snapshot must belong to the child deployment.");
1555
+ }
1556
+ const snapshotFile = readJsonFile(
1557
+ root,
1558
+ decisionSnapshot.path,
1559
+ "Owner deployment decision snapshot",
1560
+ );
1561
+ if (
1562
+ sha256(snapshotFile.bytes) !== decisionSnapshot.sha256
1563
+ || canonicalJson(validateOwnerDeploymentDecisionV1(snapshotFile.value))
1564
+ !== canonicalJson(ownerDecision)
1565
+ ) {
1566
+ throw new Error("Owner deployment decision snapshot drifted.");
1567
+ }
1568
+ const plan = readJsonFile(
1569
+ root,
1570
+ `${RUNTIME_ROOT}/executions/${runId}/execution-plan.json`,
1571
+ "Deployment execute plan",
1572
+ );
1573
+ if (
1574
+ plan.value?.schemaVersion !== "OwlCodaRunKitExecutionPlanV1"
1575
+ || plan.value.runId !== runId
1576
+ || plan.value.state !== "planned"
1577
+ || plan.value.authorizationGranted !== false
1578
+ || plan.value.goalContractSha256 !== executeGoal.sha256
1579
+ || plan.value.ownerDecisionSha256 !== ownerDecision.decisionSha256
1580
+ || canonicalJson(plan.value.ownerDecisionSnapshot)
1581
+ !== canonicalJson(decisionSnapshot)
1582
+ || validateExecutionPin({
1583
+ expected: enginePin.value,
1584
+ actual: plan.value.enginePin,
1585
+ }).status !== "valid"
1586
+ ) {
1587
+ throw new Error("Deployment execute child plan is invalid or drifted.");
1588
+ }
1589
+
1590
+ const workItemId = safeIdentifier(
1591
+ executeRequest.workItemId,
1592
+ "Deployment execute workItemId",
1593
+ );
1594
+ const leases = listLeaseArtifacts({
1595
+ workspaceRoot: root,
1596
+ executionRoot,
1597
+ }).filter(lease => lease.workItemId === workItemId);
1598
+ if (leases.length !== 1 || leases[0].state !== "active") {
1599
+ throw new Error("Deployment execute requires the exact active child writer lease.");
1600
+ }
1601
+ const [lease] = leases;
1602
+ const leaseBytes = readFileSync(lease.leasePath);
1603
+
1604
+ const profileId = safeIdentifier(
1605
+ executeRequest.profileId,
1606
+ "Deployment execute profileId",
1607
+ );
1608
+ const builtInProfilePath =
1609
+ `${RUNTIME_ROOT}/executions/${runId}/deployment-profile.json`;
1610
+ const profiles = readJsonFile(
1611
+ root,
1612
+ existsSync(path.join(root, builtInProfilePath))
1613
+ ? builtInProfilePath
1614
+ : `${RUNTIME_ROOT}/profiles.json`,
1615
+ "Deployment profiles",
1616
+ );
1617
+ if (
1618
+ profiles.value?.schemaVersion !== "OwlCodaRunKitProfilesV1"
1619
+ || !Array.isArray(profiles.value.profiles)
1620
+ || profiles.value.profiles.filter(profile => profile?.id === profileId).length !== 1
1621
+ ) {
1622
+ throw new Error("Deployment execute profile is missing or ambiguous.");
1623
+ }
1624
+
1625
+ const preflightDescriptor = descriptor(
1626
+ executeRequest.resourcePreflight,
1627
+ "Deployment resource preflight",
1628
+ );
1629
+ const preflightPrefix =
1630
+ `${RUNTIME_ROOT}/executions/${runId}/resource-preflights/`;
1631
+ if (!preflightDescriptor.path.startsWith(preflightPrefix)) {
1632
+ throw new Error("Deployment resource preflight must belong to the child execution.");
1633
+ }
1634
+ const preflight = readJsonFile(
1635
+ root,
1636
+ preflightDescriptor.path,
1637
+ "Deployment resource preflight",
1638
+ );
1639
+ if (sha256(preflight.bytes) !== preflightDescriptor.sha256) {
1640
+ throw new Error("Deployment resource preflight hash does not match its exact bytes.");
1641
+ }
1642
+ const preflightSummary = summarizeResourcePreflight(preflight.value, runId);
1643
+ if (
1644
+ !new Set([
1645
+ "ready_for_model_execution",
1646
+ "ready_without_model_execution",
1647
+ ]).has(preflightSummary.status)
1648
+ || (
1649
+ preflightSummary.validUntil !== null
1650
+ && Date.parse(preflightSummary.validUntil) <= Date.now()
1651
+ )
1652
+ ) {
1653
+ throw new Error("Deployment resource preflight is blocked or expired.");
1654
+ }
1655
+ const verificationPlan = readJsonFile(
1656
+ root,
1657
+ preflight.value.verificationPlan.path,
1658
+ "Deployment verification plan",
1659
+ );
1660
+ if (
1661
+ sha256(verificationPlan.bytes) !== preflight.value.verificationPlan.sha256
1662
+ || verificationPlan.value?.schemaVersion
1663
+ !== "OwlCodaRunKitVerificationPlanV1"
1664
+ || verificationPlan.value.runId !== runId
1665
+ || verificationPlan.value.planId !== preflight.value.verificationPlan.planId
1666
+ || verificationPlan.value.authorizationGranted !== false
1667
+ || verificationPlan.value.acceptance?.blocked !== false
1668
+ || !verificationPlan.value.profileImpact?.selectedProfileIds
1669
+ ?.includes(profileId)
1670
+ ) {
1671
+ throw new Error(
1672
+ "Deployment verification plan does not bind the required child profile.",
1673
+ );
1674
+ }
1675
+
1676
+ const artifact = readRegularFile(
1677
+ root,
1678
+ prepareReceipt.artifact.path,
1679
+ "Deployment artifact",
1680
+ );
1681
+ if (
1682
+ sha256(artifact.bytes) !== prepareReceipt.artifact.sha256
1683
+ || artifact.size !== prepareReceipt.artifact.size
1684
+ ) {
1685
+ throw new Error("Deployment artifact size or SHA-256 drifted before execute.");
1686
+ }
1687
+
1688
+ return {
1689
+ enginePin: {
1690
+ path: enginePin.relativePath,
1691
+ sha256: sha256(enginePin.bytes),
1692
+ value: structuredClone(enginePin.value),
1693
+ },
1694
+ executionPlan: {
1695
+ path: plan.relativePath,
1696
+ sha256: sha256(plan.bytes),
1697
+ },
1698
+ deploymentParent: {
1699
+ prepareRunId: prepareReceipt.prepareRunId,
1700
+ prepareReceiptSha256: prepareReceipt.receiptSha256,
1701
+ },
1702
+ lease: {
1703
+ workItemId,
1704
+ path: lease.leaseRelativePath,
1705
+ sha256: sha256(leaseBytes),
1706
+ ownedPaths: [...lease.ownedPaths],
1707
+ },
1708
+ profile: {
1709
+ profileId,
1710
+ profilesPath: profiles.relativePath,
1711
+ profilesSha256: sha256(profiles.bytes),
1712
+ verificationPlanPath: verificationPlan.relativePath,
1713
+ verificationPlanSha256: sha256(verificationPlan.bytes),
1714
+ },
1715
+ resourcePreflight: {
1716
+ preflightId: preflightSummary.preflightId,
1717
+ path: preflight.relativePath,
1718
+ sha256: sha256(preflight.bytes),
1719
+ decision: preflightSummary.status,
1720
+ },
1721
+ };
1722
+ }
1723
+
1724
+ export function createDeploymentExecuteLineageFromActiveRun({
1725
+ workspaceRoot,
1726
+ prepareReceipt,
1727
+ executeRequest,
1728
+ remoteManifest,
1729
+ remoteManifestBytes,
1730
+ verifyOwnerAuthority = ({ authority }) => verifyTrustedOwnerAuthorityV1({
1731
+ authority,
1732
+ expectedScope: "execute_exact_remote_deployment",
1733
+ expectedPurpose: "remote_deployment",
1734
+ }),
1735
+ }) {
1736
+ const root = canonicalWorkspaceRoot(workspaceRoot);
1737
+ const runId = safeIdentifier(executeRequest?.executeRunId, "executeRunId");
1738
+ const executionRoot = path.join(root, RUNTIME_ROOT, "executions", runId);
1739
+ if (!existsSync(executionRoot)) {
1740
+ throw new Error("Deployment execute requires a real active child execution.");
1741
+ }
1742
+ const stat = lstatSync(executionRoot);
1743
+ if (
1744
+ stat.isSymbolicLink()
1745
+ || !stat.isDirectory()
1746
+ || realpathSync(executionRoot) !== executionRoot
1747
+ || existsSync(path.join(executionRoot, "closeout-receipt.json"))
1748
+ ) {
1749
+ throw new Error("Deployment execute requires a real active child execution.");
1750
+ }
1751
+ const ownerAuthority = loadOwnerDeploymentAuthority({
1752
+ root,
1753
+ descriptor: executeRequest.ownerAuthority,
1754
+ prepareReceipt,
1755
+ executeRequest,
1756
+ remoteManifestBinding: validateRemoteManifestBinding({
1757
+ remoteManifest,
1758
+ remoteManifestBytes,
1759
+ prepareReceipt,
1760
+ executeRunId: runId,
1761
+ target: validateRemoteTarget(executeRequest.target),
1762
+ }),
1763
+ ownerDecision: loadOwnerDeploymentDecision(
1764
+ root,
1765
+ executeRequest.ownerDecision,
1766
+ ).value,
1767
+ verifyOwnerAuthority,
1768
+ });
1769
+ const decisionArtifact = loadOwnerDeploymentDecision(
1770
+ root,
1771
+ executeRequest.ownerDecision,
1772
+ );
1773
+ const executionBinding = loadDeploymentChildControl({
1774
+ root,
1775
+ prepareReceipt,
1776
+ executeRequest,
1777
+ ownerDecision: decisionArtifact.value,
1778
+ });
1779
+ const goal = readJsonFile(
1780
+ root,
1781
+ executeRequest.executeGoal.path,
1782
+ "Deployment execute Goal",
1783
+ ).value;
1784
+ return createDeploymentExecuteLineage({
1785
+ prepareReceipt,
1786
+ executeRequest: {
1787
+ ...executeRequest,
1788
+ ownerAuthority,
1789
+ },
1790
+ executionBinding,
1791
+ remoteManifest,
1792
+ remoteManifestBytes,
1793
+ ownerDecision: decisionArtifact.value,
1794
+ decisionGoal: goal,
1795
+ });
1796
+ }
1797
+
1798
+ export function verifyDeploymentExecuteLineage({
1799
+ lineage,
1800
+ prepareReceipt,
1801
+ executeRequest,
1802
+ remoteManifest,
1803
+ remoteManifestBytes,
1804
+ ownerDecision = null,
1805
+ decisionGoal = null,
1806
+ }) {
1807
+ const issues = [];
1808
+ try {
1809
+ const expected = createDeploymentExecuteLineage({
1810
+ prepareReceipt,
1811
+ executeRequest,
1812
+ remoteManifest,
1813
+ remoteManifestBytes,
1814
+ ownerDecision,
1815
+ decisionGoal,
1816
+ });
1817
+ if (lineage?.lineageSha256 !== hashObject((({ lineageSha256, ...body }) => body)(lineage))) {
1818
+ issues.push("Deployment lineage hash does not match its contents.");
1819
+ }
1820
+ if (canonicalJson(lineage) !== canonicalJson(expected)) {
1821
+ issues.push("Deployment lineage target or upstream bindings drifted.");
1822
+ }
1823
+ } catch (error) {
1824
+ issues.push(error instanceof Error ? error.message : String(error));
1825
+ }
1826
+ return {
1827
+ status: issues.length === 0 ? "valid" : "invalid",
1828
+ issues,
1829
+ };
1830
+ }
1831
+
1832
+ export function closeDeploymentExecuteChildRun({
1833
+ workspaceRoot,
1834
+ prepareReceipt,
1835
+ executeRequest,
1836
+ result,
1837
+ resultPath,
1838
+ supersession = null,
1839
+ }) {
1840
+ const root = canonicalWorkspaceRoot(workspaceRoot);
1841
+ validatePrepareReceipt(prepareReceipt);
1842
+ const runId = safeIdentifier(executeRequest?.executeRunId, "executeRunId");
1843
+ const paths = deploymentChildPaths(root, runId);
1844
+ const resultFile = readRegularFile(
1845
+ root,
1846
+ resultPath,
1847
+ "Deployment result",
1848
+ );
1849
+ let parsedResult;
1850
+ try {
1851
+ parsedResult = JSON.parse(resultFile.bytes.toString("utf8"));
1852
+ } catch {
1853
+ throw new Error("Deployment result must contain valid JSON.");
1854
+ }
1855
+ if (canonicalJson(parsedResult) !== canonicalJson(result)) {
1856
+ throw new Error("Deployment result object does not match its exact bytes.");
1857
+ }
1858
+ return withControlTransaction(root, () => {
1859
+ if (existsSync(path.join(paths.executionRoot, "closeout-receipt.json"))) {
1860
+ throw new Error(`Deployment execute child is already closed: ${runId}`);
1861
+ }
1862
+ const pin = readJsonFile(
1863
+ root,
1864
+ `${RUNTIME_ROOT}/executions/${runId}/engine-pin.json`,
1865
+ "Deployment execute engine pin",
1866
+ );
1867
+ if (validateExecutionPin({
1868
+ expected: pin.value,
1869
+ actual: currentCoreIdentity(),
1870
+ }).status !== "valid") {
1871
+ throw new Error(
1872
+ "Deployment execute child engine pin drifted before closeout.",
1873
+ );
1874
+ }
1875
+ const leases = listLeaseArtifacts({
1876
+ workspaceRoot: root,
1877
+ executionRoot: paths.executionRoot,
1878
+ });
1879
+ const deploymentLeases = leases.filter(
1880
+ lease => lease.workItemId === executeRequest.workItemId,
1881
+ );
1882
+ if (deploymentLeases.length !== 1) {
1883
+ throw new Error(
1884
+ "Deployment execute closeout requires its exact writer lease.",
1885
+ );
1886
+ }
1887
+ const releasedLeaseIds = [];
1888
+ if (deploymentLeases[0].state === "active") {
1889
+ const released = releaseLeaseWithinControlTransaction({
1890
+ workspaceRoot: root,
1891
+ runId,
1892
+ workItemId: executeRequest.workItemId,
1893
+ });
1894
+ if (released.status !== "lease_released") {
1895
+ throw new Error(
1896
+ `Deployment execute lease could not be released: ${released.status}`,
1897
+ );
1898
+ }
1899
+ }
1900
+ releasedLeaseIds.push(executeRequest.workItemId);
1901
+ const accepted = result.status === "deployed" && supersession === null;
1902
+ let verification;
1903
+ if (accepted) {
1904
+ const plan = readJsonFile(
1905
+ root,
1906
+ `${RUNTIME_ROOT}/executions/${runId}`
1907
+ + "/verification-plans/deployment-execute-plan.json",
1908
+ "Deployment verification plan",
1909
+ );
1910
+ const resultReceiptBody = {
1911
+ schemaVersion: "OwlCodaRunKitDeploymentResultReceiptV1",
1912
+ runId,
1913
+ resultPath: resultFile.relativePath,
1914
+ resultSha256: sha256(resultFile.bytes),
1915
+ resultStatus: result.status,
1916
+ completedStages: [...result.completedStages],
1917
+ authorizationGranted: false,
1918
+ };
1919
+ const resultReceipt = {
1920
+ ...resultReceiptBody,
1921
+ receiptSha256: hashObject(resultReceiptBody),
1922
+ };
1923
+ const receiptPath = path.join(
1924
+ paths.executionRoot,
1925
+ "verification-receipts/deployment-execute"
1926
+ + "/deployment-result-receipt.json",
1927
+ );
1928
+ writeJsonExclusiveAtomically(receiptPath, resultReceipt);
1929
+ const gateInputBody = {
1930
+ schemaVersion: "OwlCodaRunKitDeploymentVerificationGateInputV1",
1931
+ runId,
1932
+ decision: "accepted_passed",
1933
+ profileId: executeRequest.profileId,
1934
+ verificationPlanSha256: sha256(plan.bytes),
1935
+ resultReceiptSha256: sha256(readFileSync(receiptPath)),
1936
+ sourceFingerprint: prepareReceipt.closeout.sourceFingerprint,
1937
+ authorizationGranted: false,
1938
+ };
1939
+ const gateInput = {
1940
+ ...gateInputBody,
1941
+ gateInputSha256: hashObject(gateInputBody),
1942
+ };
1943
+ const gateInputPath = path.join(
1944
+ paths.executionRoot,
1945
+ "verification-receipts/deployment-execute"
1946
+ + "/verification-gate-input.json",
1947
+ );
1948
+ writeJsonExclusiveAtomically(gateInputPath, gateInput);
1949
+ verification = {
1950
+ contractVersion: "0.2",
1951
+ gateDecision: "accepted_passed",
1952
+ gateInputSha256: sha256(readFileSync(gateInputPath)),
1953
+ activeReceiptSha256: sha256(readFileSync(receiptPath)),
1954
+ sourceFingerprint: prepareReceipt.closeout.sourceFingerprint,
1955
+ verificationContextFingerprint:
1956
+ plan.value.verificationContextFingerprint,
1957
+ selectedProfileIds: [executeRequest.profileId],
1958
+ leaseState: "released",
1959
+ releasedLeaseIds,
1960
+ };
1961
+ }
1962
+ const supersessionStatus = supersession === null
1963
+ ? null
1964
+ : createDeploymentSupersessionStatusV1({
1965
+ runId,
1966
+ priorDecision: supersession.priorDecision,
1967
+ replacementDecision: supersession.replacementDecision,
1968
+ });
1969
+ const decision = accepted ? "accepted" : "blocked";
1970
+ const closeout = createCoreArtifact({
1971
+ core: pin.value,
1972
+ producer: {
1973
+ adapterKind: "owlcoda",
1974
+ adapterVersion: currentCoreIdentity().coreVersion,
1975
+ },
1976
+ payload: {
1977
+ runId,
1978
+ decision,
1979
+ ...(supersessionStatus === null
1980
+ ? {}
1981
+ : {
1982
+ statusCode: supersessionStatus.status,
1983
+ businessGoalIncomplete:
1984
+ supersessionStatus.businessGoalIncomplete,
1985
+ replacementPlanRequired:
1986
+ supersessionStatus.replacementPlanRequired,
1987
+ nextAllowedAction:
1988
+ supersessionStatus.nextAllowedAction,
1989
+ supersession: {
1990
+ priorDecisionSha256:
1991
+ supersessionStatus.priorDecisionSha256,
1992
+ replacementDecisionSha256:
1993
+ supersessionStatus.replacementDecisionSha256,
1994
+ },
1995
+ }),
1996
+ authorizationGranted: false,
1997
+ ...(verification ? { verification } : {}),
1998
+ },
1999
+ extensions: {},
2000
+ });
2001
+ const closeoutPath = path.join(
2002
+ paths.executionRoot,
2003
+ "closeout-receipt.json",
2004
+ );
2005
+ writeJsonExclusiveAtomically(closeoutPath, closeout);
2006
+ const priorEvents = readFileSync(paths.eventsPath, "utf8")
2007
+ .trim()
2008
+ .split("\n")
2009
+ .filter(Boolean);
2010
+ appendFileSync(
2011
+ paths.eventsPath,
2012
+ `${JSON.stringify({
2013
+ sequence: priorEvents.length + 1,
2014
+ type: "execution_closed",
2015
+ runId,
2016
+ decision,
2017
+ ...(supersessionStatus === null
2018
+ ? {}
2019
+ : { statusCode: supersessionStatus.status }),
2020
+ artifactSha256: closeout.artifactSha256,
2021
+ })}\n`,
2022
+ );
2023
+ return {
2024
+ runId,
2025
+ closeoutDecision: decision,
2026
+ ...(supersessionStatus === null
2027
+ ? {}
2028
+ : {
2029
+ closeoutStatus: supersessionStatus.status,
2030
+ businessGoalIncomplete: true,
2031
+ replacementPlanRequired: true,
2032
+ nextAllowedAction: "plan_replacement_execution",
2033
+ }),
2034
+ closeoutPath: relativeToWorkspace(root, closeoutPath),
2035
+ closeoutArtifactSha256: closeout.artifactSha256,
2036
+ releasedLeaseIds,
2037
+ authorizationGranted: false,
2038
+ };
2039
+ });
2040
+ }