@kungfu-tech/buildchain 4.0.0 → 4.0.1-alpha.10

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 (228) hide show
  1. package/AGENTS.md +13 -5
  2. package/actions/promote-buildchain-ref/README.md +11 -6
  3. package/actions/release-tail/README.md +8 -0
  4. package/architecture/ci-lane-change-budget.json +187 -0
  5. package/architecture/decisions/0002-next-development-transition.md +101 -0
  6. package/architecture/decisions/0003-two-phase-delivery-warrant.md +152 -0
  7. package/architecture/internal-capabilities.json +219 -7
  8. package/architecture/maintainability-policy.json +246 -29
  9. package/architecture/release-tail-contract-inventory.json +5 -2
  10. package/architecture/v3-core-mechanism-inventory.json +91 -0
  11. package/architecture/v4-adopter-delivery-parity.json +32 -5
  12. package/architecture/v4-capability-state-machine-manifest.json +73 -0
  13. package/architecture/v4-compatibility-facts-parity.json +77 -0
  14. package/architecture/v4-delivery-authority-parity.json +250 -0
  15. package/architecture/v4-delivery-warrant-shadow-fixtures.json +41 -9
  16. package/architecture/v4-floating-consumer-policy.json +81 -0
  17. package/architecture/v4-floating-consumer-policy.md +32 -0
  18. package/architecture/v4-next-development-parity.json +192 -0
  19. package/architecture/v4-publication-rehearsal-parity.json +84 -0
  20. package/architecture/v4-release-train-parity.json +1 -0
  21. package/architecture/v4-runtime-ref-resume-authority.json +64 -0
  22. package/architecture/v4-stage-capsule-qualification.json +2 -2
  23. package/architecture/v4-tail-reseal-parity.json +150 -0
  24. package/bin/buildchain.mjs +32 -3
  25. package/bin/internal/adopter-delivery-cli.mjs +70 -0
  26. package/bin/internal/command-registry.mjs +3 -0
  27. package/bin/internal/compatibility-facts-cli.mjs +101 -0
  28. package/bin/internal/trust-release-release-handlers.mjs +5 -0
  29. package/contracts/dev-delivery-authority-v2.schema.json +662 -0
  30. package/contracts/fixtures/next-development-transition-v1/anchored-manual-waiting.json +47 -0
  31. package/contracts/fixtures/next-development-transition-v1/semver-auto-planned.json +47 -0
  32. package/contracts/fixtures/next-development-transition-v1/version-model-cases.json +40 -0
  33. package/contracts/fixtures/v4-adopter-delivery-v1/archive-template.json +19 -0
  34. package/contracts/fixtures/v4-adopter-delivery-v1/bootstrap-positive.json +93 -0
  35. package/contracts/fixtures/v4-adopter-delivery-v1/gate-positive.json +29 -0
  36. package/contracts/fixtures/v4-adopter-delivery-v1/gate-unknown-selector.json +26 -0
  37. package/contracts/fixtures/v4-adopter-delivery-v1/offline-vectors.json +50 -0
  38. package/contracts/fixtures/v4-compatibility-facts-v1/shared.json +1129 -0
  39. package/contracts/fixtures/v4-floating-consumer-policy-v1/cases.json +59 -0
  40. package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/artifacts/product.bin +1 -0
  41. package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/config/buildchain.toml +5 -0
  42. package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/documents/release-activation.json +1 -0
  43. package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/documents/signed-channel.json +1 -0
  44. package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/evidence/qualification.json +1 -0
  45. package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/manifests/candidate.json +5 -0
  46. package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/manifests/release-passport.json +1 -0
  47. package/contracts/fixtures/v4-publication-rehearsal-v1/capsule.json +707 -0
  48. package/contracts/fixtures/v4-publication-rehearsal-v1/offline-vectors.json +27 -0
  49. package/contracts/fixtures/v4-runtime-ref-resume-authority-v1/scenario.json +15 -0
  50. package/contracts/fixtures/v4-tail-reseal-v1/valid.json +229 -0
  51. package/contracts/next-development-request-v1.schema.json +66 -0
  52. package/contracts/next-development-transition-v1.schema.json +292 -0
  53. package/contracts/v4-adopter-delivery-v1.schema.json +81 -0
  54. package/contracts/v4-compatibility-facts-v1.schema.json +230 -0
  55. package/contracts/v4-floating-consumer-policy-receipt-v1.schema.json +107 -0
  56. package/contracts/v4-publication-rehearsal-capsule-v1.schema.json +233 -0
  57. package/contracts/v4-runtime-ref-resume-authority-v1.schema.json +235 -0
  58. package/contracts/v4-tail-reseal-v1.schema.json +276 -0
  59. package/dist/site/agent-index.json +5 -0
  60. package/dist/site/artifact-schemas.json +10 -0
  61. package/dist/site/buildchain-contract.json +1562 -44
  62. package/dist/site/buildchain-site.json +684 -42
  63. package/dist/site/capability-registry.json +17 -14
  64. package/dist/site/cli-registry.json +205 -3
  65. package/dist/site/controller-registry.json +62 -6
  66. package/dist/site/kfd-claims.json +551 -22
  67. package/dist/site/kfd-upstream-aggregate.json +1 -1
  68. package/dist/site/manual-registry.json +55 -9
  69. package/dist/site/node-api-registry.json +15247 -8690
  70. package/dist/site/page-registry.json +647 -29
  71. package/dist/site/public-surface-audit.json +876 -55
  72. package/dist/site/publication-authority-registry.json +44 -8
  73. package/dist/site/publication-registry.json +4 -4
  74. package/dist/site/release-provenance.json +26 -0
  75. package/dist/site/schemas/dev-delivery-authority-v2.schema.json +662 -0
  76. package/dist/site/schemas/release-tail-capabilities-v1.schema.json +199 -0
  77. package/dist/site/schemas/v4-adopter-delivery-v1.schema.json +81 -0
  78. package/dist/site/schemas/v4-compatibility-facts-v1.schema.json +230 -0
  79. package/dist/site/schemas/v4-publication-rehearsal-capsule-v1.schema.json +233 -0
  80. package/dist/site/site-manifest.json +37 -13
  81. package/dist/site/workflow-registry.json +200 -22
  82. package/docs/MAP.md +10 -2
  83. package/docs/cli-reference.md +404 -13
  84. package/docs/cli.md +8 -0
  85. package/docs/dev-alpha-candidate-patrol.md +8 -0
  86. package/docs/dev-delivery-qualification-landing-adr.md +251 -0
  87. package/docs/dev-delivery-warrant.md +361 -30
  88. package/docs/lifecycle-protocol.md +41 -0
  89. package/docs/next-development-transition.md +118 -0
  90. package/docs/node-api-reference.md +748 -322
  91. package/docs/release-tail-provider-plane.md +30 -0
  92. package/docs/reusable-build-surface.md +41 -0
  93. package/docs/runtime-train-validation.md +10 -0
  94. package/docs/v4-adopter-delivery.md +133 -0
  95. package/docs/v4-compatibility-facts.md +91 -0
  96. package/docs/v4-publication-rehearsal.md +130 -0
  97. package/docs/v4-runtime-ref-resume-authority.md +69 -0
  98. package/docs/v4-tail-reseal.md +73 -0
  99. package/docs/versioning.md +4 -2
  100. package/package.json +36 -6
  101. package/packages/core/adopter-delivery-passport.js +259 -0
  102. package/packages/core/adopter-delivery-vectors.js +158 -0
  103. package/packages/core/adopter-delivery-vectors.json +77 -0
  104. package/packages/core/artifact-signing.js +61 -0
  105. package/packages/core/buildchain-agent-manuals.js +3 -0
  106. package/packages/core/buildchain-compatibility-authority.js +336 -0
  107. package/packages/core/buildchain-compatibility-fact.js +394 -0
  108. package/packages/core/buildchain-compatibility-facts.json +217 -0
  109. package/packages/core/buildchain-compatibility-proof.js +566 -0
  110. package/packages/core/buildchain-config.js +150 -1
  111. package/packages/core/buildchain-contract.js +96 -143
  112. package/packages/core/buildchain-delivery-bootstrap.js +240 -0
  113. package/packages/core/buildchain-delivery-infrastructure.js +164 -0
  114. package/packages/core/buildchain-delivery-self-dogfood.js +395 -0
  115. package/packages/core/buildchain-publication-authority.js +1 -0
  116. package/packages/core/channel-candidate.js +8 -0
  117. package/packages/core/channel-promotion-baseline.js +55 -0
  118. package/packages/core/ci-lane-change-budget.js +247 -0
  119. package/packages/core/dev-alpha-candidate-selection.js +10 -2
  120. package/packages/core/dev-delivery-authority-candidate.js +270 -0
  121. package/packages/core/dev-delivery-authority-evidence.js +146 -0
  122. package/packages/core/dev-delivery-authority-landing.js +461 -0
  123. package/packages/core/dev-delivery-authority-observation.js +48 -0
  124. package/packages/core/dev-delivery-authority-qualification.js +591 -0
  125. package/packages/core/dev-delivery-authority-settlement.js +213 -0
  126. package/packages/core/dev-delivery-authority-state.js +583 -0
  127. package/packages/core/dev-delivery-candidate-identity.js +13 -0
  128. package/packages/core/dev-delivery-contract-surface.js +76 -0
  129. package/packages/core/dev-delivery-execution-failure.js +133 -0
  130. package/packages/core/dev-delivery-execution-transfer.js +592 -0
  131. package/packages/core/dev-delivery-landing-admission-core.js +119 -0
  132. package/packages/core/dev-delivery-landing-readback.js +598 -0
  133. package/packages/core/dev-delivery-landing-terminal-evidence.js +271 -0
  134. package/packages/core/dev-delivery-landing-testing-port.js +6 -0
  135. package/packages/core/dev-delivery-native-execution.js +110 -0
  136. package/packages/core/dev-delivery-native-proof.js +562 -0
  137. package/packages/core/dev-delivery-process-boundary.js +563 -0
  138. package/packages/core/dev-delivery-proof.js +37 -3
  139. package/packages/core/dev-delivery-provider-attempt.js +127 -0
  140. package/packages/core/dev-delivery-provider-heartbeat.js +382 -0
  141. package/packages/core/dev-delivery-warrant-cancellation.js +1 -0
  142. package/packages/core/dev-delivery-warrant-qualification.js +145 -0
  143. package/packages/core/dev-delivery-warrant-settlement.js +237 -36
  144. package/packages/core/dev-delivery-warrant-state.js +587 -0
  145. package/packages/core/dev-delivery-warrant.js +328 -370
  146. package/packages/core/github-governance-authority.js +1 -0
  147. package/packages/core/index.js +7 -0
  148. package/packages/core/kungfu-temporal-fact.js +557 -0
  149. package/packages/core/legacy-kfd-adopter-driver.js +167 -0
  150. package/packages/core/next-development-candidate-reservation.js +186 -0
  151. package/packages/core/next-development-controller.js +728 -0
  152. package/packages/core/next-development-projection.js +287 -0
  153. package/packages/core/next-development-transition.js +738 -0
  154. package/packages/core/paper-agent-entry.js +11 -5
  155. package/packages/core/paper.js +16 -5
  156. package/packages/core/publication-authority.js +5 -5
  157. package/packages/core/published-delivery-authority.js +266 -0
  158. package/packages/core/release-candidate-recovery.js +66 -11
  159. package/packages/core/release-candidate.js +79 -19
  160. package/packages/core/release-passport.js +271 -38
  161. package/packages/core/v4-adopter-delivery-parity.js +3 -3
  162. package/packages/core/v4-adopter-delivery.js +359 -0
  163. package/packages/core/v4-canonical-contracts.js +5 -0
  164. package/packages/core/v4-delivery-warrant-read-candidate.js +10 -3
  165. package/packages/core/v4-floating-consumer-evidence.js +338 -0
  166. package/packages/core/v4-floating-consumer-policy.js +569 -0
  167. package/packages/core/v4-floating-consumer-release-passport.js +153 -0
  168. package/packages/core/v4-publication-rehearsal-capsule.js +468 -0
  169. package/packages/core/v4-publication-rehearsal-provider-bindings.js +212 -0
  170. package/packages/core/v4-publication-rehearsal.js +481 -0
  171. package/packages/core/v4-runtime-ref-resume-authority.js +625 -0
  172. package/packages/core/v4-runtime-selector-persistence.js +228 -0
  173. package/packages/core/v4-tail-reseal-contract.js +26 -0
  174. package/packages/core/v4-tail-reseal-github.js +178 -0
  175. package/packages/core/v4-tail-reseal-receipt.js +225 -0
  176. package/packages/core/v4-tail-reseal.js +594 -0
  177. package/packages/core/workflow-yaml-contract.js +72 -2
  178. package/scripts/audit-publication-control-plane.mjs +31 -31
  179. package/scripts/buildchain-cli-help.mjs +41 -2
  180. package/scripts/check-ci-lane-change-budget.mjs +100 -0
  181. package/scripts/check-inventory.mjs +14 -3
  182. package/scripts/check-v4-floating-consumer-policy-contract.mjs +217 -0
  183. package/scripts/check-v4-public-dogfood-contract.mjs +6 -11
  184. package/scripts/dev-alpha-candidate-patrol.mjs +22 -1
  185. package/scripts/dev-delivery-authority-command-adapters.mjs +206 -0
  186. package/scripts/dev-delivery-authority-provider.mjs +28 -0
  187. package/scripts/dev-delivery-authority.mjs +490 -0
  188. package/scripts/dev-delivery-native-run.mjs +177 -0
  189. package/scripts/dev-delivery-process-boundary.mjs +260 -0
  190. package/scripts/dev-delivery-proof.mjs +67 -2
  191. package/scripts/dev-delivery-provider-heartbeat.mjs +215 -0
  192. package/scripts/dev-delivery-source-proof-replay.mjs +153 -0
  193. package/scripts/dev-delivery-source-proof-reuse.mjs +547 -0
  194. package/scripts/dev-delivery-two-phase-resume.mjs +345 -0
  195. package/scripts/dev-delivery-two-phase.mjs +573 -0
  196. package/scripts/dev-delivery-warrant-options.mjs +266 -0
  197. package/scripts/dev-delivery-warrant-store.mjs +231 -0
  198. package/scripts/dev-delivery-warrant.mjs +232 -194
  199. package/scripts/dev-pr-auto-merge.mjs +37 -48
  200. package/scripts/dev-pr-delivery-warrant.mjs +216 -2
  201. package/scripts/dev-pr-prequeue-guard.mjs +399 -0
  202. package/scripts/dev-qualification-patrol.mjs +9 -9
  203. package/scripts/dispatch-artifact-signing-authority.mjs +1 -1
  204. package/scripts/ensure-github-release.mjs +3 -3
  205. package/scripts/generate-channel-build-workflow.mjs +3 -0
  206. package/scripts/generate-channel-promotion-workflow.mjs +114 -14
  207. package/scripts/generate-next-development-guidance.mjs +49 -0
  208. package/scripts/generate-release-candidate-passport.mjs +192 -32
  209. package/scripts/generate-site-bundle.mjs +69 -4
  210. package/scripts/init-repo.mjs +26 -4
  211. package/scripts/inspect-artifact-signing-requests.mjs +6 -0
  212. package/scripts/next-development-self-dogfood-harness.mjs +460 -0
  213. package/scripts/next-development-self-dogfood.mjs +597 -0
  214. package/scripts/next-development-transition.mjs +47 -0
  215. package/scripts/npm-publish-transaction.mjs +103 -91
  216. package/scripts/promotion-channel-router.mjs +4 -4
  217. package/scripts/release-candidate-anchor-provenance.mjs +99 -0
  218. package/scripts/release-tail.mjs +51 -3
  219. package/scripts/release-train-self-dogfood.mjs +94 -92
  220. package/scripts/resume-from-candidate-run.mjs +565 -41
  221. package/scripts/seal-artifact-signing-requests.mjs +6 -0
  222. package/scripts/site-capability-metadata.mjs +43 -0
  223. package/scripts/stable-candidate-qualification.mjs +9 -10
  224. package/scripts/v4-consumer-policy.mjs +231 -0
  225. package/scripts/v4-publication-rehearsal-fixture.mjs +144 -0
  226. package/scripts/v4-tail-reseal-macos-rehearsal.mjs +134 -0
  227. package/scripts/v4-tail-reseal.mjs +416 -0
  228. package/templates/native-dev-delivery.yml +143 -0
@@ -0,0 +1,345 @@
1
+ import { execFileSync } from "node:child_process";
2
+
3
+ import {
4
+ createNativeCommandContract,
5
+ createNativeProofReuseDecision,
6
+ createNativeQualificationProof,
7
+ } from "../packages/core/dev-delivery-warrant.js";
8
+
9
+ const ROOT_PATTERN = /^sha256:[0-9a-f]{64}$/u;
10
+
11
+ function exactLocalSha(value, label) {
12
+ const normalized = String(value || "")
13
+ .trim()
14
+ .toLowerCase();
15
+ if (!/^[0-9a-f]{40}$/u.test(normalized))
16
+ throw new Error(`${label} must be an exact lowercase Git SHA`);
17
+ return normalized;
18
+ }
19
+
20
+ export class LocalTwoPhaseClient {
21
+ constructor({ candidateDirectory } = {}) {
22
+ this.candidateDirectory = candidateDirectory;
23
+ }
24
+
25
+ git(args, options = {}) {
26
+ return execFileSync("git", ["-C", this.candidateDirectory, ...args], {
27
+ encoding: "utf8",
28
+ ...options,
29
+ }).trim();
30
+ }
31
+
32
+ async baseSha(branch) {
33
+ return exactLocalSha(
34
+ this.git(["rev-parse", `refs/remotes/origin/${branch}`]),
35
+ "protected base SHA",
36
+ );
37
+ }
38
+
39
+ async exactPullRequestHead(_pullRequestNumber, expectedHead) {
40
+ const observed = exactLocalSha(this.git(["rev-parse", "HEAD"]), "PR head");
41
+ if (observed !== expectedHead)
42
+ throw new Error(
43
+ `semantic source head changed: ${observed} != ${expectedHead}`,
44
+ );
45
+ return observed;
46
+ }
47
+
48
+ async baseDelta(previousBase, currentBase) {
49
+ if (previousBase === currentBase)
50
+ return {
51
+ graphKnown: true,
52
+ attributionComplete: true,
53
+ changedPaths: [],
54
+ renames: [],
55
+ };
56
+ try {
57
+ this.git(["merge-base", "--is-ancestor", previousBase, currentBase]);
58
+ } catch {
59
+ return {
60
+ graphKnown: false,
61
+ attributionComplete: false,
62
+ changedPaths: [],
63
+ renames: [],
64
+ };
65
+ }
66
+ const entries = this.git([
67
+ "diff",
68
+ "--name-status",
69
+ "-M",
70
+ previousBase,
71
+ currentBase,
72
+ ])
73
+ .split("\n")
74
+ .filter(Boolean)
75
+ .map((line) => line.split("\t"));
76
+ const renames = entries
77
+ .filter(([status]) => status.startsWith("R"))
78
+ .map(([, from, to]) => ({ from, to }));
79
+ return {
80
+ graphKnown: true,
81
+ attributionComplete: renames.every(({ from, to }) => from && to),
82
+ changedPaths: [
83
+ ...new Set(entries.flatMap(([, ...paths]) => paths).filter(Boolean)),
84
+ ].sort(),
85
+ renames,
86
+ };
87
+ }
88
+ }
89
+
90
+ export class GitHubTwoPhaseClient {
91
+ constructor({
92
+ repository,
93
+ token,
94
+ apiUrl = "https://api.github.com",
95
+ fetchImpl = globalThis.fetch,
96
+ } = {}) {
97
+ if (!token) throw new Error("GITHUB_TOKEN is required");
98
+ this.repository = repository;
99
+ this.token = token;
100
+ this.apiUrl = apiUrl.replace(/\/+$/u, "");
101
+ this.fetch = fetchImpl;
102
+ }
103
+
104
+ async request(requestPath, { method = "GET", body } = {}) {
105
+ const response = await this.fetch(`${this.apiUrl}${requestPath}`, {
106
+ method,
107
+ headers: {
108
+ accept: "application/vnd.github+json",
109
+ authorization: `Bearer ${this.token}`,
110
+ "content-type": "application/json",
111
+ "x-github-api-version": "2022-11-28",
112
+ },
113
+ body: body === undefined ? undefined : JSON.stringify(body),
114
+ });
115
+ const raw = await response.text();
116
+ const data = raw ? JSON.parse(raw) : null;
117
+ if (!response.ok) throw new Error(data?.message || `${requestPath} failed`);
118
+ return data;
119
+ }
120
+
121
+ async baseSha(branch) {
122
+ const data = await this.request(
123
+ `/repos/${this.repository}/git/ref/heads/${branch
124
+ .split("/")
125
+ .map(encodeURIComponent)
126
+ .join("/")}`,
127
+ );
128
+ return exactLocalSha(data?.object?.sha, "protected base SHA");
129
+ }
130
+
131
+ async exactPullRequestHead(pullRequestNumber, expectedHead) {
132
+ const data = await this.request(
133
+ `/repos/${this.repository}/pulls/${pullRequestNumber}`,
134
+ );
135
+ const observed = exactLocalSha(data?.head?.sha, "observed PR head");
136
+ if (observed !== expectedHead)
137
+ throw new Error(
138
+ `semantic source head changed: ${observed} != ${expectedHead}`,
139
+ );
140
+ return observed;
141
+ }
142
+
143
+ async baseDelta(previousBase, currentBase) {
144
+ if (previousBase === currentBase)
145
+ return {
146
+ graphKnown: true,
147
+ attributionComplete: true,
148
+ changedPaths: [],
149
+ renames: [],
150
+ };
151
+ const data = await this.request(
152
+ `/repos/${this.repository}/compare/${previousBase}...${currentBase}`,
153
+ );
154
+ return attributedGitHubBaseDelta(data, previousBase);
155
+ }
156
+
157
+ async wake(eventType, candidate) {
158
+ await this.request(`/repos/${this.repository}/dispatches`, {
159
+ method: "POST",
160
+ body: { event_type: eventType, client_payload: { candidate } },
161
+ });
162
+ }
163
+ }
164
+
165
+ export function attributedGitHubBaseDelta(data, previousBase) {
166
+ const files = Array.isArray(data?.files) ? data.files : [];
167
+ const graphKnown =
168
+ data?.status === "ahead" &&
169
+ data?.merge_base_commit?.sha === previousBase &&
170
+ files.length < 300;
171
+ const renames = files
172
+ .filter((entry) => entry.status === "renamed")
173
+ .map((entry) => ({
174
+ from: String(entry.previous_filename || ""),
175
+ to: String(entry.filename || ""),
176
+ }));
177
+ const attributionComplete =
178
+ graphKnown && renames.every((entry) => entry.from && entry.to);
179
+ return {
180
+ graphKnown,
181
+ attributionComplete,
182
+ changedPaths: attributionComplete
183
+ ? [
184
+ ...new Set(
185
+ files
186
+ .flatMap((entry) => [
187
+ String(entry.filename || ""),
188
+ String(entry.previous_filename || ""),
189
+ ])
190
+ .filter(Boolean),
191
+ ),
192
+ ].sort()
193
+ : [],
194
+ renames: attributionComplete ? renames : [],
195
+ };
196
+ }
197
+
198
+ export async function replayQualifiedNativeWarrant({
199
+ warrant,
200
+ pullRequestNumber,
201
+ expectedHead,
202
+ exactPullRequestHead,
203
+ }) {
204
+ if (warrant.phase !== "qualified") return null;
205
+ if (
206
+ !ROOT_PATTERN.test(warrant.nativeProofRoot || "") ||
207
+ !ROOT_PATTERN.test(warrant.nativeProofReuseRoot || "") ||
208
+ !ROOT_PATTERN.test(warrant.qualificationReceiptRoot || "")
209
+ ) {
210
+ throw new Error(
211
+ "qualified Warrant replay is missing rooted native or qualification evidence",
212
+ );
213
+ }
214
+ await exactPullRequestHead(pullRequestNumber, expectedHead);
215
+ return {
216
+ schema: "kungfu.buildchain.two-phase-delivery-result/v1",
217
+ ok: true,
218
+ outcome: "already-qualified-warrant",
219
+ nativeAttempts: 0,
220
+ nativeProofRoot: warrant.nativeProofRoot,
221
+ nativeReuseDecisionRoot: warrant.nativeProofReuseRoot,
222
+ qualificationReceiptRoot: warrant.qualificationReceiptRoot,
223
+ landingAuthority: false,
224
+ qualifiedWarrant: warrant,
225
+ };
226
+ }
227
+
228
+ export async function classifyNativeProofAgainstCurrent(
229
+ proof,
230
+ options,
231
+ client,
232
+ ) {
233
+ const currentBase = await client.baseSha(options.branch);
234
+ const delta = await client.baseDelta(proof.qualifiedBase, currentBase);
235
+ const current = {
236
+ sourceHead: options.expectedHead,
237
+ sourceIdentityRoot: options.sourceIdentityRoot,
238
+ sourcePatchRoot: options.sourcePatchRoot,
239
+ planRoot: options.planRoot,
240
+ closureRoot: options.closureRoot,
241
+ dependencyRoot: options.dependencyRoot,
242
+ toolchainRoot: options.toolchainRoot,
243
+ environmentRoot: options.environmentRoot,
244
+ nativeCommandRoot: options.nativeCommandRoot,
245
+ currentBase,
246
+ graphKnown: delta.graphKnown,
247
+ attributionComplete: delta.attributionComplete,
248
+ changedPaths: delta.changedPaths,
249
+ renames: delta.renames,
250
+ };
251
+ return {
252
+ current,
253
+ decision: createNativeProofReuseDecision({ proof, current }),
254
+ };
255
+ }
256
+
257
+ export async function runNativeQualificationAttempt({
258
+ options,
259
+ warrant,
260
+ attempt,
261
+ client,
262
+ runCommand,
263
+ runNative,
264
+ composeCandidate,
265
+ writeEvidence,
266
+ }) {
267
+ await client.exactPullRequestHead(
268
+ options.pullRequestNumber,
269
+ options.expectedHead,
270
+ );
271
+ const qualifiedBase = await client.baseSha(options.branch);
272
+ composeCandidate(
273
+ options.candidateDirectory,
274
+ options.expectedHead,
275
+ qualifiedBase,
276
+ );
277
+ const commandContract = createNativeCommandContract(options.nativeCommand);
278
+ if (
279
+ commandContract.commandRoot !==
280
+ warrant.nativeCommandContract?.commandRoot ||
281
+ commandContract.commandRoot !== options.nativeCommandRoot
282
+ ) {
283
+ throw new Error(
284
+ "native command does not match the authorized Warrant contract",
285
+ );
286
+ }
287
+ const nativeExecutionReceipt = await runNative({
288
+ command: options.nativeCommand,
289
+ cwd: options.candidateDirectory,
290
+ intervalMs: options.heartbeatSeconds * 1000,
291
+ executionBinding: {
292
+ repository: options.repository,
293
+ protectedBase: options.branch,
294
+ sourceHead: options.expectedHead,
295
+ qualifiedBase,
296
+ nativeCommandRoot: options.nativeCommandRoot,
297
+ toolchainRoot: options.toolchainRoot,
298
+ environmentRoot: options.environmentRoot,
299
+ },
300
+ heartbeat: async () => {
301
+ await runCommand({
302
+ command: "heartbeat",
303
+ repository: options.repository,
304
+ branch: options.branch,
305
+ fencingToken: warrant.fencingToken,
306
+ leaseGeneration: warrant.generation,
307
+ leaseSeconds: options.leaseSeconds,
308
+ execute: true,
309
+ token: options.token,
310
+ apiUrl: options.apiUrl,
311
+ });
312
+ },
313
+ });
314
+ writeEvidence(
315
+ `native-heartbeat-attempt-${attempt}.json`,
316
+ nativeExecutionReceipt,
317
+ );
318
+ await client.exactPullRequestHead(
319
+ options.pullRequestNumber,
320
+ options.expectedHead,
321
+ );
322
+ const proof = createNativeQualificationProof({
323
+ repository: options.repository,
324
+ protectedBase: options.branch,
325
+ sourceIdentityRoot: options.sourceIdentityRoot,
326
+ sourcePatchRoot: options.sourcePatchRoot,
327
+ planRoot: options.planRoot,
328
+ closureRoot: options.closureRoot,
329
+ dependencyRoot: options.dependencyRoot,
330
+ toolchainRoot: options.toolchainRoot,
331
+ environmentRoot: options.environmentRoot,
332
+ sourceHead: options.expectedHead,
333
+ qualifiedBase,
334
+ nativeCommandRoot: options.nativeCommandRoot,
335
+ nativeExecutionReceipt,
336
+ affectedPaths: options.affectedPaths,
337
+ shardEvidenceRoots: [
338
+ ...options.shardEvidenceRoots,
339
+ nativeExecutionReceipt.receiptRoot,
340
+ ],
341
+ qualifiedAt: new Date().toISOString(),
342
+ });
343
+ writeEvidence("native-proof.json", proof);
344
+ return proof;
345
+ }