@kungfu-tech/buildchain 3.0.5 → 3.0.6-alpha.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 (83) hide show
  1. package/README.md +31 -0
  2. package/actions/macos-credential-island/README.md +8 -0
  3. package/bin/buildchain.mjs +1 -1
  4. package/contracts/auditable-demo-media-profiles-v1.json +61 -0
  5. package/contracts/auditable-demo-scenario-v1.schema.json +164 -0
  6. package/contracts/evidence/auditable-demo-responsive-web-delivery-v1.json +3 -3
  7. package/contracts/evidence/auditable-demo-web-delivery-v1.json +3 -3
  8. package/dist/site/buildchain-contract.json +107 -26
  9. package/dist/site/buildchain-site.json +121 -49
  10. package/dist/site/capability-registry.json +3 -3
  11. package/dist/site/cli-registry.json +9 -3
  12. package/dist/site/controller-registry.json +27 -3
  13. package/dist/site/kfd-claims.json +101 -15
  14. package/dist/site/kfd-upstream-aggregate.json +1 -1
  15. package/dist/site/manual-registry.json +10 -9
  16. package/dist/site/node-api-registry.json +540 -31
  17. package/dist/site/page-registry.json +105 -29
  18. package/dist/site/public-surface-audit.json +184 -11
  19. package/dist/site/publication-authority-registry.json +62 -1
  20. package/dist/site/publication-registry.json +4 -4
  21. package/dist/site/site-manifest.json +13 -13
  22. package/dist/site/workflow-registry.json +118 -4
  23. package/docs/MAP.md +4 -1
  24. package/docs/auditable-demo.md +90 -7
  25. package/docs/aws-us-elastic-runner-burst-plane.md +151 -16
  26. package/docs/cli-reference.md +35 -2
  27. package/docs/dev-alpha-candidate-patrol.md +14 -5
  28. package/docs/dev-qualification-patrol.md +108 -0
  29. package/docs/node-api-reference.md +123 -72
  30. package/docs/publish-transaction.md +7 -5
  31. package/docs/release-flow.md +4 -0
  32. package/docs/release-governance.md +39 -0
  33. package/docs/release-propagation.md +93 -0
  34. package/docs/reusable-build-surface.md +53 -12
  35. package/docs/stable-candidate-patrol.md +5 -2
  36. package/package.json +1 -1
  37. package/packages/core/buildchain-contract.js +36 -1
  38. package/packages/core/buildchain-publication-authority.js +3 -0
  39. package/packages/core/public-surface-audit.js +4 -35
  40. package/packages/core/release-propagation-agent-entry.js +185 -0
  41. package/packages/core/release-propagation-pickup.js +387 -0
  42. package/packages/core/release-propagation-push.js +293 -0
  43. package/packages/core/release-propagation-release.js +61 -18
  44. package/packages/core/release-propagation-stage-evidence.js +36 -0
  45. package/packages/core/release-propagation-work.js +8 -4
  46. package/packages/core/release-propagation.js +27 -2
  47. package/packages/core/workflow-call-contract.js +308 -0
  48. package/packages/core/workflow-yaml-contract.js +272 -0
  49. package/scripts/artifact-signing-controller-core.mjs +525 -0
  50. package/scripts/artifact-signing-controller.mjs +302 -0
  51. package/scripts/artifact-signing-delegation.mjs +51 -3
  52. package/scripts/auditable-demo-platform.mjs +564 -0
  53. package/scripts/auditable-demo-renditions.mjs +7 -2
  54. package/scripts/auditable-demo-transport-smoke.mjs +176 -0
  55. package/scripts/auditable-demo.mjs +27 -21
  56. package/scripts/aws-macos-jit-controller-core.mjs +389 -0
  57. package/scripts/aws-macos-jit-controller-runtime.mjs +82 -0
  58. package/scripts/aws-macos-jit-controller.mjs +558 -0
  59. package/scripts/aws-macos-jit-job-controller.mjs +401 -0
  60. package/scripts/aws-windows-jit-campaign-core.mjs +296 -0
  61. package/scripts/aws-windows-jit-campaign.mjs +202 -0
  62. package/scripts/aws-windows-jit-controller-core.mjs +20 -2
  63. package/scripts/aws-windows-jit-controller.mjs +184 -109
  64. package/scripts/aws-windows-jit-core.mjs +21 -3
  65. package/scripts/aws-windows-jit.mjs +2 -0
  66. package/scripts/build-standalone-binary.mjs +6 -0
  67. package/scripts/buildchain-cli-help.mjs +2 -1
  68. package/scripts/capture-package-release-propagation.mjs +24 -1
  69. package/scripts/check-inventory.mjs +6 -0
  70. package/scripts/compiler-cache-evidence.mjs +90 -7
  71. package/scripts/dev-alpha-candidate-patrol.mjs +80 -5
  72. package/scripts/dev-pr-auto-merge.mjs +4 -4
  73. package/scripts/dev-qualification-patrol.mjs +594 -0
  74. package/scripts/dispatch-artifact-signing-authority.mjs +312 -61
  75. package/scripts/finalize-native-artifact-signing-result.mjs +37 -15
  76. package/scripts/generate-site-bundle.mjs +5 -0
  77. package/scripts/inspect-artifact-signing-requests.mjs +12 -0
  78. package/scripts/locked-source-checkout.mjs +17 -3
  79. package/scripts/release-propagation.mjs +150 -2
  80. package/scripts/run-lifecycle-core.mjs +25 -0
  81. package/scripts/site-capability-metadata.mjs +1 -1
  82. package/scripts/stable-candidate-patrol.mjs +30 -4
  83. package/scripts/workflow-call-contract.mjs +133 -0
@@ -0,0 +1,302 @@
1
+ #!/usr/bin/env node
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { pathToFileURL } from "node:url";
5
+
6
+ import {
7
+ RECEIPT_CONTRACT,
8
+ artifactSigningControlRequestOutputs,
9
+ assertArtifactSigningControlRequestContext,
10
+ digestDocument,
11
+ normalizeControllerStatus,
12
+ readArtifactSigningControlRequest,
13
+ required,
14
+ sealArtifactSigningControlRequest,
15
+ validateArtifactSigningControlRequest,
16
+ validateArtifactSigningControllerReceipt,
17
+ } from "./artifact-signing-controller-core.mjs";
18
+ import {
19
+ assertArtifactSigningDelegationContext,
20
+ artifactSigningDelegationOutputs,
21
+ createArtifactSigningDelegation,
22
+ readArtifactSigningDelegation,
23
+ } from "./artifact-signing-delegation.mjs";
24
+ import { writeGitHubOutputs } from "./build-contract-core.mjs";
25
+
26
+ export {
27
+ artifactSigningCorrelation,
28
+ artifactSigningRequestRoot,
29
+ artifactSigningControlRequestOutputs,
30
+ assertArtifactSigningControlRequestContext,
31
+ createArtifactSigningControlRequest,
32
+ readArtifactSigningControlRequest,
33
+ sealArtifactSigningControlRequest,
34
+ validateArtifactSigningControlRequest,
35
+ validateArtifactSigningControllerReceipt,
36
+ } from "./artifact-signing-controller-core.mjs";
37
+
38
+ function authorityRuntimeShaFromEnvironment() {
39
+ return process.env.BUILDCHAIN_AUTHORITY_RUNTIME_SHA || "";
40
+ }
41
+
42
+ export function settleArtifactSigningControl({
43
+ request,
44
+ authorityStatus = process.env.BUILDCHAIN_AUTHORITY_STATUS || "failed",
45
+ authorityRunId = process.env.BUILDCHAIN_AUTHORITY_RUN_ID || "",
46
+ authorityRuntimeSha = authorityRuntimeShaFromEnvironment(),
47
+ authorityRunUrl = process.env.BUILDCHAIN_AUTHORITY_RUN_URL || "",
48
+ authorityResultArtifact = process.env.BUILDCHAIN_SIGNING_RESULT_ARTIFACT ||
49
+ "",
50
+ authorityCorrelationId = process.env.BUILDCHAIN_AUTHORITY_CORRELATION_ID ||
51
+ "",
52
+ authorityConclusion = process.env.BUILDCHAIN_AUTHORITY_CONCLUSION || "",
53
+ controllerRepository = process.env.GITHUB_REPOSITORY,
54
+ controllerRunId = process.env.GITHUB_RUN_ID,
55
+ controllerRunAttempt = process.env.GITHUB_RUN_ATTEMPT || "1",
56
+ controllerJob = process.env.GITHUB_JOB || "artifact-signing-control",
57
+ controllerRunnerOs = process.env.RUNNER_OS || "Linux",
58
+ controllerStartedAt = process.env.BUILDCHAIN_CONTROLLER_STARTED_AT ||
59
+ new Date().toISOString(),
60
+ controllerCompletedAt = process.env.BUILDCHAIN_CONTROLLER_COMPLETED_AT ||
61
+ new Date().toISOString(),
62
+ receiptPath = process.env.BUILDCHAIN_SIGNING_CONTROLLER_RECEIPT_PATH,
63
+ delegationPath = process.env.BUILDCHAIN_SIGNING_DELEGATION_PATH,
64
+ } = {}) {
65
+ const control = validateArtifactSigningControlRequest(request);
66
+ const status = normalizeControllerStatus(authorityStatus);
67
+ const expectedStatus = control.request.count === 0 ? "skipped" : "succeeded";
68
+ const qualifying =
69
+ status === expectedStatus &&
70
+ (control.request.count === 0 || authorityConclusion === "success");
71
+ if (
72
+ authorityCorrelationId &&
73
+ authorityCorrelationId !== control.authority.correlationId
74
+ ) {
75
+ throw new Error("authority correlation does not match control request");
76
+ }
77
+ if (
78
+ authorityResultArtifact &&
79
+ authorityResultArtifact !== control.authority.resultArtifact
80
+ ) {
81
+ throw new Error("authority result artifact does not match control request");
82
+ }
83
+ const receipt = {
84
+ schemaVersion: 1,
85
+ contract: RECEIPT_CONTRACT,
86
+ requestDigest: control.digest,
87
+ source: control.source,
88
+ runtime: {
89
+ repository: control.runtime.repository,
90
+ sha: control.runtime.sha,
91
+ },
92
+ platform: control.platform,
93
+ request: control.request,
94
+ authority: {
95
+ repository: control.authority.repository,
96
+ runtimeSha: authorityRuntimeSha,
97
+ runId: control.request.count > 0 ? authorityRunId : "",
98
+ runUrl: control.request.count > 0 ? authorityRunUrl : "",
99
+ resultArtifact: control.request.count > 0 ? authorityResultArtifact : "",
100
+ correlationId: control.authority.correlationId,
101
+ conclusion:
102
+ control.request.count > 0
103
+ ? authorityConclusion || status
104
+ : "not-required",
105
+ },
106
+ controller: {
107
+ repository: controllerRepository,
108
+ runId: controllerRunId,
109
+ runAttempt: Number(controllerRunAttempt),
110
+ job: controllerJob,
111
+ runnerOs: controllerRunnerOs,
112
+ startedAt: controllerStartedAt,
113
+ completedAt: controllerCompletedAt,
114
+ status,
115
+ },
116
+ qualifying,
117
+ };
118
+ receipt.digest = digestDocument(receipt);
119
+ const validatedReceipt = validateArtifactSigningControllerReceipt(receipt);
120
+ const resolvedReceiptPath = path.resolve(
121
+ required(receiptPath, "controller receipt path"),
122
+ );
123
+ fs.mkdirSync(path.dirname(resolvedReceiptPath), { recursive: true });
124
+ fs.writeFileSync(
125
+ resolvedReceiptPath,
126
+ `${JSON.stringify(validatedReceipt, null, 2)}\n`,
127
+ );
128
+
129
+ let delegation = null;
130
+ if (validatedReceipt.qualifying) {
131
+ delegation = createArtifactSigningDelegation({
132
+ sourceRepository: control.source.repository,
133
+ sourceRunId: control.source.runId,
134
+ sourceRunAttempt: control.source.runAttempt,
135
+ sourceSha: control.source.sha,
136
+ sourceTreeSha: control.source.treeSha,
137
+ runtimeRepository: control.runtime.repository,
138
+ runtimeSha: control.runtime.sha,
139
+ platformId: control.platform.id,
140
+ platformName: control.platform.name,
141
+ requestCount: control.request.count,
142
+ requestArtifact: control.request.artifact,
143
+ requestRoot: control.request.root,
144
+ authorityRunId: validatedReceipt.authority.runId,
145
+ authorityRuntimeSha: validatedReceipt.authority.runtimeSha,
146
+ resultArtifact: validatedReceipt.authority.resultArtifact,
147
+ artifactName: control.artifact.name,
148
+ manifestArtifact: control.artifact.manifestArtifact,
149
+ diagnosticsArtifact: control.artifact.diagnosticsArtifact,
150
+ workingDirectory: control.workingDirectory,
151
+ controllerMode: "detached",
152
+ controllerReceiptDigest: validatedReceipt.digest,
153
+ });
154
+ const resolvedDelegationPath = path.resolve(
155
+ required(delegationPath, "delegation path"),
156
+ );
157
+ fs.mkdirSync(path.dirname(resolvedDelegationPath), { recursive: true });
158
+ fs.writeFileSync(
159
+ resolvedDelegationPath,
160
+ `${JSON.stringify(delegation, null, 2)}\n`,
161
+ );
162
+ }
163
+ return { receipt: validatedReceipt, delegation };
164
+ }
165
+
166
+ export function readArtifactSigningControllerReceipt(
167
+ inputPath = process.env.BUILDCHAIN_SIGNING_CONTROLLER_RECEIPT_PATH,
168
+ ) {
169
+ const target = path.resolve(required(inputPath, "controller receipt path"));
170
+ return validateArtifactSigningControllerReceipt(
171
+ JSON.parse(fs.readFileSync(target, "utf8")),
172
+ );
173
+ }
174
+
175
+ export function assertArtifactSigningControllerReceipt({
176
+ request,
177
+ receipt,
178
+ delegation,
179
+ }) {
180
+ const control = validateArtifactSigningControlRequest(request);
181
+ const result = validateArtifactSigningControllerReceipt(receipt);
182
+ const finalDelegation = assertArtifactSigningDelegationContext(delegation, {
183
+ sourceRepository: control.source.repository,
184
+ sourceRunId: control.source.runId,
185
+ sourceRunAttempt: control.source.runAttempt,
186
+ sourceSha: control.source.sha,
187
+ runtimeRepository: control.runtime.repository,
188
+ runtimeSha: control.runtime.sha,
189
+ platformId: control.platform.id,
190
+ });
191
+ const comparisons = [
192
+ [result.requestDigest, control.digest, "control request digest"],
193
+ [result.source.treeSha, control.source.treeSha, "source tree SHA"],
194
+ [result.request.root, control.request.root, "request root"],
195
+ [result.request.artifact, control.request.artifact, "request artifact"],
196
+ [
197
+ result.authority.correlationId,
198
+ control.authority.correlationId,
199
+ "correlation",
200
+ ],
201
+ [
202
+ result.authority.runId,
203
+ finalDelegation.authority.runId,
204
+ "authority run ID",
205
+ ],
206
+ [
207
+ result.authority.runtimeSha,
208
+ finalDelegation.authority.runtimeSha,
209
+ "authority runtime SHA",
210
+ ],
211
+ [
212
+ result.authority.resultArtifact,
213
+ finalDelegation.authority.resultArtifact,
214
+ "authority result artifact",
215
+ ],
216
+ [
217
+ finalDelegation.controller.receiptDigest,
218
+ result.digest,
219
+ "controller receipt digest",
220
+ ],
221
+ [
222
+ finalDelegation.request.root,
223
+ result.request.root,
224
+ "delegation request root",
225
+ ],
226
+ ];
227
+ for (const [actual, expected, label] of comparisons) {
228
+ if (actual !== expected) {
229
+ throw new Error(`artifact signing controller ${label} mismatch`);
230
+ }
231
+ }
232
+ if (!result.qualifying) {
233
+ throw new Error("artifact signing controller receipt is not qualifying");
234
+ }
235
+ return { request: control, receipt: result, delegation: finalDelegation };
236
+ }
237
+
238
+ function expectedContext() {
239
+ return {
240
+ sourceRepository: process.env.BUILDCHAIN_EXPECTED_SOURCE_REPOSITORY || "",
241
+ sourceRunId: process.env.BUILDCHAIN_EXPECTED_SOURCE_RUN_ID || "",
242
+ sourceRunAttempt: process.env.BUILDCHAIN_EXPECTED_SOURCE_RUN_ATTEMPT || "",
243
+ sourceSha: process.env.BUILDCHAIN_EXPECTED_SOURCE_SHA || "",
244
+ sourceTreeSha: process.env.BUILDCHAIN_EXPECTED_SOURCE_TREE_SHA || "",
245
+ runtimeRepository: process.env.BUILDCHAIN_EXPECTED_RUNTIME_REPOSITORY || "",
246
+ runtimeSha: process.env.BUILDCHAIN_EXPECTED_RUNTIME_SHA || "",
247
+ platformId: process.env.BUILDCHAIN_EXPECTED_PLATFORM_ID || "",
248
+ };
249
+ }
250
+
251
+ if (
252
+ process.argv[1] &&
253
+ import.meta.url === pathToFileURL(process.argv[1]).href
254
+ ) {
255
+ try {
256
+ const mode = process.argv[2] || "seal";
257
+ if (mode === "seal") {
258
+ sealArtifactSigningControlRequest();
259
+ } else if (mode === "outputs") {
260
+ const request = assertArtifactSigningControlRequestContext(
261
+ readArtifactSigningControlRequest(),
262
+ expectedContext(),
263
+ );
264
+ writeGitHubOutputs(artifactSigningControlRequestOutputs(request));
265
+ } else if (mode === "settle") {
266
+ const request = assertArtifactSigningControlRequestContext(
267
+ readArtifactSigningControlRequest(),
268
+ expectedContext(),
269
+ );
270
+ const { receipt, delegation } = settleArtifactSigningControl({ request });
271
+ writeGitHubOutputs({
272
+ "controller-status": receipt.controller.status,
273
+ "controller-receipt-digest": receipt.digest,
274
+ "controller-qualifying": String(receipt.qualifying),
275
+ "delegation-created": String(Boolean(delegation)),
276
+ });
277
+ } else if (mode === "verify") {
278
+ const request = assertArtifactSigningControlRequestContext(
279
+ readArtifactSigningControlRequest(),
280
+ expectedContext(),
281
+ );
282
+ const checked = assertArtifactSigningControllerReceipt({
283
+ request,
284
+ receipt: readArtifactSigningControllerReceipt(),
285
+ delegation: readArtifactSigningDelegation(),
286
+ });
287
+ writeGitHubOutputs({
288
+ ...artifactSigningDelegationOutputs(checked.delegation),
289
+ "request-root": checked.receipt.request.root,
290
+ "controller-receipt-digest": checked.receipt.digest,
291
+ "controller-status": checked.receipt.controller.status,
292
+ });
293
+ } else {
294
+ throw new Error(`unsupported artifact signing controller mode: ${mode}`);
295
+ }
296
+ } catch (error) {
297
+ console.error(
298
+ `::error::${String(error?.message || error).replace(/\r?\n/gu, "%0A")}`,
299
+ );
300
+ process.exitCode = 1;
301
+ }
302
+ }
@@ -22,6 +22,14 @@ function optional(value, label) {
22
22
  return normalized;
23
23
  }
24
24
 
25
+ function sha256Root(value, label) {
26
+ const normalized = optional(value, label);
27
+ if (normalized && !/^sha256:[0-9a-f]{64}$/u.test(normalized)) {
28
+ throw new Error(`${label} must be a canonical sha256 root`);
29
+ }
30
+ return normalized;
31
+ }
32
+
25
33
  function exactSha(value, label) {
26
34
  const normalized = required(value, label);
27
35
  if (!/^[0-9a-f]{40}$/u.test(normalized))
@@ -97,8 +105,13 @@ export function validateArtifactSigningDelegation(value) {
97
105
  requestCount > 0
98
106
  ? required(value.request?.artifact, "request.artifact")
99
107
  : optional(value.request?.artifact, "request.artifact"),
108
+ root: sha256Root(value.request?.root, "request.root"),
100
109
  },
101
110
  authority: {
111
+ runtimeSha:
112
+ requestCount > 0
113
+ ? exactSha(value.authority?.runtimeSha, "authority.runtimeSha")
114
+ : optional(value.authority?.runtimeSha, "authority.runtimeSha"),
102
115
  runId:
103
116
  requestCount > 0
104
117
  ? required(value.authority?.runId, "authority.runId")
@@ -129,15 +142,32 @@ export function validateArtifactSigningDelegation(value) {
129
142
  value.workingDirectory || ".",
130
143
  "workingDirectory",
131
144
  ),
145
+ controller: {
146
+ mode: optional(value.controller?.mode, "controller.mode"),
147
+ receiptDigest: sha256Root(
148
+ value.controller?.receiptDigest,
149
+ "controller.receiptDigest",
150
+ ),
151
+ },
132
152
  };
133
153
  if (
134
154
  requestCount === 0 &&
135
- (delegation.authority.runId || delegation.authority.resultArtifact)
155
+ (delegation.authority.runtimeSha ||
156
+ delegation.authority.runId ||
157
+ delegation.authority.resultArtifact)
136
158
  ) {
137
159
  throw new Error(
138
160
  "unsigned delegation must not contain authority result coordinates",
139
161
  );
140
162
  }
163
+ if (
164
+ Boolean(delegation.controller.mode) !==
165
+ Boolean(delegation.controller.receiptDigest)
166
+ ) {
167
+ throw new Error(
168
+ "delegation controller mode and receipt digest must be provided together",
169
+ );
170
+ }
141
171
  return delegation;
142
172
  }
143
173
 
@@ -153,12 +183,17 @@ export function createArtifactSigningDelegation({
153
183
  platformName = process.env.BUILDCHAIN_PLATFORM_NAME,
154
184
  requestCount = process.env.BUILDCHAIN_SIGNING_REQUEST_COUNT || "0",
155
185
  requestArtifact = process.env.BUILDCHAIN_SIGNING_REQUEST_ARTIFACT || "",
186
+ requestRoot = process.env.BUILDCHAIN_SIGNING_REQUEST_ROOT_DIGEST || "",
156
187
  authorityRunId = process.env.BUILDCHAIN_AUTHORITY_RUN_ID || "",
188
+ authorityRuntimeSha = process.env.BUILDCHAIN_AUTHORITY_RUNTIME_SHA || "",
157
189
  resultArtifact = process.env.BUILDCHAIN_SIGNING_RESULT_ARTIFACT || "",
158
190
  artifactName = process.env.BUILDCHAIN_ARTIFACT_NAME,
159
191
  manifestArtifact = process.env.BUILDCHAIN_MANIFEST_ARTIFACT_NAME,
160
192
  diagnosticsArtifact = process.env.BUILDCHAIN_DIAGNOSTICS_ARTIFACT_NAME,
161
193
  workingDirectory = process.env.BUILDCHAIN_SIGNING_CWD || ".",
194
+ controllerMode = process.env.BUILDCHAIN_SIGNING_CONTROLLER_MODE || "",
195
+ controllerReceiptDigest = process.env
196
+ .BUILDCHAIN_SIGNING_CONTROLLER_RECEIPT_DIGEST || "",
162
197
  } = {}) {
163
198
  return validateArtifactSigningDelegation({
164
199
  schemaVersion: 1,
@@ -172,10 +207,22 @@ export function createArtifactSigningDelegation({
172
207
  },
173
208
  runtime: { repository: runtimeRepository, sha: runtimeSha },
174
209
  platform: { id: platformId, name: platformName },
175
- request: { count: Number(requestCount), artifact: requestArtifact },
176
- authority: { runId: authorityRunId, resultArtifact },
210
+ request: {
211
+ count: Number(requestCount),
212
+ artifact: requestArtifact,
213
+ root: requestRoot,
214
+ },
215
+ authority: {
216
+ runtimeSha: authorityRuntimeSha,
217
+ runId: authorityRunId,
218
+ resultArtifact,
219
+ },
177
220
  artifact: { name: artifactName, manifestArtifact, diagnosticsArtifact },
178
221
  workingDirectory,
222
+ controller: {
223
+ mode: controllerMode,
224
+ receiptDigest: controllerReceiptDigest,
225
+ },
179
226
  });
180
227
  }
181
228
 
@@ -205,6 +252,7 @@ export function artifactSigningDelegationOutputs(delegation) {
205
252
  "request-count": String(value.request.count),
206
253
  "request-artifact": value.request.artifact,
207
254
  "authority-run-id": value.authority.runId,
255
+ "authority-runtime-sha": value.authority.runtimeSha,
208
256
  "result-artifact": value.authority.resultArtifact,
209
257
  "artifact-name": value.artifact.name,
210
258
  "manifest-artifact-name": value.artifact.manifestArtifact,