@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,562 @@
1
+ import {
2
+ devDeliveryClone as clone,
3
+ devDeliveryContentRoot,
4
+ devDeliveryExactRoot as exactRoot,
5
+ devDeliveryExactSha as exactSha,
6
+ devDeliveryProtectedBase as protectedBase,
7
+ devDeliveryRepository as repository,
8
+ devDeliveryText as text,
9
+ devDeliveryTimestamp as timestamp,
10
+ } from "./dev-delivery-common.js";
11
+ import {
12
+ NATIVE_EXECUTION_BINDING_SCHEMA,
13
+ NATIVE_EXECUTION_RECEIPT_SCHEMA,
14
+ NATIVE_COMMAND_CONTRACT_SCHEMA,
15
+ createNativeCommandContract,
16
+ createNativeExecutionBinding,
17
+ createNativeExecutionReceipt,
18
+ normalizeNativeCommandContract,
19
+ verifyNativeExecutionReceipt,
20
+ } from "./dev-delivery-native-execution.js";
21
+ export {
22
+ NATIVE_EXECUTION_BINDING_SCHEMA,
23
+ NATIVE_EXECUTION_RECEIPT_SCHEMA,
24
+ NATIVE_COMMAND_CONTRACT_SCHEMA,
25
+ createNativeCommandContract,
26
+ createNativeExecutionBinding,
27
+ createNativeExecutionReceipt,
28
+ normalizeNativeCommandContract,
29
+ verifyNativeExecutionReceipt,
30
+ };
31
+ export const NATIVE_QUALIFICATION_PROOF_SCHEMA =
32
+ "kungfu.buildchain.native-qualification-proof/v4";
33
+ const LEGACY_NATIVE_QUALIFICATION_PROOF_V3_SCHEMA =
34
+ "kungfu.buildchain.native-qualification-proof/v3";
35
+ const LEGACY_NATIVE_QUALIFICATION_PROOF_V2_SCHEMA =
36
+ "kungfu.buildchain.native-qualification-proof/v2";
37
+ const LEGACY_NATIVE_QUALIFICATION_PROOF_SCHEMA =
38
+ "kungfu.buildchain.native-qualification-proof/v1";
39
+ export const NATIVE_PROOF_REUSE_DECISION_SCHEMA =
40
+ "kungfu.buildchain.native-proof-reuse-decision/v1";
41
+ export const DEV_DELIVERY_QUALIFICATION_RECEIPT_SCHEMA =
42
+ "kungfu.buildchain.dev-delivery-qualification-receipt/v1";
43
+ export const NATIVE_PROOF_BASE_DELTA_SCHEMA =
44
+ "kungfu.buildchain.native-proof-base-delta/v1";
45
+ const NATIVE_QUALIFICATION_ROOT_SEMANTICS = "semantic-native-identity-v1";
46
+
47
+ function normalizeQualifiedWarrant(warrant, candidate, allowLegacyV3Readback) {
48
+ const qualifiedV3Readback =
49
+ allowLegacyV3Readback &&
50
+ !warrant.nativeCommandContract &&
51
+ !candidate.nativeCommandContract &&
52
+ !warrant.nativeExecutionReceiptRoot &&
53
+ !warrant.qualificationReceiptRoot;
54
+ warrant.nativeProofRoot = exactRoot(
55
+ warrant.nativeProofRoot,
56
+ "Warrant nativeProofRoot",
57
+ );
58
+ warrant.nativeProofReuseRoot = exactRoot(
59
+ warrant.nativeProofReuseRoot,
60
+ "Warrant nativeProofReuseRoot",
61
+ );
62
+ if (!qualifiedV3Readback) {
63
+ warrant.nativeExecutionReceiptRoot = exactRoot(
64
+ warrant.nativeExecutionReceiptRoot,
65
+ "Warrant nativeExecutionReceiptRoot",
66
+ );
67
+ warrant.qualificationReceiptRoot = exactRoot(
68
+ warrant.qualificationReceiptRoot,
69
+ "Warrant qualificationReceiptRoot",
70
+ );
71
+ }
72
+ warrant.qualifiedAt = timestamp(warrant.qualifiedAt, "Warrant qualifiedAt");
73
+ }
74
+
75
+ export function validateActiveDevDeliveryWarrant(
76
+ queue,
77
+ { allowLegacyV3Readback = false } = {},
78
+ ) {
79
+ const warrant = queue.activeWarrant;
80
+ if (warrant.schema !== "kungfu.buildchain.dev-delivery-warrant/v1")
81
+ throw new Error("active Warrant schema is unsupported");
82
+ warrant.candidateId = exactRoot(warrant.candidateId, "Warrant candidateId");
83
+ warrant.fencingToken = exactRoot(
84
+ warrant.fencingToken,
85
+ "Warrant fencingToken",
86
+ );
87
+ warrant.expectedOldStateRoot = exactRoot(
88
+ warrant.expectedOldStateRoot,
89
+ "Warrant expectedOldStateRoot",
90
+ );
91
+ if (
92
+ !Number.isInteger(Number(warrant.generation)) ||
93
+ Number(warrant.generation) < 1
94
+ )
95
+ throw new Error("Warrant generation must be a positive integer");
96
+ warrant.generation = Number(warrant.generation);
97
+ warrant.issuedAt = timestamp(warrant.issuedAt, "Warrant issuedAt");
98
+ warrant.expiresAt = timestamp(warrant.expiresAt, "Warrant expiresAt");
99
+ const historicalPhaseLess = !Object.hasOwn(warrant, "phase");
100
+ const phase = historicalPhaseLess ? "legacy-active" : warrant.phase;
101
+ if (!["legacy-active", "provisional", "qualified"].includes(phase))
102
+ throw new Error("active Warrant phase is unsupported");
103
+ const active = queue.candidates.filter((candidate) =>
104
+ ["selected", "proving", "waiting", "blocked", "qualified"].includes(
105
+ candidate.status,
106
+ ),
107
+ );
108
+ if (active.length !== 1 || active[0].candidateId !== warrant.candidateId)
109
+ throw new Error(
110
+ "exactly one active candidate must match the active Warrant",
111
+ );
112
+ if (warrant.phase === "qualified") {
113
+ normalizeQualifiedWarrant(warrant, active[0], allowLegacyV3Readback);
114
+ } else if (
115
+ warrant.phase === "provisional" &&
116
+ (warrant.nativeProofRoot ||
117
+ warrant.nativeProofReuseRoot ||
118
+ warrant.nativeExecutionReceiptRoot ||
119
+ warrant.qualificationReceiptRoot ||
120
+ warrant.qualifiedAt)
121
+ ) {
122
+ throw new Error(
123
+ "provisional Warrant cannot carry qualified native evidence",
124
+ );
125
+ }
126
+ if (
127
+ historicalPhaseLess &&
128
+ (active[0].environmentRoot ||
129
+ warrant.nativeProofRoot ||
130
+ warrant.nativeProofReuseRoot ||
131
+ warrant.qualifiedAt)
132
+ ) {
133
+ throw new Error(
134
+ "phase-less active Warrant must use the historical non-native contract",
135
+ );
136
+ }
137
+ if (phase === "provisional" && active[0].status === "qualified")
138
+ throw new Error("provisional Warrant cannot bind a qualified candidate");
139
+ if (warrant.phase === "qualified" && active[0].status !== "qualified")
140
+ throw new Error("qualified Warrant must bind a qualified candidate");
141
+ if (
142
+ warrant.releaseBlockerPriority?.claimRoot !==
143
+ active[0].releaseBlockerPriority?.claimRoot
144
+ )
145
+ throw new Error("active Warrant release-blocker priority drift");
146
+ if (
147
+ warrant.nativeCommandContract?.commandRoot !==
148
+ active[0].nativeCommandContract?.commandRoot
149
+ )
150
+ throw new Error("active Warrant native command contract drift");
151
+ if (
152
+ JSON.stringify(warrant.shardEvidenceRoots || []) !==
153
+ JSON.stringify(active[0].shardEvidenceRoots || [])
154
+ )
155
+ throw new Error("active Warrant shard evidence roots drift");
156
+ }
157
+ export function createDevDeliveryWarrantToken(input) {
158
+ return devDeliveryContentRoot({
159
+ schema: "kungfu.buildchain.dev-delivery-warrant/v1",
160
+ repository: input.repository,
161
+ protectedBase: input.protectedBase,
162
+ candidateId: input.candidateId,
163
+ phase: input.phase,
164
+ generation: input.generation,
165
+ expectedOldStateRoot: input.expectedOldStateRoot,
166
+ issuedAt: input.issuedAt,
167
+ });
168
+ }
169
+ function exactRoots(values, label) {
170
+ if (!Array.isArray(values) || values.length === 0) {
171
+ throw new Error(`${label} must contain at least one content root`);
172
+ }
173
+ return [...new Set(values.map((value) => exactRoot(value, label)))].sort();
174
+ }
175
+ function normalizedPaths(values) {
176
+ if (!Array.isArray(values)) throw new Error("paths must be a JSON array");
177
+ return [
178
+ ...new Set(
179
+ values
180
+ .map(text)
181
+ .map((entry) => entry.replace(/^\.\//u, "").replace(/\/+$/u, ""))
182
+ .filter(Boolean),
183
+ ),
184
+ ].sort();
185
+ }
186
+ function normalizedRenames(values) {
187
+ if (!Array.isArray(values)) throw new Error("renames must be a JSON array");
188
+ return values
189
+ .map((entry) => ({
190
+ from: normalizedPaths([entry?.from])[0] || "",
191
+ to: normalizedPaths([entry?.to])[0] || "",
192
+ }))
193
+ .filter((entry) => entry.from && entry.to)
194
+ .sort(
195
+ (left, right) =>
196
+ left.from.localeCompare(right.from) || left.to.localeCompare(right.to),
197
+ );
198
+ }
199
+ export function createNativeProofBaseDelta(input = {}) {
200
+ const body = {
201
+ schema: NATIVE_PROOF_BASE_DELTA_SCHEMA,
202
+ repository: repository(input.repository),
203
+ protectedBase: protectedBase(input.protectedBase),
204
+ qualifiedBase: exactSha(input.qualifiedBase, "qualifiedBase"),
205
+ currentBase: exactSha(input.currentBase, "currentBase"),
206
+ graphKnown: input.graphKnown === true,
207
+ attributionComplete: input.attributionComplete === true,
208
+ changedPaths: normalizedPaths(input.changedPaths || []),
209
+ renames: normalizedRenames(input.renames || []),
210
+ };
211
+ return { ...body, deltaRoot: devDeliveryContentRoot(body) };
212
+ }
213
+ function proofIdentity(body) {
214
+ const identity = clone(body);
215
+ delete identity.qualifiedAt;
216
+ delete identity.observationRoot;
217
+ return identity;
218
+ }
219
+ function proofObservation(body) {
220
+ return { qualifiedAt: body.qualifiedAt };
221
+ }
222
+ function rooted(body) {
223
+ return { ...body, decisionRoot: devDeliveryContentRoot(body) };
224
+ }
225
+ export function createNativeQualificationProof(input = {}) {
226
+ const sourceHead = exactSha(input.sourceHead, "sourceHead");
227
+ const qualifiedBase = exactSha(input.qualifiedBase, "qualifiedBase");
228
+ const toolchainRoot = exactRoot(input.toolchainRoot, "toolchainRoot");
229
+ const environmentRoot = exactRoot(input.environmentRoot, "environmentRoot");
230
+ const nativeCommandRoot = exactRoot(
231
+ input.nativeCommandRoot,
232
+ "nativeCommandRoot",
233
+ );
234
+ const executionReceipt = verifyNativeExecutionReceipt(
235
+ input.nativeExecutionReceipt,
236
+ {
237
+ repository: repository(input.repository),
238
+ protectedBase: protectedBase(input.protectedBase),
239
+ sourceHead,
240
+ qualifiedBase,
241
+ nativeCommandRoot,
242
+ toolchainRoot,
243
+ environmentRoot,
244
+ },
245
+ );
246
+ if (!executionReceipt.ok) {
247
+ throw new Error(
248
+ `native execution receipt rejected: ${executionReceipt.reason}`,
249
+ );
250
+ }
251
+ const body = {
252
+ schema: NATIVE_QUALIFICATION_PROOF_SCHEMA,
253
+ rootSemantics: NATIVE_QUALIFICATION_ROOT_SEMANTICS,
254
+ repository: repository(input.repository),
255
+ protectedBase: protectedBase(input.protectedBase),
256
+ sourceIdentityRoot: exactRoot(
257
+ input.sourceIdentityRoot,
258
+ "sourceIdentityRoot",
259
+ ),
260
+ sourcePatchRoot: exactRoot(input.sourcePatchRoot, "sourcePatchRoot"),
261
+ planRoot: exactRoot(input.planRoot, "planRoot"),
262
+ closureRoot: exactRoot(input.closureRoot, "closureRoot"),
263
+ dependencyRoot: exactRoot(input.dependencyRoot, "dependencyRoot"),
264
+ toolchainRoot,
265
+ environmentRoot,
266
+ sourceHead,
267
+ qualifiedBase,
268
+ nativeCommandRoot,
269
+ nativeExecutionBindingRoot: executionReceipt.executionBindingRoot,
270
+ nativeExecutionReceiptRoot: executionReceipt.receiptRoot,
271
+ nativeExecutionReceipt: executionReceipt.receipt,
272
+ affectedPaths: normalizedPaths(input.affectedPaths || []),
273
+ shardEvidenceRoots: exactRoots(
274
+ [...(input.shardEvidenceRoots || []), executionReceipt.receiptRoot],
275
+ "shardEvidenceRoots",
276
+ ),
277
+ qualifiedAt: timestamp(input.qualifiedAt, "qualifiedAt"),
278
+ };
279
+ body.observationRoot = devDeliveryContentRoot(proofObservation(body));
280
+ return {
281
+ ...body,
282
+ proofRoot: devDeliveryContentRoot(proofIdentity(body)),
283
+ };
284
+ }
285
+ export function verifyNativeQualificationProof(proofInput, expected = {}) {
286
+ try {
287
+ const proof = clone(proofInput || {});
288
+ if (
289
+ ![
290
+ NATIVE_QUALIFICATION_PROOF_SCHEMA,
291
+ LEGACY_NATIVE_QUALIFICATION_PROOF_V3_SCHEMA,
292
+ LEGACY_NATIVE_QUALIFICATION_PROOF_V2_SCHEMA,
293
+ LEGACY_NATIVE_QUALIFICATION_PROOF_SCHEMA,
294
+ ].includes(proof.schema)
295
+ ) {
296
+ return { ok: false, reason: "unsupported-schema" };
297
+ }
298
+ const proofRoot = proof.proofRoot;
299
+ delete proof.proofRoot;
300
+ if (proof.rootSemantics !== NATIVE_QUALIFICATION_ROOT_SEMANTICS) {
301
+ return { ok: false, reason: "unsupported-root-semantics" };
302
+ }
303
+ if (devDeliveryContentRoot(proofIdentity(proof)) !== proofRoot) {
304
+ return { ok: false, reason: "proof-root-drift" };
305
+ }
306
+ if (
307
+ devDeliveryContentRoot(proofObservation(proof)) !== proof.observationRoot
308
+ ) {
309
+ return { ok: false, reason: "observation-root-drift" };
310
+ }
311
+ for (const [field, value] of Object.entries(expected)) {
312
+ if (value !== undefined && proof[field] !== value) {
313
+ return { ok: false, reason: `${field}-mismatch` };
314
+ }
315
+ }
316
+ if (proof.schema === NATIVE_QUALIFICATION_PROOF_SCHEMA) {
317
+ repository(proof.repository);
318
+ protectedBase(proof.protectedBase);
319
+ exactSha(proof.sourceHead, "sourceHead");
320
+ exactSha(proof.qualifiedBase, "qualifiedBase");
321
+ for (const field of [
322
+ "sourceIdentityRoot",
323
+ "sourcePatchRoot",
324
+ "planRoot",
325
+ "closureRoot",
326
+ "dependencyRoot",
327
+ "toolchainRoot",
328
+ "environmentRoot",
329
+ "nativeCommandRoot",
330
+ "nativeExecutionBindingRoot",
331
+ "nativeExecutionReceiptRoot",
332
+ ]) {
333
+ exactRoot(proof[field], field);
334
+ }
335
+ const expectedBindingRoot = devDeliveryContentRoot(
336
+ createNativeExecutionBinding(proof),
337
+ );
338
+ if (proof.nativeExecutionBindingRoot !== expectedBindingRoot) {
339
+ return { ok: false, reason: "native-execution-binding-root-drift" };
340
+ }
341
+ const shardEvidenceRoots = exactRoots(
342
+ proof.shardEvidenceRoots,
343
+ "shardEvidenceRoots",
344
+ );
345
+ if (!shardEvidenceRoots.includes(proof.nativeExecutionReceiptRoot)) {
346
+ return { ok: false, reason: "native-execution-receipt-unbound" };
347
+ }
348
+ if (!proof.nativeExecutionReceipt) {
349
+ return {
350
+ ok: false,
351
+ reason: "native-execution-receipt-bytes-missing",
352
+ };
353
+ }
354
+ const executionReceipt = verifyNativeExecutionReceipt(
355
+ proof.nativeExecutionReceipt,
356
+ {
357
+ repository: proof.repository,
358
+ protectedBase: proof.protectedBase,
359
+ sourceHead: proof.sourceHead,
360
+ qualifiedBase: proof.qualifiedBase,
361
+ nativeCommandRoot: proof.nativeCommandRoot,
362
+ toolchainRoot: proof.toolchainRoot,
363
+ environmentRoot: proof.environmentRoot,
364
+ },
365
+ );
366
+ if (!executionReceipt.ok) {
367
+ return {
368
+ ok: false,
369
+ reason: `native-execution-${executionReceipt.reason}`,
370
+ };
371
+ }
372
+ if (
373
+ executionReceipt.receiptRoot !== proof.nativeExecutionReceiptRoot ||
374
+ executionReceipt.executionBindingRoot !==
375
+ proof.nativeExecutionBindingRoot
376
+ ) {
377
+ return { ok: false, reason: "native-execution-receipt-root-drift" };
378
+ }
379
+ if (
380
+ Date.parse(proof.qualifiedAt) <
381
+ Date.parse(executionReceipt.receipt.completedAt)
382
+ ) {
383
+ return {
384
+ ok: false,
385
+ reason: "native-execution-qualified-before-completion",
386
+ };
387
+ }
388
+ normalizedPaths(proof.affectedPaths || []);
389
+ timestamp(proof.qualifiedAt, "qualifiedAt");
390
+ } else {
391
+ repository(proof.repository);
392
+ protectedBase(proof.protectedBase);
393
+ exactSha(proof.qualifiedBase, "qualifiedBase");
394
+ for (const field of [
395
+ "sourceIdentityRoot",
396
+ "sourcePatchRoot",
397
+ "planRoot",
398
+ "closureRoot",
399
+ "dependencyRoot",
400
+ "toolchainRoot",
401
+ ]) {
402
+ exactRoot(proof[field], field);
403
+ }
404
+ normalizedPaths(proof.affectedPaths || []);
405
+ exactRoots(proof.shardEvidenceRoots, "shardEvidenceRoots");
406
+ timestamp(proof.qualifiedAt, "qualifiedAt");
407
+ }
408
+ return { ok: true, reason: "exact-native-proof", proofRoot };
409
+ } catch (error) {
410
+ return { ok: false, reason: "invalid-proof", error: error.message };
411
+ }
412
+ }
413
+ function pathsOverlap(changedPath, affectedPath) {
414
+ if (affectedPath === "*" || affectedPath === "**") return true;
415
+ return (
416
+ changedPath === affectedPath ||
417
+ changedPath.startsWith(`${affectedPath}/`) ||
418
+ affectedPath.startsWith(`${changedPath}/`)
419
+ );
420
+ }
421
+ function nativeReuseBody(proof, current) {
422
+ const verification = verifyNativeQualificationProof(proof);
423
+ const currentBase = current.currentBase
424
+ ? exactSha(current.currentBase, "currentBase")
425
+ : null;
426
+ const changedPaths = normalizedPaths(current.changedPaths || []);
427
+ const base = {
428
+ schema: NATIVE_PROOF_REUSE_DECISION_SCHEMA,
429
+ proofRoot: verification.ok ? proof.proofRoot : null,
430
+ repository: verification.ok ? proof.repository : null,
431
+ protectedBase: verification.ok ? proof.protectedBase : null,
432
+ qualifiedBase: verification.ok ? proof.qualifiedBase : null,
433
+ currentBase,
434
+ graphKnown: current.graphKnown === true,
435
+ attributionComplete: current.attributionComplete === true,
436
+ changedPaths,
437
+ renames: normalizedRenames(current.renames || []),
438
+ baseDeltaRoot: null,
439
+ overlappingPaths: [],
440
+ reusable: false,
441
+ action: "rerun-full-native-qualification",
442
+ reason: verification.reason,
443
+ requiredValidation: "full-native",
444
+ };
445
+ if (!verification.ok) return base;
446
+ if (proof.schema !== NATIVE_QUALIFICATION_PROOF_SCHEMA) {
447
+ return {
448
+ ...base,
449
+ reason: "native-execution-evidence-unbound",
450
+ };
451
+ }
452
+ const semanticFields = [
453
+ "sourceHead",
454
+ "sourceIdentityRoot",
455
+ "sourcePatchRoot",
456
+ "planRoot",
457
+ "closureRoot",
458
+ "dependencyRoot",
459
+ "toolchainRoot",
460
+ "environmentRoot",
461
+ "nativeCommandRoot",
462
+ ];
463
+ for (const field of semanticFields) {
464
+ if (!current[field] || current[field] !== proof[field]) {
465
+ return {
466
+ ...base,
467
+ reason: `${field}-changed-or-unknown`,
468
+ };
469
+ }
470
+ }
471
+ if (!currentBase) {
472
+ return { ...base, reason: "current-base-unknown" };
473
+ }
474
+ const delta = createNativeProofBaseDelta({
475
+ repository: proof.repository,
476
+ protectedBase: proof.protectedBase,
477
+ qualifiedBase: proof.qualifiedBase,
478
+ currentBase,
479
+ graphKnown: current.graphKnown,
480
+ attributionComplete: current.attributionComplete,
481
+ changedPaths,
482
+ renames: current.renames || [],
483
+ });
484
+ base.baseDeltaRoot = delta.deltaRoot;
485
+ base.renames = delta.renames;
486
+ if (currentBase === proof.qualifiedBase) {
487
+ return {
488
+ ...base,
489
+ reusable: true,
490
+ action: "accept-fresh-native-proof",
491
+ reason: "exact-qualified-base",
492
+ requiredValidation: "exact-merge-group",
493
+ };
494
+ }
495
+ if (
496
+ current.graphKnown !== true ||
497
+ current.attributionComplete !== true ||
498
+ !Array.isArray(current.changedPaths) ||
499
+ !Array.isArray(current.renames)
500
+ ) {
501
+ return { ...base, reason: "base-delta-attribution-unknown" };
502
+ }
503
+ if (proof.affectedPaths.length === 0) {
504
+ return { ...base, reason: "affected-closure-paths-unknown" };
505
+ }
506
+ const attributedPaths = [
507
+ ...changedPaths,
508
+ ...base.renames.flatMap((rename) => [rename.from, rename.to]),
509
+ ];
510
+ const overlap = [...new Set(attributedPaths)].filter((changedPath) =>
511
+ proof.affectedPaths.some((affectedPath) =>
512
+ pathsOverlap(changedPath, affectedPath),
513
+ ),
514
+ );
515
+ if (overlap.length > 0) {
516
+ return {
517
+ ...base,
518
+ action: "rerun-affected-native-shards",
519
+ reason: "base-delta-overlaps-affected-closure",
520
+ requiredValidation: "incremental-or-full-native",
521
+ overlappingPaths: overlap,
522
+ };
523
+ }
524
+ return {
525
+ ...base,
526
+ reusable: true,
527
+ action: "reuse-native-proof",
528
+ reason: "semantic-source-stable-and-base-delta-disjoint",
529
+ requiredValidation: "exact-merge-group",
530
+ };
531
+ }
532
+ export function createNativeProofReuseDecision({ proof, current = {} } = {}) {
533
+ return rooted(nativeReuseBody(proof, current));
534
+ }
535
+ export function verifyNativeProofReuseDecision(
536
+ decisionInput,
537
+ { proof, current = {} } = {},
538
+ ) {
539
+ try {
540
+ const decision = clone(decisionInput || {});
541
+ if (decision.schema !== NATIVE_PROOF_REUSE_DECISION_SCHEMA) {
542
+ return { ok: false, reason: "unsupported-schema" };
543
+ }
544
+ const decisionRoot = decision.decisionRoot;
545
+ delete decision.decisionRoot;
546
+ if (devDeliveryContentRoot(decision) !== decisionRoot) {
547
+ return { ok: false, reason: "decision-root-drift" };
548
+ }
549
+ const recomputed = nativeReuseBody(proof, current);
550
+ if (JSON.stringify(decision) !== JSON.stringify(recomputed)) {
551
+ return { ok: false, reason: "decision-input-drift" };
552
+ }
553
+ return {
554
+ ok: decision.reusable === true,
555
+ reason: decision.reason,
556
+ decisionRoot,
557
+ action: decision.action,
558
+ };
559
+ } catch (error) {
560
+ return { ok: false, reason: "invalid-decision", error: error.message };
561
+ }
562
+ }