@kungfu-tech/buildchain 4.0.1-alpha.2 → 4.0.1-alpha.21

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 (203) hide show
  1. package/actions/release-tail/README.md +8 -0
  2. package/architecture/ci-lane-change-budget.json +187 -0
  3. package/architecture/decisions/0002-next-development-transition.md +101 -0
  4. package/architecture/decisions/0003-two-phase-delivery-warrant.md +152 -0
  5. package/architecture/internal-capabilities.json +211 -8
  6. package/architecture/maintainability-policy.json +113 -28
  7. package/architecture/release-tail-contract-inventory.json +5 -2
  8. package/architecture/v3-core-mechanism-inventory.json +91 -0
  9. package/architecture/v4-adopter-delivery-parity.json +32 -5
  10. package/architecture/v4-capability-state-machine-manifest.json +73 -0
  11. package/architecture/v4-compatibility-facts-parity.json +77 -0
  12. package/architecture/v4-delivery-authority-parity.json +250 -0
  13. package/architecture/v4-delivery-warrant-shadow-fixtures.json +41 -9
  14. package/architecture/v4-floating-consumer-policy.json +6 -0
  15. package/architecture/v4-next-development-parity.json +192 -0
  16. package/architecture/v4-publication-rehearsal-parity.json +84 -0
  17. package/architecture/v4-release-train-parity.json +1 -0
  18. package/architecture/v4-tail-reseal-parity.json +150 -0
  19. package/bin/buildchain.mjs +32 -3
  20. package/bin/internal/adopter-delivery-cli.mjs +70 -0
  21. package/bin/internal/command-registry.mjs +3 -0
  22. package/bin/internal/compatibility-facts-cli.mjs +101 -0
  23. package/contracts/dev-delivery-authority-v2.schema.json +662 -0
  24. package/contracts/fixtures/next-development-transition-v1/anchored-manual-waiting.json +47 -0
  25. package/contracts/fixtures/next-development-transition-v1/semver-auto-planned.json +47 -0
  26. package/contracts/fixtures/next-development-transition-v1/version-model-cases.json +40 -0
  27. package/contracts/fixtures/v4-adopter-delivery-v1/archive-template.json +19 -0
  28. package/contracts/fixtures/v4-adopter-delivery-v1/bootstrap-positive.json +93 -0
  29. package/contracts/fixtures/v4-adopter-delivery-v1/gate-positive.json +29 -0
  30. package/contracts/fixtures/v4-adopter-delivery-v1/gate-unknown-selector.json +26 -0
  31. package/contracts/fixtures/v4-adopter-delivery-v1/offline-vectors.json +50 -0
  32. package/contracts/fixtures/v4-compatibility-facts-v1/shared.json +1129 -0
  33. package/contracts/fixtures/v4-floating-consumer-policy-v1/cases.json +7 -1
  34. package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/artifacts/product.bin +1 -0
  35. package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/config/buildchain.toml +5 -0
  36. package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/documents/release-activation.json +1 -0
  37. package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/documents/signed-channel.json +1 -0
  38. package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/evidence/qualification.json +1 -0
  39. package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/manifests/candidate.json +5 -0
  40. package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/manifests/release-passport.json +1 -0
  41. package/contracts/fixtures/v4-publication-rehearsal-v1/capsule.json +707 -0
  42. package/contracts/fixtures/v4-publication-rehearsal-v1/offline-vectors.json +27 -0
  43. package/contracts/fixtures/v4-tail-reseal-v1/valid.json +229 -0
  44. package/contracts/next-development-request-v1.schema.json +66 -0
  45. package/contracts/next-development-transition-v1.schema.json +292 -0
  46. package/contracts/v4-adopter-delivery-v1.schema.json +81 -0
  47. package/contracts/v4-compatibility-facts-v1.schema.json +230 -0
  48. package/contracts/v4-floating-consumer-policy-receipt-v1.schema.json +4 -2
  49. package/contracts/v4-publication-rehearsal-capsule-v1.schema.json +233 -0
  50. package/contracts/v4-tail-reseal-v1.schema.json +276 -0
  51. package/dist/site/agent-index.json +5 -0
  52. package/dist/site/artifact-schemas.json +10 -0
  53. package/dist/site/buildchain-contract.json +1475 -27
  54. package/dist/site/buildchain-site.json +627 -31
  55. package/dist/site/capability-registry.json +17 -14
  56. package/dist/site/cli-registry.json +205 -3
  57. package/dist/site/kfd-claims.json +490 -16
  58. package/dist/site/kfd-upstream-aggregate.json +1 -1
  59. package/dist/site/manual-registry.json +52 -6
  60. package/dist/site/node-api-registry.json +14736 -8851
  61. package/dist/site/page-registry.json +593 -21
  62. package/dist/site/public-surface-audit.json +837 -48
  63. package/dist/site/publication-authority-registry.json +44 -8
  64. package/dist/site/publication-registry.json +4 -4
  65. package/dist/site/release-provenance.json +24 -0
  66. package/dist/site/schemas/dev-delivery-authority-v2.schema.json +662 -0
  67. package/dist/site/schemas/release-tail-capabilities-v1.schema.json +199 -0
  68. package/dist/site/schemas/v4-adopter-delivery-v1.schema.json +81 -0
  69. package/dist/site/schemas/v4-compatibility-facts-v1.schema.json +230 -0
  70. package/dist/site/schemas/v4-publication-rehearsal-capsule-v1.schema.json +233 -0
  71. package/dist/site/site-manifest.json +34 -10
  72. package/dist/site/workflow-registry.json +160 -10
  73. package/docs/MAP.md +8 -2
  74. package/docs/cli-reference.md +404 -13
  75. package/docs/cli.md +8 -0
  76. package/docs/dev-alpha-candidate-patrol.md +8 -0
  77. package/docs/dev-delivery-qualification-landing-adr.md +251 -0
  78. package/docs/dev-delivery-warrant.md +351 -38
  79. package/docs/next-development-transition.md +118 -0
  80. package/docs/node-api-reference.md +646 -293
  81. package/docs/release-tail-provider-plane.md +30 -0
  82. package/docs/v4-adopter-delivery.md +133 -0
  83. package/docs/v4-compatibility-facts.md +91 -0
  84. package/docs/v4-publication-rehearsal.md +130 -0
  85. package/docs/v4-tail-reseal.md +73 -0
  86. package/docs/versioning.md +4 -3
  87. package/package.json +34 -6
  88. package/packages/core/adopter-delivery-passport.js +259 -0
  89. package/packages/core/adopter-delivery-vectors.js +158 -0
  90. package/packages/core/adopter-delivery-vectors.json +77 -0
  91. package/packages/core/buildchain-agent-manuals.js +3 -0
  92. package/packages/core/buildchain-compatibility-authority.js +336 -0
  93. package/packages/core/buildchain-compatibility-fact.js +394 -0
  94. package/packages/core/buildchain-compatibility-facts.json +217 -0
  95. package/packages/core/buildchain-compatibility-proof.js +566 -0
  96. package/packages/core/buildchain-config.js +84 -0
  97. package/packages/core/buildchain-contract.js +96 -143
  98. package/packages/core/buildchain-delivery-bootstrap.js +240 -0
  99. package/packages/core/buildchain-delivery-infrastructure.js +164 -0
  100. package/packages/core/buildchain-delivery-self-dogfood.js +395 -0
  101. package/packages/core/buildchain-publication-authority.js +1 -0
  102. package/packages/core/channel-candidate.js +8 -0
  103. package/packages/core/channel-promotion-baseline.js +55 -0
  104. package/packages/core/ci-lane-change-budget.js +247 -0
  105. package/packages/core/dev-alpha-candidate-selection.js +10 -2
  106. package/packages/core/dev-delivery-authority-candidate.js +270 -0
  107. package/packages/core/dev-delivery-authority-evidence.js +146 -0
  108. package/packages/core/dev-delivery-authority-landing.js +461 -0
  109. package/packages/core/dev-delivery-authority-observation.js +48 -0
  110. package/packages/core/dev-delivery-authority-qualification.js +591 -0
  111. package/packages/core/dev-delivery-authority-settlement.js +213 -0
  112. package/packages/core/dev-delivery-authority-state.js +583 -0
  113. package/packages/core/dev-delivery-candidate-identity.js +13 -0
  114. package/packages/core/dev-delivery-contract-surface.js +76 -0
  115. package/packages/core/dev-delivery-execution-failure.js +133 -0
  116. package/packages/core/dev-delivery-execution-transfer.js +592 -0
  117. package/packages/core/dev-delivery-landing-admission-core.js +119 -0
  118. package/packages/core/dev-delivery-landing-readback.js +598 -0
  119. package/packages/core/dev-delivery-landing-terminal-evidence.js +271 -0
  120. package/packages/core/dev-delivery-landing-testing-port.js +6 -0
  121. package/packages/core/dev-delivery-native-execution.js +110 -0
  122. package/packages/core/dev-delivery-native-proof.js +562 -0
  123. package/packages/core/dev-delivery-process-boundary.js +563 -0
  124. package/packages/core/dev-delivery-provider-attempt.js +127 -0
  125. package/packages/core/dev-delivery-provider-heartbeat.js +382 -0
  126. package/packages/core/dev-delivery-warrant-cancellation.js +1 -0
  127. package/packages/core/dev-delivery-warrant-qualification.js +145 -0
  128. package/packages/core/dev-delivery-warrant-settlement.js +237 -36
  129. package/packages/core/dev-delivery-warrant-state.js +587 -0
  130. package/packages/core/dev-delivery-warrant.js +328 -370
  131. package/packages/core/github-governance-authority.js +1 -0
  132. package/packages/core/index.js +5 -0
  133. package/packages/core/kungfu-temporal-fact.js +557 -0
  134. package/packages/core/legacy-kfd-adopter-driver.js +167 -0
  135. package/packages/core/next-development-candidate-reservation.js +186 -0
  136. package/packages/core/next-development-controller.js +728 -0
  137. package/packages/core/next-development-projection.js +287 -0
  138. package/packages/core/next-development-transition.js +738 -0
  139. package/packages/core/paper-agent-entry.js +11 -5
  140. package/packages/core/paper.js +16 -5
  141. package/packages/core/published-delivery-authority.js +266 -0
  142. package/packages/core/release-candidate-recovery.js +70 -15
  143. package/packages/core/release-candidate.js +2 -2
  144. package/packages/core/release-passport.js +36 -9
  145. package/packages/core/v4-adopter-delivery-parity.js +3 -3
  146. package/packages/core/v4-adopter-delivery.js +359 -0
  147. package/packages/core/v4-canonical-contracts.js +5 -0
  148. package/packages/core/v4-delivery-warrant-read-candidate.js +10 -3
  149. package/packages/core/v4-floating-consumer-evidence.js +18 -4
  150. package/packages/core/v4-floating-consumer-policy.js +143 -20
  151. package/packages/core/v4-floating-consumer-release-passport.js +32 -5
  152. package/packages/core/v4-publication-rehearsal-capsule.js +468 -0
  153. package/packages/core/v4-publication-rehearsal-provider-bindings.js +212 -0
  154. package/packages/core/v4-publication-rehearsal.js +481 -0
  155. package/packages/core/v4-tail-reseal-contract.js +26 -0
  156. package/packages/core/v4-tail-reseal-github.js +178 -0
  157. package/packages/core/v4-tail-reseal-receipt.js +225 -0
  158. package/packages/core/v4-tail-reseal.js +594 -0
  159. package/packages/core/workflow-yaml-contract.js +24 -2
  160. package/scripts/buildchain-cli-help.mjs +41 -2
  161. package/scripts/check-ci-lane-change-budget.mjs +100 -0
  162. package/scripts/check-inventory.mjs +14 -3
  163. package/scripts/check-v4-floating-consumer-policy-contract.mjs +23 -4
  164. package/scripts/dev-alpha-candidate-patrol.mjs +22 -1
  165. package/scripts/dev-delivery-authority-command-adapters.mjs +206 -0
  166. package/scripts/dev-delivery-authority-provider.mjs +28 -0
  167. package/scripts/dev-delivery-authority.mjs +490 -0
  168. package/scripts/dev-delivery-native-run.mjs +177 -0
  169. package/scripts/dev-delivery-process-boundary.mjs +260 -0
  170. package/scripts/dev-delivery-proof.mjs +67 -2
  171. package/scripts/dev-delivery-provider-heartbeat.mjs +215 -0
  172. package/scripts/dev-delivery-source-proof-replay.mjs +153 -0
  173. package/scripts/dev-delivery-source-proof-reuse.mjs +13 -97
  174. package/scripts/dev-delivery-two-phase-resume.mjs +345 -0
  175. package/scripts/dev-delivery-two-phase.mjs +573 -0
  176. package/scripts/dev-delivery-warrant-options.mjs +266 -0
  177. package/scripts/dev-delivery-warrant-store.mjs +231 -0
  178. package/scripts/dev-delivery-warrant.mjs +232 -194
  179. package/scripts/dev-pr-auto-merge.mjs +1 -1
  180. package/scripts/dev-pr-delivery-warrant.mjs +11 -0
  181. package/scripts/dev-qualification-patrol.mjs +9 -9
  182. package/scripts/dispatch-artifact-signing-authority.mjs +1 -1
  183. package/scripts/generate-channel-promotion-workflow.mjs +2 -2
  184. package/scripts/generate-next-development-guidance.mjs +49 -0
  185. package/scripts/generate-release-candidate-passport.mjs +152 -0
  186. package/scripts/generate-site-bundle.mjs +69 -4
  187. package/scripts/init-repo.mjs +22 -4
  188. package/scripts/next-development-self-dogfood-harness.mjs +460 -0
  189. package/scripts/next-development-self-dogfood.mjs +597 -0
  190. package/scripts/next-development-transition.mjs +47 -0
  191. package/scripts/npm-publish-transaction.mjs +2 -2
  192. package/scripts/promotion-channel-router.mjs +4 -4
  193. package/scripts/release-candidate-anchor-provenance.mjs +99 -0
  194. package/scripts/release-tail.mjs +51 -3
  195. package/scripts/release-train-self-dogfood.mjs +94 -92
  196. package/scripts/resume-from-candidate-run.mjs +557 -30
  197. package/scripts/site-capability-metadata.mjs +41 -0
  198. package/scripts/stable-candidate-qualification.mjs +9 -10
  199. package/scripts/v4-consumer-policy.mjs +5 -5
  200. package/scripts/v4-publication-rehearsal-fixture.mjs +144 -0
  201. package/scripts/v4-tail-reseal-macos-rehearsal.mjs +134 -0
  202. package/scripts/v4-tail-reseal.mjs +416 -0
  203. package/templates/native-dev-delivery.yml +143 -0
@@ -1,8 +1,50 @@
1
- import { devDeliveryContentRoot, devDeliveryExactRoot as exactRoot, devDeliveryExactSha as exactSha, devDeliveryPositiveInteger as positiveInteger, devDeliveryText as text } from "./dev-delivery-common.js";
1
+ import {
2
+ devDeliveryContentRoot,
3
+ devDeliveryExactRoot as exactRoot,
4
+ devDeliveryExactSha as exactSha,
5
+ devDeliveryPositiveInteger as positiveInteger,
6
+ devDeliveryText as text,
7
+ } from "./dev-delivery-common.js";
2
8
 
3
- export const DEV_DELIVERY_SETTLEMENT_RECEIPT_SCHEMA = "kungfu.buildchain.dev-delivery-settlement-receipt/v1";
9
+ export const DEV_DELIVERY_SETTLEMENT_RECEIPT_SCHEMA =
10
+ "kungfu.buildchain.dev-delivery-settlement-receipt/v1";
4
11
 
5
- function noopReceipt(queue, identity, candidate, action) {
12
+ const PROVIDER_FAILURE_FIELDS = [
13
+ "transferRoot",
14
+ "finalizerBoundaryRoot",
15
+ "nativeJobId",
16
+ "sealJobId",
17
+ ];
18
+
19
+ export function normalizeProviderFailureAuthorityBinding(
20
+ input = {},
21
+ { required = false } = {},
22
+ ) {
23
+ const present = PROVIDER_FAILURE_FIELDS.filter(
24
+ (field) => input?.[field] !== undefined && input[field] !== "",
25
+ );
26
+ if (present.length === 0 && !required) return null;
27
+ if (present.length !== PROVIDER_FAILURE_FIELDS.length) {
28
+ throw new Error(
29
+ "provider failure authority binding requires transfer root, boundary root, native job id, and seal job id",
30
+ );
31
+ }
32
+ const binding = {
33
+ transferRoot: exactRoot(input.transferRoot, "transferRoot"),
34
+ finalizerBoundaryRoot: exactRoot(
35
+ input.finalizerBoundaryRoot,
36
+ "finalizerBoundaryRoot",
37
+ ),
38
+ nativeJobId: positiveInteger(input.nativeJobId, "nativeJobId"),
39
+ sealJobId: positiveInteger(input.sealJobId, "sealJobId"),
40
+ };
41
+ if (binding.nativeJobId === binding.sealJobId) {
42
+ throw new Error("native and seal job ids must be distinct");
43
+ }
44
+ return binding;
45
+ }
46
+
47
+ function noopReceipt(queue, identity, candidate, action, details = {}) {
6
48
  return {
7
49
  schema: DEV_DELIVERY_SETTLEMENT_RECEIPT_SCHEMA,
8
50
  action,
@@ -13,61 +55,220 @@ function noopReceipt(queue, identity, candidate, action) {
13
55
  sourceHead: identity.sourceHead,
14
56
  outcome: identity.outcome,
15
57
  candidateId: candidate?.candidateId || null,
16
- evidenceRoot: candidate?.terminal?.evidenceRoot || identity.evidenceRoot || null,
58
+ evidenceRoot:
59
+ candidate?.terminal?.evidenceRoot || identity.evidenceRoot || null,
17
60
  expectedOldStateRoot: queue.stateRoot,
18
61
  nextStateRoot: queue.stateRoot,
19
62
  nextAction: "No fenced delivery state remains for this terminal event.",
63
+ ...details,
20
64
  };
21
65
  }
22
66
 
23
- export function createDevDeliveryTerminalSettler({ normalizeQueue, closeWarrant, cancelQueued, terminalStates }) {
24
- return function settleDevDeliveryTerminalEvent(queueInput, input, { now = new Date().toISOString() } = {}) {
67
+ function settleTerminalCandidate(queue, identity, candidate) {
68
+ if (candidate.status !== identity.outcome) {
69
+ if (identity.outcome !== "dequeued")
70
+ throw new Error(
71
+ "terminal candidate outcome does not match the terminal event",
72
+ );
73
+ const receipt = noopReceipt(
74
+ queue,
75
+ identity,
76
+ candidate,
77
+ "stale-transient-dequeue-noop",
78
+ {
79
+ terminalClass: "transient-dequeue",
80
+ authoritativeOutcome: candidate.status,
81
+ nextAction:
82
+ "Retain the authoritative terminal settlement; the stale dequeue cannot rewrite it.",
83
+ },
84
+ );
85
+ return { queue, receipt, receiptRoot: devDeliveryContentRoot(receipt) };
86
+ }
87
+ const existingBinding = normalizeProviderFailureAuthorityBinding(
88
+ candidate.terminal || {},
89
+ );
90
+ const repeatedBinding = normalizeProviderFailureAuthorityBinding(identity, {
91
+ required: Boolean(existingBinding),
92
+ });
93
+ if (JSON.stringify(existingBinding) !== JSON.stringify(repeatedBinding)) {
94
+ throw new Error(
95
+ "duplicate terminal event provider failure authority drift",
96
+ );
97
+ }
98
+ if (candidate.terminal?.evidenceRoot !== identity.evidenceRoot) {
99
+ throw new Error("duplicate terminal event evidenceRoot drift");
100
+ }
101
+ const receipt = noopReceipt(
102
+ queue,
103
+ identity,
104
+ candidate,
105
+ "duplicate-terminal-event-noop",
106
+ );
107
+ return { queue, receipt, receiptRoot: devDeliveryContentRoot(receipt) };
108
+ }
109
+
110
+ function retainDequeuedWarrant(
111
+ queue,
112
+ identity,
113
+ candidate,
114
+ fencingToken,
115
+ leaseGeneration,
116
+ now,
117
+ ) {
118
+ const leaseFresh =
119
+ Date.parse(queue.activeWarrant.expiresAt) > Date.parse(now);
120
+ const receipt = noopReceipt(
121
+ queue,
122
+ identity,
123
+ candidate,
124
+ leaseFresh
125
+ ? "transient-dequeue-retained-active-warrant"
126
+ : "expired-active-warrant-awaits-fenced-settlement",
127
+ {
128
+ terminalClass: "transient-dequeue",
129
+ fencingToken,
130
+ leaseGeneration,
131
+ warrantExpiresAt: queue.activeWarrant.expiresAt,
132
+ nextAction: leaseFresh
133
+ ? "Continue the exact active native execution and heartbeat; later candidates remain queued."
134
+ : "Prove the stale native worker stopped, then close this exact fenced generation before selecting a successor.",
135
+ },
136
+ );
137
+ return { queue, receipt, receiptRoot: devDeliveryContentRoot(receipt) };
138
+ }
139
+
140
+ export function createDevDeliveryTerminalSettler({
141
+ normalizeQueue,
142
+ closeWarrant,
143
+ cancelQueued,
144
+ terminalStates,
145
+ }) {
146
+ return function settleDevDeliveryTerminalEvent(
147
+ queueInput,
148
+ input,
149
+ { now = new Date().toISOString() } = {},
150
+ ) {
25
151
  const queue = normalizeQueue(queueInput);
26
152
  const identity = {
27
- pullRequestNumber: positiveInteger(input?.pullRequestNumber, "pullRequestNumber"),
153
+ pullRequestNumber: positiveInteger(
154
+ input?.pullRequestNumber,
155
+ "pullRequestNumber",
156
+ ),
28
157
  sourceHead: exactSha(input?.sourceHead, "sourceHead"),
29
158
  outcome: text(input?.outcome),
30
- evidenceRoot: input?.evidenceRoot ? exactRoot(input.evidenceRoot, "evidenceRoot") : "",
159
+ evidenceRoot: input?.evidenceRoot
160
+ ? exactRoot(input.evidenceRoot, "evidenceRoot")
161
+ : "",
31
162
  reason: text(input?.reason),
32
163
  eventAction: text(input?.eventAction).toLowerCase(),
164
+ ...normalizeProviderFailureAuthorityBinding(input || {}),
33
165
  };
34
- if (!terminalStates.has(identity.outcome)) throw new Error(`outcome must be one of ${[...terminalStates].join(", ")}`);
35
- const samePullRequest = queue.candidates.filter((entry) => entry.pullRequestNumber === identity.pullRequestNumber);
36
- const candidate = samePullRequest.find((entry) => entry.sourceHead === identity.sourceHead) || null;
37
- if (!candidate && samePullRequest.length > 0) throw new Error("terminal event sourceHead does not match the recorded candidate");
166
+ if (!terminalStates.has(identity.outcome))
167
+ throw new Error(
168
+ `outcome must be one of ${[...terminalStates].join(", ")}`,
169
+ );
170
+ const samePullRequest = queue.candidates.filter(
171
+ (entry) => entry.pullRequestNumber === identity.pullRequestNumber,
172
+ );
173
+ const matchingHead = samePullRequest.filter(
174
+ (entry) => entry.sourceHead === identity.sourceHead,
175
+ );
176
+ const activeCandidate = queue.activeWarrant
177
+ ? matchingHead.find(
178
+ (entry) => entry.candidateId === queue.activeWarrant.candidateId,
179
+ )
180
+ : null;
181
+ const candidate = activeCandidate || matchingHead.at(-1) || null;
182
+ if (!candidate && samePullRequest.length > 0)
183
+ throw new Error(
184
+ "terminal event sourceHead does not match the recorded candidate",
185
+ );
38
186
 
39
187
  if (candidate && terminalStates.has(candidate.status)) {
40
- if (candidate.status !== identity.outcome) throw new Error("terminal candidate outcome does not match the terminal event");
41
- const receipt = noopReceipt(queue, identity, candidate, "duplicate-terminal-event-noop");
42
- return { queue, receipt, receiptRoot: devDeliveryContentRoot(receipt) };
188
+ return settleTerminalCandidate(queue, identity, candidate);
43
189
  }
44
190
 
45
191
  if (queue.activeWarrant) {
46
- if (!candidate || queue.activeWarrant.candidateId !== candidate.candidateId) throw new Error("terminal event does not match the active Delivery Warrant");
47
- if (!identity.evidenceRoot) throw new Error("active terminal settlement requires evidenceRoot");
48
- return closeWarrant(queue, {
49
- candidateId: candidate.candidateId,
50
- fencingToken: exactRoot(input?.fencingToken, "fencingToken"),
51
- generation: positiveInteger(input?.leaseGeneration, "leaseGeneration"),
52
- }, { outcome: identity.outcome, evidenceRoot: identity.evidenceRoot, reason: identity.reason, now });
192
+ if (
193
+ !candidate ||
194
+ queue.activeWarrant.candidateId !== candidate.candidateId
195
+ )
196
+ throw new Error(
197
+ "terminal event does not match the active Delivery Warrant",
198
+ );
199
+ if (!identity.evidenceRoot)
200
+ throw new Error("active terminal settlement requires evidenceRoot");
201
+ const fencingToken = exactRoot(input?.fencingToken, "fencingToken");
202
+ const leaseGeneration = positiveInteger(
203
+ input?.leaseGeneration,
204
+ "leaseGeneration",
205
+ );
206
+ if (fencingToken !== queue.activeWarrant.fencingToken)
207
+ throw new Error("stale fencing token");
208
+ if (leaseGeneration !== queue.activeWarrant.generation)
209
+ throw new Error("stale lease generation");
210
+ if (identity.outcome === "dequeued") {
211
+ return retainDequeuedWarrant(
212
+ queue,
213
+ identity,
214
+ candidate,
215
+ fencingToken,
216
+ leaseGeneration,
217
+ now,
218
+ );
219
+ }
220
+ return closeWarrant(
221
+ queue,
222
+ {
223
+ candidateId: candidate.candidateId,
224
+ fencingToken,
225
+ generation: leaseGeneration,
226
+ },
227
+ {
228
+ outcome: identity.outcome,
229
+ evidenceRoot: identity.evidenceRoot,
230
+ reason: identity.reason,
231
+ providerFailureAuthority:
232
+ normalizeProviderFailureAuthorityBinding(identity),
233
+ now,
234
+ },
235
+ );
53
236
  }
54
237
 
55
238
  if (!candidate) {
56
- const receipt = noopReceipt(queue, identity, null, "terminal-event-not-applicable");
239
+ const receipt = noopReceipt(
240
+ queue,
241
+ identity,
242
+ null,
243
+ "terminal-event-not-applicable",
244
+ );
57
245
  return { queue, receipt, receiptRoot: devDeliveryContentRoot(receipt) };
58
246
  }
59
- if (candidate.status !== "queued") throw new Error(`candidate status ${candidate.status} requires an active Delivery Warrant`);
60
- if (!["cancelled", "dequeued"].includes(identity.outcome)) throw new Error("queued candidate cannot settle as merged or terminal-failure");
61
- if (!identity.evidenceRoot) throw new Error("queued terminal settlement requires evidenceRoot");
62
- return cancelQueued(queue, {
63
- candidateId: candidate.candidateId,
64
- pullRequestNumber: identity.pullRequestNumber,
65
- expectedSourceHead: identity.sourceHead,
66
- observedSourceHead: identity.sourceHead,
67
- eventAction: identity.eventAction || (identity.outcome === "dequeued" ? "dequeued" : "closed"),
68
- outcome: identity.outcome,
69
- evidenceRoot: identity.evidenceRoot,
70
- reason: identity.reason,
71
- }, { now });
247
+ if (candidate.status !== "queued")
248
+ throw new Error(
249
+ `candidate status ${candidate.status} requires an active Delivery Warrant`,
250
+ );
251
+ if (!["cancelled", "dequeued"].includes(identity.outcome))
252
+ throw new Error(
253
+ "queued candidate cannot settle as merged or terminal-failure",
254
+ );
255
+ if (!identity.evidenceRoot)
256
+ throw new Error("queued terminal settlement requires evidenceRoot");
257
+ return cancelQueued(
258
+ queue,
259
+ {
260
+ candidateId: candidate.candidateId,
261
+ pullRequestNumber: identity.pullRequestNumber,
262
+ expectedSourceHead: identity.sourceHead,
263
+ observedSourceHead: identity.sourceHead,
264
+ eventAction:
265
+ identity.eventAction ||
266
+ (identity.outcome === "dequeued" ? "dequeued" : "closed"),
267
+ outcome: identity.outcome,
268
+ evidenceRoot: identity.evidenceRoot,
269
+ reason: identity.reason,
270
+ },
271
+ { now },
272
+ );
72
273
  };
73
274
  }