@kungfu-tech/buildchain 3.0.9-alpha.10 → 3.0.9-alpha.12

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 (31) hide show
  1. package/actions/promote-buildchain-ref/README.md +4 -0
  2. package/bin/internal/trust-release-release-handlers.mjs +1 -0
  3. package/dist/site/buildchain-contract.json +211 -26
  4. package/dist/site/buildchain-site.json +30 -15
  5. package/dist/site/capability-registry.json +1 -1
  6. package/dist/site/cli-registry.json +2 -1
  7. package/dist/site/controller-registry.json +6 -2
  8. package/dist/site/kfd-claims.json +34 -7
  9. package/dist/site/kfd-upstream-aggregate.json +1 -1
  10. package/dist/site/manual-registry.json +3 -3
  11. package/dist/site/node-api-registry.json +276 -24
  12. package/dist/site/page-registry.json +23 -8
  13. package/dist/site/public-surface-audit.json +9 -6
  14. package/dist/site/publication-registry.json +4 -4
  15. package/dist/site/release-provenance.json +2 -0
  16. package/dist/site/site-manifest.json +7 -7
  17. package/dist/site/workflow-registry.json +10 -7
  18. package/docs/cli-reference.md +2 -2
  19. package/docs/node-api-reference.md +61 -40
  20. package/docs/release-passport.md +10 -0
  21. package/package.json +3 -1
  22. package/packages/core/buildchain-compatibility-proof.js +66 -0
  23. package/packages/core/buildchain-delivery-self-dogfood.js +395 -0
  24. package/packages/core/dev-delivery-warrant.js +1 -0
  25. package/packages/core/published-delivery-authority.js +247 -0
  26. package/packages/core/release-passport.js +8 -1
  27. package/scripts/buildchain-cli-help.mjs +1 -0
  28. package/scripts/check-inventory.mjs +1 -1
  29. package/scripts/dev-delivery-warrant.mjs +1 -1
  30. package/scripts/site-capability-metadata.mjs +2 -0
  31. package/scripts/workflow-call-contract.mjs +1 -1
@@ -404,6 +404,16 @@ inspect `buildchain.release.json` and know whether the released package
404
404
  actually exposes no more and no less than the declared collaboration interface,
405
405
  instead of trusting docs or release notes.
406
406
 
407
+ ### Adopter delivery binding
408
+
409
+ Pass a completed protocol-neutral adopter delivery gate result as JSON or a
410
+ path with `--adopter-delivery-json`. The collector validates the rooted gate
411
+ closure and writes the same non-qualifying `adopterDelivery` binding into both
412
+ `buildchain.release.json` and `artifact-evidence.json`. Release verification
413
+ fails closed if the product identity, artifact root, gate root, or either copy
414
+ is substituted. Reusable promotion callers can forward the same value with
415
+ `release-passport-adopter-delivery-json`.
416
+
407
417
  ### KFD support projection
408
418
 
409
419
  Pass the standard full-cut declaration with `--kfd-adopter-manifest-json`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kungfu-tech/buildchain",
3
- "version": "3.0.9-alpha.10",
3
+ "version": "3.0.9-alpha.12",
4
4
  "private": false,
5
5
  "description": "Buildchain Release Passport, release governance, CLI toolkit, and site facts.",
6
6
  "repository": "https://github.com/kungfu-systems/buildchain",
@@ -39,6 +39,8 @@
39
39
  "./kfd-adopter-category-driver": "./packages/core/kfd-adopter-category-driver.js",
40
40
  "./buildchain-delivery-infrastructure": "./packages/core/buildchain-delivery-infrastructure.js",
41
41
  "./buildchain-delivery-bootstrap": "./packages/core/buildchain-delivery-bootstrap.js",
42
+ "./buildchain-delivery-self-dogfood": "./packages/core/buildchain-delivery-self-dogfood.js",
43
+ "./published-delivery-authority": "./packages/core/published-delivery-authority.js",
42
44
  "./legacy-kfd-adopter-driver": "./packages/core/legacy-kfd-adopter-driver.js",
43
45
  "./adopter-delivery-passport": "./packages/core/adopter-delivery-passport.js",
44
46
  "./adopter-delivery-vectors": "./packages/core/adopter-delivery-vectors.js",
@@ -132,6 +132,72 @@ const HISTORICAL_ACCEPTANCES = [
132
132
  commit: "34fad9d3a94c450d75c0d06fd6ed00470c992ff7",
133
133
  },
134
134
  },
135
+ {
136
+ proofId: "reusable-build-a6a353-to-dfbedd",
137
+ surfaceId: "reusable-build",
138
+ surfaceKind: "workflow",
139
+ sourceBreakingDigest: "sha256:a6a35370d6b0d0f46e1b2712dcc01961fe53c2febde95409a27a485c10a36650",
140
+ targetBreakingDigest: "sha256:dfbedd543ae0c067982b5c8c02d98dd2f7f7df88752be97fb330da6b0ba30faa",
141
+ evidence: {
142
+ kind: "protected-pull-request-contract-acceptance",
143
+ pullRequest: "https://github.com/kungfu-systems/buildchain/pull/2089",
144
+ protectedBase: "dev/v3/v3.0",
145
+ sourceCommit: "1a6cb874bc6f1611f3eef607e711d3532798e9e7",
146
+ mergeCommit: "71a75f21159b994241ec7cb2c50f7a150c5d440b",
147
+ contractDigest: "sha256:7c2a7c132a2b2722f70f148b81048147047d4d2c46cf33f7cd2dc158aec092e0",
148
+ compatibilityDigest: "sha256:61af7d0871220bc0909008bdc571905ad500cccf853e7841bc5d462a34b2d436",
149
+ },
150
+ cut: {
151
+ kind: "protected-git-cut",
152
+ repository: "kungfu-systems/buildchain",
153
+ protectedBase: "dev/v3/v3.0",
154
+ commit: "71a75f21159b994241ec7cb2c50f7a150c5d440b",
155
+ },
156
+ },
157
+ {
158
+ proofId: "web-surface-da569f-to-27f0cb",
159
+ surfaceId: "web-surface",
160
+ surfaceKind: "workflow",
161
+ sourceBreakingDigest: "sha256:da569f90374e878948e3d5160ed9929338ce0572473ca8ee54867b0fe1aaeace",
162
+ targetBreakingDigest: "sha256:27f0cb9c7d97288850d215be8696b323471c41fd1cdf3a2ff3ebf21f62541960",
163
+ evidence: {
164
+ kind: "protected-pull-request-contract-acceptance",
165
+ pullRequest: "https://github.com/kungfu-systems/buildchain/pull/2089",
166
+ protectedBase: "dev/v3/v3.0",
167
+ sourceCommit: "1a6cb874bc6f1611f3eef607e711d3532798e9e7",
168
+ mergeCommit: "71a75f21159b994241ec7cb2c50f7a150c5d440b",
169
+ contractDigest: "sha256:7c2a7c132a2b2722f70f148b81048147047d4d2c46cf33f7cd2dc158aec092e0",
170
+ compatibilityDigest: "sha256:61af7d0871220bc0909008bdc571905ad500cccf853e7841bc5d462a34b2d436",
171
+ },
172
+ cut: {
173
+ kind: "protected-git-cut",
174
+ repository: "kungfu-systems/buildchain",
175
+ protectedBase: "dev/v3/v3.0",
176
+ commit: "71a75f21159b994241ec7cb2c50f7a150c5d440b",
177
+ },
178
+ },
179
+ {
180
+ proofId: "release-propagation-d7a1f1-to-b873ce",
181
+ surfaceId: "controller:release-propagation",
182
+ surfaceKind: "controller",
183
+ sourceBreakingDigest: "sha256:d7a1f15990ce8bd13149474888232c7d4451dd2a49bebf4d4ce1336695da430e",
184
+ targetBreakingDigest: "sha256:b873ceb65618972bea615afcb9c616c138ce834b3246ec7237ef87c1618d68bd",
185
+ evidence: {
186
+ kind: "protected-pull-request-contract-acceptance",
187
+ pullRequest: "https://github.com/kungfu-systems/buildchain/pull/2143",
188
+ protectedBase: "dev/v3/v3.0",
189
+ sourceCommit: "b63aff4dd63ad6017b8f48e1c690f595a9c832a2",
190
+ mergeCommit: "487ee09ca4832ffd15607db00060df4c0839fbae",
191
+ contractDigest: "sha256:00c37f8a663387831ba4d066056d0b21d4f3c5f3ea5b0cf84456af332cf8d87e",
192
+ compatibilityDigest: "sha256:3bbcaf835844260ed98414d3bd176667245d12131e13fc748e4c2fae12399691",
193
+ },
194
+ cut: {
195
+ kind: "protected-git-cut",
196
+ repository: "kungfu-systems/buildchain",
197
+ protectedBase: "dev/v3/v3.0",
198
+ commit: "487ee09ca4832ffd15607db00060df4c0839fbae",
199
+ },
200
+ },
135
201
  ];
136
202
 
137
203
  function exactText(value, label) {
@@ -0,0 +1,395 @@
1
+ import { initAdopterManifest } from "@kungfu-tech/kfd/adopter-conformance/toolchain";
2
+
3
+ import { adopterDeliveryGateDigest } from "./adopter-delivery-gate.js";
4
+ import { withPublishedBuildchainDeliveryAuthority } from "./published-delivery-authority.js";
5
+
6
+ export const BUILDCHAIN_DELIVERY_SELF_DOGFOOD_CONTRACT =
7
+ "kungfu-buildchain-delivery-infrastructure-self-dogfood/v1";
8
+
9
+ const ROOT_PATTERN = /^sha256:[0-9a-f]{64}$/;
10
+ const SHA_PATTERN = /^[0-9a-f]{40}$/;
11
+ const BUILDCHAIN_PACKAGE = "@kungfu-tech/buildchain";
12
+ const KFD_PACKAGE = "@kungfu-tech/kfd";
13
+ const PROFILE_REQUIREMENTS = Object.freeze([
14
+ ["adopter-identity", ["declaration"]],
15
+ ["artifact-readback", ["verification"]],
16
+ ["claim-boundary", ["declaration"]],
17
+ ["delivery-policy-cut", ["declaration", "verification"]],
18
+ ["kfd-cut", ["verification"]],
19
+ ["protected-delivery", ["implementation", "review", "verification"]],
20
+ ["source-artifact", ["implementation"]],
21
+ ]);
22
+
23
+ function exactPackage(value, { name, version = "", root = "", label }) {
24
+ if (
25
+ value?.name !== name ||
26
+ typeof value.version !== "string" ||
27
+ value.version.length === 0 ||
28
+ !ROOT_PATTERN.test(value.artifactRoot ?? "")
29
+ ) {
30
+ throw new TypeError(`${label} package identity is incomplete`);
31
+ }
32
+ if (version && value.version !== version) {
33
+ throw new TypeError(`${label} package version does not match its binding`);
34
+ }
35
+ if (root && value.artifactRoot !== root) {
36
+ throw new TypeError(`${label} package root does not match its binding`);
37
+ }
38
+ return structuredClone(value);
39
+ }
40
+
41
+ function authorityFunctions(authorityRuntime) {
42
+ const names = [
43
+ "createBuildchainDeliveryInfrastructureInstanceManifest",
44
+ "verifyBuildchainDeliveryInfrastructureInstance",
45
+ "createAdopterDeliveryGate",
46
+ "createPackageArtifactProfile",
47
+ "createKfdAdopterCategoryProtocolDriver",
48
+ "qualifyBuildchainDeliveryInfrastructureBootstrap",
49
+ ];
50
+ for (const name of names) {
51
+ if (typeof authorityRuntime?.[name] !== "function") {
52
+ throw new TypeError(`authority runtime is missing ${name}`);
53
+ }
54
+ }
55
+ return authorityRuntime;
56
+ }
57
+
58
+ function passed(value, label) {
59
+ if (value?.status !== "passed") {
60
+ throw new Error(
61
+ `${label} failed closed: ${JSON.stringify(value?.issues ?? [])}`,
62
+ );
63
+ }
64
+ return value;
65
+ }
66
+
67
+ function candidateWarrant(candidate) {
68
+ const terminal = candidate?.terminal;
69
+ if (
70
+ candidate?.status !== "merged" ||
71
+ !SHA_PATTERN.test(candidate?.sourceHead ?? "") ||
72
+ !ROOT_PATTERN.test(candidate?.sourceProofRoot ?? "") ||
73
+ terminal?.outcome !== "merged" ||
74
+ !ROOT_PATTERN.test(terminal?.nativeProofRoot ?? "") ||
75
+ !ROOT_PATTERN.test(terminal?.evidenceRoot ?? "")
76
+ ) {
77
+ throw new TypeError("candidate Warrant settlement is incomplete");
78
+ }
79
+ return {
80
+ outcome: "merged",
81
+ sourceHead: candidate.sourceHead,
82
+ sourceProofRoot: candidate.sourceProofRoot,
83
+ nativeProofRoot: terminal.nativeProofRoot,
84
+ integrationProofRoot: terminal.evidenceRoot,
85
+ };
86
+ }
87
+
88
+ function deliveryCut() {
89
+ const protocol = {
90
+ id: "kfd.adopter-category/instance-manifest",
91
+ version: "1.0.0",
92
+ };
93
+ protocol.root = adopterDeliveryGateDigest(protocol);
94
+ const profile = {
95
+ id: "kfd.adopter-category/delivery-infrastructure",
96
+ version: "1.0.0",
97
+ };
98
+ profile.root = adopterDeliveryGateDigest({
99
+ ...profile,
100
+ requirements: PROFILE_REQUIREMENTS,
101
+ });
102
+ return {
103
+ gateRoot: adopterDeliveryGateDigest({
104
+ protocol,
105
+ profile,
106
+ artifactProfile: {
107
+ id: "buildchain.artifact/package",
108
+ version: "1.0.0",
109
+ },
110
+ }),
111
+ protocol,
112
+ profile,
113
+ };
114
+ }
115
+
116
+ function candidateEvidence({
117
+ source,
118
+ artifact,
119
+ authority,
120
+ warrant,
121
+ kfdRoot,
122
+ observedAt,
123
+ }) {
124
+ const roots = {
125
+ "adopter-identity:declaration": source.root,
126
+ "artifact-readback:verification": artifact.root,
127
+ "claim-boundary:declaration": adopterDeliveryGateDigest({
128
+ qualifying: false,
129
+ selfCertified: false,
130
+ releaseAuthorized: false,
131
+ }),
132
+ "delivery-policy-cut:declaration": authority.gateRoot,
133
+ "delivery-policy-cut:verification": warrant.integrationProofRoot,
134
+ "kfd-cut:verification": kfdRoot,
135
+ "protected-delivery:implementation": artifact.root,
136
+ "protected-delivery:review": warrant.sourceProofRoot,
137
+ "protected-delivery:verification": warrant.nativeProofRoot,
138
+ "source-artifact:implementation": source.root,
139
+ };
140
+ return PROFILE_REQUIREMENTS.flatMap(([requirementId, kinds]) =>
141
+ kinds.map((kind) => ({
142
+ requirementId,
143
+ kind,
144
+ coordinate: `evidence://kungfu-systems/buildchain/${requirementId}/${kind}`,
145
+ root: roots[`${requirementId}:${kind}`],
146
+ observedAt,
147
+ })),
148
+ );
149
+ }
150
+
151
+ export function createBuildchainDeliveryInfrastructureSelfDogfood(
152
+ {
153
+ authorityPackage,
154
+ kfdPackage,
155
+ authority,
156
+ candidate,
157
+ instanceId,
158
+ adopterManifest,
159
+ source,
160
+ artifact,
161
+ release,
162
+ evidence = [],
163
+ warrant,
164
+ transitionEvidence,
165
+ verifiedAt,
166
+ maxAgeSeconds,
167
+ } = {},
168
+ authorityRuntime,
169
+ ) {
170
+ const runtime = authorityFunctions(authorityRuntime);
171
+ const boundAuthorityPackage = exactPackage(authorityPackage, {
172
+ name: BUILDCHAIN_PACKAGE,
173
+ version: authority?.version,
174
+ root: authority?.packageRoot,
175
+ label: "Buildchain authority",
176
+ });
177
+ const boundKfdPackage = exactPackage(kfdPackage, {
178
+ name: KFD_PACKAGE,
179
+ version: adopterManifest?.kfdCut?.package?.version,
180
+ root: adopterManifest?.kfdCut?.package?.artifactRoot,
181
+ label: "KFD authority",
182
+ });
183
+ if (candidate?.authorityVersion !== boundAuthorityPackage.version) {
184
+ throw new TypeError(
185
+ "candidate does not name the exact Buildchain N-1 authority",
186
+ );
187
+ }
188
+
189
+ const instanceManifest =
190
+ runtime.createBuildchainDeliveryInfrastructureInstanceManifest({
191
+ instanceId,
192
+ adopterManifest,
193
+ source,
194
+ artifact,
195
+ release,
196
+ evidence,
197
+ });
198
+ const instanceReport = runtime.verifyBuildchainDeliveryInfrastructureInstance(
199
+ instanceManifest,
200
+ {
201
+ adopterManifest,
202
+ verifiedAt,
203
+ maxAgeSeconds,
204
+ },
205
+ );
206
+ if (instanceReport?.valid !== true) {
207
+ throw new Error(
208
+ `delivery-infrastructure instance failed closed: ${JSON.stringify(instanceReport?.issues ?? [])}`,
209
+ );
210
+ }
211
+
212
+ const gateResult = passed(
213
+ runtime
214
+ .createAdopterDeliveryGate({
215
+ drivers: [runtime.createKfdAdopterCategoryProtocolDriver()],
216
+ artifactProfiles: [runtime.createPackageArtifactProfile()],
217
+ })
218
+ .evaluate(
219
+ {
220
+ schemaVersion: 1,
221
+ contract: "kungfu-buildchain-adopter-delivery-request",
222
+ protocol: {
223
+ id: "kfd.adopter-category/instance-manifest",
224
+ version: "1.0.0",
225
+ },
226
+ artifactProfile: {
227
+ id: "buildchain.artifact/package",
228
+ version: "1.0.0",
229
+ },
230
+ project: {
231
+ instanceId,
232
+ adopterId: "kungfu-systems/buildchain",
233
+ },
234
+ artifact: structuredClone(artifact),
235
+ declaration: instanceManifest,
236
+ },
237
+ { adopterManifest, verifiedAt, maxAgeSeconds },
238
+ ),
239
+ "adopter delivery gate",
240
+ );
241
+ const bootstrap = passed(
242
+ runtime.qualifyBuildchainDeliveryInfrastructureBootstrap({
243
+ authority,
244
+ candidate,
245
+ gateResult,
246
+ warrant,
247
+ transitionEvidence,
248
+ }),
249
+ "delivery-infrastructure bootstrap",
250
+ );
251
+
252
+ const result = {
253
+ schemaVersion: 1,
254
+ contract: BUILDCHAIN_DELIVERY_SELF_DOGFOOD_CONTRACT,
255
+ status: "passed",
256
+ authorityRuntime: {
257
+ buildchainPackage: boundAuthorityPackage,
258
+ kfdPackage: boundKfdPackage,
259
+ },
260
+ candidate: structuredClone(candidate),
261
+ roots: {
262
+ adopterManifest: adopterDeliveryGateDigest(adopterManifest),
263
+ instanceManifest: adopterDeliveryGateDigest(instanceManifest),
264
+ instanceReport: adopterDeliveryGateDigest(instanceReport),
265
+ gateResult: gateResult.gateRoot,
266
+ bootstrap: bootstrap.bootstrapRoot,
267
+ warrant: adopterDeliveryGateDigest(warrant),
268
+ },
269
+ instanceManifest,
270
+ instanceReport,
271
+ gateResult,
272
+ bootstrap,
273
+ qualifying: false,
274
+ selfCertified: false,
275
+ releaseAuthorized: false,
276
+ finalAuthority:
277
+ "protected-n-minus-one-runtime-plus-exact-delivery-evidence",
278
+ };
279
+ result.selfDogfoodRoot = adopterDeliveryGateDigest(result);
280
+ return result;
281
+ }
282
+
283
+ export async function createPublishedBuildchainDeliveryInfrastructureSelfDogfood({
284
+ authorityPackages,
285
+ selfDogfood,
286
+ } = {}) {
287
+ return withPublishedBuildchainDeliveryAuthority(
288
+ authorityPackages,
289
+ async ({ packages, authorityRuntime, authorityRoot }) => {
290
+ const result = createBuildchainDeliveryInfrastructureSelfDogfood(
291
+ {
292
+ ...structuredClone(selfDogfood ?? {}),
293
+ authorityPackage: packages.buildchain,
294
+ kfdPackage: packages.kfd,
295
+ },
296
+ authorityRuntime,
297
+ );
298
+ return {
299
+ ...result,
300
+ publishedAuthorityRoot: authorityRoot,
301
+ };
302
+ },
303
+ );
304
+ }
305
+
306
+ export async function createPublishedBuildchainDeliveryInfrastructureCandidateSelfDogfood({
307
+ authorityPackages,
308
+ authoritySourceCommit,
309
+ candidatePackage,
310
+ warrantCandidate,
311
+ source,
312
+ release,
313
+ verifiedAt,
314
+ maxAgeSeconds = 86400,
315
+ } = {}) {
316
+ if (!SHA_PATTERN.test(authoritySourceCommit ?? "")) {
317
+ throw new TypeError("authority source commit is invalid");
318
+ }
319
+ const artifact = exactPackage(candidatePackage, {
320
+ name: BUILDCHAIN_PACKAGE,
321
+ label: "Buildchain candidate",
322
+ });
323
+ if (
324
+ source?.coordinate !==
325
+ `kungfu-systems/buildchain@${warrantCandidate?.sourceHead ?? ""}` ||
326
+ !ROOT_PATTERN.test(source?.root ?? "") ||
327
+ !ROOT_PATTERN.test(release?.root ?? "")
328
+ ) {
329
+ throw new TypeError("candidate source or release binding is incomplete");
330
+ }
331
+ const warrant = candidateWarrant(warrantCandidate);
332
+ const cut = deliveryCut();
333
+ const authority = {
334
+ version: authorityPackages?.buildchain?.version,
335
+ sourceCommit: authoritySourceCommit,
336
+ packageRoot: authorityPackages?.buildchain?.artifactRoot,
337
+ ...cut,
338
+ protected: true,
339
+ published: true,
340
+ };
341
+ const candidate = {
342
+ version: artifact.version,
343
+ sourceCommit: warrant.sourceHead,
344
+ packageRoot: artifact.artifactRoot,
345
+ ...cut,
346
+ authorityVersion: authority.version,
347
+ };
348
+ const adopterManifest = initAdopterManifest({
349
+ manifestId: `buildchain-delivery-infrastructure-${artifact.version}`,
350
+ adopterId: "kungfu-systems/buildchain",
351
+ artifactKind: "package",
352
+ artifactCoordinate: `${artifact.name}@${artifact.version}`,
353
+ artifactRoot: artifact.artifactRoot,
354
+ scope: "Buildchain delivery infrastructure release candidate self-dogfood",
355
+ packageArtifactRoot: authorityPackages?.kfd?.artifactRoot,
356
+ verifiedAt,
357
+ maxAgeSeconds,
358
+ });
359
+ adopterManifest.releaseBindings.push({
360
+ id: `buildchain-${artifact.version}`,
361
+ artifact: {
362
+ kind: "package",
363
+ coordinate: `${artifact.name}@${artifact.version}`,
364
+ root: artifact.artifactRoot,
365
+ },
366
+ releasePassport: structuredClone(release),
367
+ kfdPackageRoot: authorityPackages.kfd.artifactRoot,
368
+ });
369
+ const evidence = candidateEvidence({
370
+ source,
371
+ artifact: adopterManifest.releaseBindings[0].artifact,
372
+ authority,
373
+ warrant,
374
+ kfdRoot: authorityPackages.kfd.artifactRoot,
375
+ observedAt: verifiedAt,
376
+ });
377
+ const result =
378
+ await createPublishedBuildchainDeliveryInfrastructureSelfDogfood({
379
+ authorityPackages,
380
+ selfDogfood: {
381
+ authority,
382
+ candidate,
383
+ instanceId: `kungfu-systems/buildchain@${artifact.version}`,
384
+ adopterManifest,
385
+ source,
386
+ artifact: adopterManifest.releaseBindings[0].artifact,
387
+ release,
388
+ evidence,
389
+ warrant,
390
+ verifiedAt,
391
+ maxAgeSeconds,
392
+ },
393
+ });
394
+ return { ...result, adopterManifest, deliveryEvidence: evidence };
395
+ }
@@ -610,6 +610,7 @@ export function closeDevDeliveryWarrant(queueInput, warrant, { outcome, evidence
610
610
  closedAt: currentTime,
611
611
  fencingToken: active.fencingToken,
612
612
  leaseGeneration: active.generation,
613
+ ...(active.nativeProofRoot ? { nativeProofRoot: exactRoot(active.nativeProofRoot, "nativeProofRoot") } : {}),
613
614
  };
614
615
  queue.activeWarrant = null;
615
616
  return { candidate, active };