@kungfu-tech/buildchain 3.0.9-alpha.8 → 4.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (255) hide show
  1. package/AGENTS.md +39 -0
  2. package/README.md +17 -13
  3. package/actions/promote-buildchain-ref/README.md +0 -10
  4. package/actions/release-tail/README.md +6 -10
  5. package/architecture/internal-capabilities.json +502 -0
  6. package/architecture/maintainability-baseline.json +59 -0
  7. package/architecture/maintainability-policy.json +1384 -0
  8. package/architecture/release-tail-contract-inventory.json +587 -0
  9. package/architecture/v3-core-mechanism-inventory.json +1043 -0
  10. package/architecture/v3-core-mechanism-inventory.md +67 -0
  11. package/architecture/v4-adopter-delivery-parity.json +47 -0
  12. package/architecture/v4-architecture-constitution.md +210 -0
  13. package/architecture/v4-bootstrap-authority.json +56 -0
  14. package/architecture/v4-canonical-contract-fixtures.json +105 -0
  15. package/architecture/v4-capability-state-machine-manifest.json +480 -0
  16. package/architecture/v4-capability-state-machine-manifest.schema.json +202 -0
  17. package/architecture/v4-delivery-warrant-shadow-bootstrap-plan.json +830 -0
  18. package/architecture/v4-delivery-warrant-shadow-bootstrap-plan.md +223 -0
  19. package/architecture/v4-delivery-warrant-shadow-bootstrap-plan.schema.json +318 -0
  20. package/architecture/v4-delivery-warrant-shadow-fixtures.json +227 -0
  21. package/architecture/v4-delivery-warrant-shadow-fixtures.schema.json +67 -0
  22. package/architecture/v4-exception-ledger.json +5 -0
  23. package/architecture/v4-exception-ledger.schema.json +56 -0
  24. package/architecture/v4-partial-mutation-recovery-qualification.json +65 -0
  25. package/architecture/v4-platform-stage-checkpoints.json +97 -0
  26. package/architecture/v4-provider-operation-journal-contract.json +113 -0
  27. package/architecture/v4-release-activation-shadow-domain.json +61 -0
  28. package/architecture/v4-release-train-parity.json +68 -0
  29. package/architecture/v4-rust-libnode-bridge-evaluation.json +107 -0
  30. package/architecture/v4-rust-libnode-bridge-spike.md +85 -0
  31. package/architecture/v4-stable-publication-fence.json +66 -0
  32. package/architecture/v4-stage-capsule-contract.json +90 -0
  33. package/architecture/v4-stage-capsule-qualification.json +99 -0
  34. package/architecture/v4-stage-capsule-resume-planner.json +52 -0
  35. package/architecture/v4-stage-capsule-store-contract.json +72 -0
  36. package/bin/buildchain.mjs +15 -6
  37. package/contracts/auditable-demo-scenario-v1.schema.json +1 -1
  38. package/contracts/buildchain-v2-residuals-v1.json +2 -2
  39. package/contracts/fixtures/v4-delivery-warrant-trace-v1/golden.json +158 -0
  40. package/contracts/fixtures/v4-delivery-warrant-trace-v1/property.json +380 -0
  41. package/contracts/fixtures/v4-delivery-warrant-trace-v1/replay.json +163 -0
  42. package/contracts/fixtures/v4-partial-mutation-recovery-v1/shared.json +155 -0
  43. package/contracts/fixtures/v4-provider-operation-journal-v1/shared.json +457 -0
  44. package/contracts/fixtures/v4-provider-readback-idempotency-v1/shared.json +682 -0
  45. package/contracts/fixtures/v4-release-activation-shadow-v1/shared.json +53 -0
  46. package/contracts/fixtures/v4-stable-publication-fence-v1/shared.json +56 -0
  47. package/contracts/fixtures/v4-stage-capsule-resume-v1/late-platform-failure.json +176 -0
  48. package/contracts/fixtures/v4-stage-capsule-store-v1/shared.json +132 -0
  49. package/contracts/fixtures/v4-stage-capsule-v1/shared.json +111 -0
  50. package/contracts/v4-canonical-contracts-v1.schema.json +182 -0
  51. package/contracts/v4-delivery-warrant-semantic-diff-report-v1.schema.json +284 -0
  52. package/contracts/v4-delivery-warrant-trace-v1.schema.json +215 -0
  53. package/contracts/v4-host-contract-v1.schema.json +135 -0
  54. package/contracts/v4-partial-mutation-recovery-v1.schema.json +168 -0
  55. package/contracts/v4-provider-operation-journal-v1.schema.json +381 -0
  56. package/contracts/v4-release-activation-shadow-v1.schema.json +186 -0
  57. package/contracts/v4-stable-publication-fence-v1.schema.json +125 -0
  58. package/contracts/v4-stage-capsule-resume-v1.schema.json +225 -0
  59. package/contracts/v4-stage-capsule-store-v1.schema.json +154 -0
  60. package/contracts/v4-stage-capsule-v1.schema.json +178 -0
  61. package/crates/buildchain-v4-bridge/Cargo.lock +213 -0
  62. package/crates/buildchain-v4-bridge/Cargo.toml +12 -0
  63. package/crates/buildchain-v4-bridge/src/main.rs +495 -0
  64. package/dist/site/agent-index.json +0 -3
  65. package/dist/site/artifact-schemas.json +0 -6
  66. package/dist/site/buildchain-contract.json +103 -397
  67. package/dist/site/buildchain-site.json +302 -270
  68. package/dist/site/capability-registry.json +9 -11
  69. package/dist/site/cli-registry.json +8 -30
  70. package/dist/site/controller-registry.json +48 -8
  71. package/dist/site/kfd-claims.json +129 -142
  72. package/dist/site/kfd-upstream-aggregate.json +9 -9
  73. package/dist/site/manual-registry.json +18 -49
  74. package/dist/site/node-api-registry.json +1882 -4118
  75. package/dist/site/page-registry.json +278 -230
  76. package/dist/site/public-surface-audit.json +87 -185
  77. package/dist/site/publication-authority-registry.json +11 -1
  78. package/dist/site/publication-registry.json +4 -4
  79. package/dist/site/release-provenance.json +3 -7
  80. package/dist/site/schemas/kfd-support-projection-v1.schema.json +106 -0
  81. package/dist/site/site-manifest.json +22 -38
  82. package/dist/site/workflow-registry.json +80 -35
  83. package/docs/MAP.md +8 -4
  84. package/docs/auditable-demo.md +2 -2
  85. package/docs/aws-us-elastic-runner-burst-plane.md +7 -59
  86. package/docs/cli-reference.md +15 -92
  87. package/docs/cli.md +14 -14
  88. package/docs/dev-alpha-candidate-patrol.md +3 -11
  89. package/docs/dev-delivery-warrant.md +28 -100
  90. package/docs/engineering-housekeeper.md +12 -4
  91. package/docs/getting-started.md +1 -1
  92. package/docs/install.md +5 -5
  93. package/docs/kfd-support.md +2 -7
  94. package/docs/lifecycle-protocol.md +2 -4
  95. package/docs/node-api-reference.md +414 -523
  96. package/docs/release-flow.md +31 -31
  97. package/docs/release-governance.md +16 -28
  98. package/docs/release-passport.md +2 -15
  99. package/docs/release-tail-contract.md +13 -6
  100. package/docs/release-tail-provider-plane.md +13 -19
  101. package/docs/release-train.md +4 -4
  102. package/docs/reusable-build-surface.md +14 -27
  103. package/docs/site-bundle-contract.md +1 -5
  104. package/docs/stable-candidate-patrol.md +7 -7
  105. package/docs/v4-canonical-contracts.md +92 -0
  106. package/docs/v4-delivery-warrant-read-candidate.md +73 -0
  107. package/docs/v4-delivery-warrant-semantic-diff.md +75 -0
  108. package/docs/v4-production-release.md +63 -0
  109. package/docs/v4-stage-capsule.md +193 -0
  110. package/docs/versioning.md +3 -3
  111. package/package.json +19 -17
  112. package/packages/core/adopter-delivery-gate.js +576 -0
  113. package/packages/core/adopter-delivery-json.js +66 -0
  114. package/packages/core/artifact-signing.js +0 -61
  115. package/packages/core/artifact-verification-envelope.js +5 -5
  116. package/packages/core/build-facts.js +12 -4
  117. package/packages/core/buildchain-agent-manuals.js +0 -2
  118. package/packages/core/buildchain-config.js +4 -69
  119. package/packages/core/buildchain-contract.js +232 -46
  120. package/packages/core/buildchain-kfd-claims.js +1 -1
  121. package/packages/core/channel-candidate.js +0 -8
  122. package/packages/core/channel-promotion-baseline.js +0 -52
  123. package/packages/core/controller-evidence.js +3 -4
  124. package/packages/core/dev-alpha-candidate-selection.js +2 -10
  125. package/packages/core/dev-delivery-warrant-cancellation.js +0 -1
  126. package/packages/core/dev-delivery-warrant-settlement.js +1 -5
  127. package/packages/core/dev-delivery-warrant.js +12 -52
  128. package/packages/core/diagnostics.js +3 -8
  129. package/packages/core/github-governance-authority.js +3 -1
  130. package/packages/core/kfd-adopter-category-driver.js +167 -0
  131. package/packages/core/kfd-adopter-manifest.js +47 -46
  132. package/packages/core/kfd-gate.js +15 -45
  133. package/packages/core/paper-agent-entry.js +7 -16
  134. package/packages/core/paper-fleet.js +2 -2
  135. package/packages/core/paper-repository.js +2 -3
  136. package/packages/core/paper-scaffold-content.js +2 -23
  137. package/packages/core/paper.js +11 -43
  138. package/packages/core/publication-reproducibility.js +4 -4
  139. package/packages/core/release-line-bootstrap.js +21 -8
  140. package/packages/core/release-passport-contract.js +5 -5
  141. package/packages/core/release-passport.js +20 -131
  142. package/packages/core/self-dogfood-version.js +48 -35
  143. package/packages/core/spawn-command.js +232 -8
  144. package/packages/core/v4-adopter-delivery-parity.js +219 -0
  145. package/packages/core/v4-canonical-contracts.js +284 -0
  146. package/packages/core/v4-delivery-warrant-fixture-runner.js +371 -0
  147. package/packages/core/v4-delivery-warrant-read-candidate.js +279 -0
  148. package/packages/core/v4-delivery-warrant-semantic-diff-gate.js +352 -0
  149. package/packages/core/v4-delivery-warrant-shadow-adapter.js +447 -0
  150. package/packages/core/v4-partial-mutation-recovery-qualification.js +395 -0
  151. package/packages/core/v4-platform-stage-checkpoints.js +471 -0
  152. package/packages/core/v4-provider-operation-journal.js +531 -0
  153. package/packages/core/v4-provider-readback-idempotency.js +394 -0
  154. package/packages/core/v4-release-activation-shadow.js +519 -0
  155. package/packages/core/v4-stable-publication-fence.js +357 -0
  156. package/packages/core/v4-stage-capsule-local-store.js +426 -0
  157. package/packages/core/v4-stage-capsule-qualification-campaign.js +512 -0
  158. package/packages/core/v4-stage-capsule-qualification.js +456 -0
  159. package/packages/core/v4-stage-capsule-resume-planner.js +397 -0
  160. package/packages/core/v4-stage-capsule-store.js +401 -0
  161. package/packages/core/v4-stage-capsule.js +319 -0
  162. package/scripts/assemble-self-publication-admission.mjs +1 -1
  163. package/scripts/audit-publication-control-plane.mjs +5 -5
  164. package/scripts/auditable-demo-bundle-verification.mjs +3 -2
  165. package/scripts/auditable-demo-platform.mjs +2 -2
  166. package/scripts/auditable-demo-renditions.mjs +1 -1
  167. package/scripts/auditable-demo.mjs +2 -2
  168. package/scripts/aws-macos-jit-controller-core.mjs +13 -346
  169. package/scripts/aws-macos-jit-controller-runtime.mjs +2 -210
  170. package/scripts/aws-macos-jit-controller.mjs +37 -275
  171. package/scripts/aws-macos-jit-core.mjs +3 -41
  172. package/scripts/aws-macos-jit.mjs +0 -12
  173. package/scripts/aws-windows-jit-campaign.mjs +2 -2
  174. package/scripts/aws-windows-jit-controller-core.mjs +1 -1
  175. package/scripts/aws-windows-jit-controller.mjs +3 -3
  176. package/scripts/build-contract-core.mjs +3 -8
  177. package/scripts/build-standalone-binary.mjs +3 -14
  178. package/scripts/buildchain-channel-router.mjs +4 -0
  179. package/scripts/buildchain-cli-help.mjs +7 -13
  180. package/scripts/buildchain-contract-lock.mjs +0 -6
  181. package/scripts/check-action-bundles.mjs +3 -4
  182. package/scripts/check-internal-architecture.mjs +7 -6
  183. package/scripts/check-inventory.mjs +30 -25
  184. package/scripts/check-v4-public-dogfood-contract.mjs +270 -0
  185. package/scripts/create-release-bundle.mjs +8 -4
  186. package/scripts/dev-alpha-candidate-patrol.mjs +1 -22
  187. package/scripts/dev-delivery-proof.mjs +2 -54
  188. package/scripts/dev-delivery-warrant.mjs +59 -77
  189. package/scripts/dev-pr-auto-merge.mjs +4 -30
  190. package/scripts/dev-pr-delivery-warrant.mjs +0 -55
  191. package/scripts/dispatch-artifact-signing-authority.mjs +7 -4
  192. package/scripts/generate-buildchain-kfd-witnesses.mjs +94 -88
  193. package/scripts/generate-channel-build-workflow.mjs +54 -24
  194. package/scripts/generate-channel-promotion-workflow.mjs +15 -6
  195. package/scripts/generate-site-bundle.mjs +5 -21
  196. package/scripts/git-fetch-process-tree.mjs +34 -1
  197. package/scripts/init-repo.mjs +64 -159
  198. package/scripts/inspect-artifact-signing-requests.mjs +0 -6
  199. package/scripts/locked-source-checkout.mjs +3 -4
  200. package/scripts/maintainability-metrics.mjs +8 -2
  201. package/scripts/npm-publish-dry-run.mjs +2 -2
  202. package/scripts/npm-publish-transaction.mjs +2 -2
  203. package/scripts/publication-commit-evidence.mjs +23 -69
  204. package/scripts/release-candidate-resolver.mjs +11 -17
  205. package/scripts/release-tail.mjs +3 -49
  206. package/scripts/resume-from-candidate-run.mjs +9 -123
  207. package/scripts/run-lifecycle-core.mjs +12 -13
  208. package/scripts/seal-artifact-signing-requests.mjs +17 -21
  209. package/scripts/site-capability-metadata.mjs +2 -7
  210. package/scripts/stable-candidate-qualification.mjs +10 -10
  211. package/scripts/v4-architecture.mjs +12 -2
  212. package/scripts/v4-bridge-bootstrap.mjs +141 -0
  213. package/scripts/v4-bridge-evidence.mjs +141 -0
  214. package/scripts/v4-host-adapter.mjs +182 -0
  215. package/scripts/v4-platform-stage-checkpoint-rehearsal.mjs +207 -0
  216. package/scripts/v4-stage-capsule-qualification.mjs +528 -0
  217. package/scripts/v4-stage-capsule-resume-rehearsal.mjs +57 -0
  218. package/scripts/v4-warrant-shadow-plan.mjs +601 -0
  219. package/scripts/verify-golden-path.mjs +5 -5
  220. package/scripts/web-surface-cloudfront-rewrite.mjs +15 -15
  221. package/scripts/web-surface-core.mjs +2 -8
  222. package/scripts/workflow-call-contract.mjs +5 -184
  223. package/contracts/fixtures/kfd-adopter-release-v1/kfd-4-perspective.json +0 -16
  224. package/contracts/fixtures/kfd-adopter-release-v1/kfd-4-replay.json +0 -57
  225. package/contracts/fixtures/next-development-transition-v1/anchored-manual-waiting.json +0 -47
  226. package/contracts/fixtures/next-development-transition-v1/semver-auto-planned.json +0 -47
  227. package/contracts/fixtures/next-development-transition-v1/version-model-cases.json +0 -40
  228. package/contracts/next-development-request-v1.schema.json +0 -66
  229. package/contracts/next-development-transition-v1.schema.json +0 -292
  230. package/contracts/publication-rehearsal-capsule-v1.schema.json +0 -173
  231. package/dist/site/schemas/publication-rehearsal-capsule-v1.schema.json +0 -269
  232. package/dist/site/schemas/release-tail-capabilities-v1.schema.json +0 -353
  233. package/dist/site/schemas/release-tail-provider-bindings-v1.schema.json +0 -94
  234. package/docs/next-development-transition.md +0 -119
  235. package/docs/publication-rehearsal.md +0 -94
  236. package/packages/core/buildchain-compatibility-proof.js +0 -631
  237. package/packages/core/dev-delivery-native-proof.js +0 -333
  238. package/packages/core/dev-delivery-warrant-shadow.js +0 -502
  239. package/packages/core/next-development-candidate-reservation.js +0 -186
  240. package/packages/core/next-development-controller.js +0 -726
  241. package/packages/core/next-development-projection.js +0 -288
  242. package/packages/core/next-development-transition.js +0 -738
  243. package/packages/core/publication-rehearsal-projection.js +0 -173
  244. package/packages/core/publication-rehearsal-runtime.js +0 -921
  245. package/scripts/aws-macos-jit-instance-rehydrate.mjs +0 -260
  246. package/scripts/aws-macos-jit-source-rebind.mjs +0 -724
  247. package/scripts/dev-delivery-native-run.mjs +0 -187
  248. package/scripts/dev-delivery-two-phase.mjs +0 -598
  249. package/scripts/generate-next-development-guidance.mjs +0 -49
  250. package/scripts/materialize-self-release-candidate-version.mjs +0 -137
  251. package/scripts/next-development-self-dogfood-harness.mjs +0 -409
  252. package/scripts/next-development-self-dogfood.mjs +0 -532
  253. package/scripts/next-development-transition.mjs +0 -47
  254. package/scripts/release-candidate-tail-reseal.mjs +0 -426
  255. package/templates/native-dev-delivery.yml +0 -82
@@ -0,0 +1,456 @@
1
+ import {
2
+ V4ContractFault,
3
+ v4ContentRoot,
4
+ validateV4Root,
5
+ } from "./v4-canonical-contracts.js";
6
+
7
+ export const V4_STAGE_CAPSULE_PLATFORM_QUALIFICATION_CONTRACT =
8
+ "buildchain-v4-stage-capsule-platform-qualification/v1";
9
+ export const V4_STAGE_CAPSULE_QUALIFICATION_CONTRACT =
10
+ "buildchain-v4-stage-capsule-qualification/v1";
11
+ export const V4_STAGE_CAPSULE_WAVE_RECONCILIATION_CONTRACT =
12
+ "buildchain-v4-stage-capsule-wave-reconciliation/v1";
13
+
14
+ const PLATFORMS = ["linux-x64", "macos-arm64", "windows-x64"];
15
+ const CONSUMERS = ["buildchain"];
16
+ const FAULTS = [
17
+ "corrupt",
18
+ "cross-platform",
19
+ "cross-stage",
20
+ "expired",
21
+ "missing",
22
+ "partial",
23
+ "policy-drift",
24
+ "root-mismatch",
25
+ "source-drift",
26
+ "stale-writer",
27
+ "toolchain-drift",
28
+ ];
29
+ const CHILDREN = [
30
+ "stage-capsule-contracts",
31
+ "stage-capsule-store-retention",
32
+ "platform-stage-checkpoints",
33
+ "resume-planner",
34
+ "stage-capsule-qualification-reconciliation",
35
+ ];
36
+ const TOKEN = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/u;
37
+ const REVISION = /^[0-9a-f]{40}$/u;
38
+
39
+ function fault(code, location, message) {
40
+ throw new V4ContractFault(code, location, message);
41
+ }
42
+
43
+ function object(value, location) {
44
+ if (!value || typeof value !== "object" || Array.isArray(value))
45
+ fault(
46
+ "invalid-stage-capsule-qualification-shape",
47
+ location,
48
+ "object required",
49
+ );
50
+ return value;
51
+ }
52
+
53
+ function exactKeys(value, expected, location) {
54
+ object(value, location);
55
+ const actual = Object.keys(value).sort();
56
+ const canonical = [...expected].sort();
57
+ if (
58
+ actual.length !== canonical.length ||
59
+ actual.some((key, index) => key !== canonical[index])
60
+ )
61
+ fault(
62
+ "invalid-stage-capsule-qualification-shape",
63
+ location,
64
+ "keys do not match the closed qualification contract",
65
+ );
66
+ }
67
+
68
+ function token(value, location) {
69
+ if (typeof value !== "string" || !TOKEN.test(value))
70
+ fault(
71
+ "invalid-stage-capsule-qualification-token",
72
+ location,
73
+ "token required",
74
+ );
75
+ }
76
+
77
+ function integer(value, location) {
78
+ if (!Number.isSafeInteger(value) || value < 0)
79
+ fault(
80
+ "invalid-stage-capsule-qualification-metric",
81
+ location,
82
+ "non-negative integer required",
83
+ );
84
+ }
85
+
86
+ function string(value, location) {
87
+ if (typeof value !== "string" || value.length === 0)
88
+ fault(
89
+ "invalid-stage-capsule-qualification-value",
90
+ location,
91
+ "string required",
92
+ );
93
+ }
94
+
95
+ function roots(value, names, location) {
96
+ exactKeys(value, names, location);
97
+ for (const name of names) validateV4Root(value[name], `${location}/${name}`);
98
+ }
99
+
100
+ function validateFaults(entries, location) {
101
+ if (!Array.isArray(entries) || entries.length !== FAULTS.length)
102
+ fault(
103
+ "incomplete-stage-capsule-fault-campaign",
104
+ location,
105
+ "the complete fault campaign is required",
106
+ );
107
+ for (const [index, entry] of entries.entries()) {
108
+ exactKeys(
109
+ entry,
110
+ ["id", "expected", "actual", "reasonCode", "passed"],
111
+ `${location}/${index}`,
112
+ );
113
+ if (entry.id !== FAULTS[index] || entry.passed !== true)
114
+ fault(
115
+ "failed-stage-capsule-fault-campaign",
116
+ `${location}/${index}`,
117
+ "fault cases must be byte-sorted and pass",
118
+ );
119
+ for (const name of ["expected", "actual", "reasonCode"])
120
+ token(entry[name], `${location}/${index}/${name}`);
121
+ }
122
+ }
123
+
124
+ function validateAuthorityAndRuns(value) {
125
+ if (
126
+ value.schema !== V4_STAGE_CAPSULE_PLATFORM_QUALIFICATION_CONTRACT ||
127
+ value.mode !== "shadow-only" ||
128
+ value.productionAuthority !== "v3" ||
129
+ value.providerEffects !== false ||
130
+ value.productionWrites !== false
131
+ )
132
+ fault(
133
+ "invalid-stage-capsule-qualification-authority",
134
+ "$",
135
+ "qualification cannot move v3 authority or enable effects",
136
+ );
137
+ token(value.consumer, "$/consumer");
138
+ if (!PLATFORMS.includes(value.platform))
139
+ fault(
140
+ "invalid-stage-capsule-qualification-platform",
141
+ "$/platform",
142
+ "unknown platform",
143
+ );
144
+ string(value.runtimeRef, "$/runtimeRef");
145
+ if (!Array.isArray(value.processRuns) || value.processRuns.length !== 2)
146
+ fault(
147
+ "invalid-stage-capsule-qualification-runs",
148
+ "$/processRuns",
149
+ "seed and resume runs are required",
150
+ );
151
+ const expectedRuns = [
152
+ ["seed", "late-failure"],
153
+ ["resume", "qualified"],
154
+ ];
155
+ for (const [index, run] of value.processRuns.entries()) {
156
+ exactKeys(run, ["id", "outcome", "evidenceRoot"], `$/processRuns/${index}`);
157
+ if (
158
+ run.id !== expectedRuns[index][0] ||
159
+ run.outcome !== expectedRuns[index][1]
160
+ )
161
+ fault(
162
+ "invalid-stage-capsule-qualification-runs",
163
+ `$/processRuns/${index}`,
164
+ "run order or outcome differs",
165
+ );
166
+ validateV4Root(run.evidenceRoot, `$/processRuns/${index}/evidenceRoot`);
167
+ }
168
+ }
169
+
170
+ function validateBuildAndPlan(value) {
171
+ for (const [name, build] of [
172
+ ["freshBuild", value.freshBuild],
173
+ ["resumedBuild", value.resumedBuild],
174
+ ])
175
+ roots(build, ["artifactManifestRoot", "contentRoot"], `/${name}`);
176
+ if (
177
+ value.freshBuild.artifactManifestRoot !==
178
+ value.resumedBuild.artifactManifestRoot ||
179
+ value.freshBuild.contentRoot !== value.resumedBuild.contentRoot
180
+ )
181
+ fault(
182
+ "stage-capsule-qualification-output-mismatch",
183
+ "$/resumedBuild",
184
+ "fresh and resumed outputs differ",
185
+ );
186
+ exactKeys(
187
+ value.resumePlan,
188
+ ["planRoot", "requiredRestores", "requiredStages"],
189
+ "$/resumePlan",
190
+ );
191
+ validateV4Root(value.resumePlan.planRoot, "$/resumePlan/planRoot");
192
+ for (const name of ["requiredRestores", "requiredStages"])
193
+ if (
194
+ !Array.isArray(value.resumePlan[name]) ||
195
+ value.resumePlan[name].length === 0
196
+ )
197
+ fault(
198
+ "invalid-stage-capsule-qualification-plan",
199
+ `$/resumePlan/${name}`,
200
+ "both retained and rebuilt stages are required",
201
+ );
202
+ }
203
+
204
+ function validateMetricsAndRollback(value) {
205
+ const metricNames = [
206
+ "fullStageCount",
207
+ "rebuiltStageCount",
208
+ "retainedStageCount",
209
+ "restoredStageCount",
210
+ "retainedBytes",
211
+ "restoreOverheadMs",
212
+ "falseReuseCount",
213
+ "falseRebuildCount",
214
+ ];
215
+ exactKeys(value.metrics, [...metricNames, "plannerAccurate"], "$/metrics");
216
+ for (const name of metricNames)
217
+ integer(value.metrics[name], `$/metrics/${name}`);
218
+ if (
219
+ value.metrics.fullStageCount !==
220
+ value.metrics.rebuiltStageCount + value.metrics.retainedStageCount ||
221
+ value.metrics.retainedStageCount < value.metrics.restoredStageCount ||
222
+ value.metrics.restoredStageCount === 0 ||
223
+ value.metrics.falseReuseCount !== 0 ||
224
+ value.metrics.falseRebuildCount !== 0 ||
225
+ value.metrics.plannerAccurate !== true
226
+ )
227
+ fault(
228
+ "failed-stage-capsule-qualification-metrics",
229
+ "$/metrics",
230
+ "planner measurements do not qualify",
231
+ );
232
+ exactKeys(
233
+ value.rollback,
234
+ [
235
+ "switch",
236
+ "productionAuthority",
237
+ "migrationRequired",
238
+ "retainedStateDestroyed",
239
+ ],
240
+ "$/rollback",
241
+ );
242
+ if (
243
+ value.rollback.switch !== "stage-capsule-mode=v3" ||
244
+ value.rollback.productionAuthority !== "v3" ||
245
+ value.rollback.migrationRequired !== false ||
246
+ value.rollback.retainedStateDestroyed !== false
247
+ )
248
+ fault(
249
+ "invalid-stage-capsule-qualification-rollback",
250
+ "$/rollback",
251
+ "rollback must remain one non-destructive v3 switch",
252
+ );
253
+ }
254
+
255
+ export function validateV4StageCapsulePlatformQualification(value) {
256
+ exactKeys(
257
+ value,
258
+ [
259
+ "schema",
260
+ "mode",
261
+ "productionAuthority",
262
+ "consumer",
263
+ "platform",
264
+ "runtimeRef",
265
+ "campaignProfileRoot",
266
+ "processRuns",
267
+ "freshBuild",
268
+ "resumedBuild",
269
+ "resumePlan",
270
+ "faultCampaign",
271
+ "metrics",
272
+ "rollback",
273
+ "providerEffects",
274
+ "productionWrites",
275
+ "reportRoot",
276
+ ],
277
+ "$",
278
+ );
279
+ validateAuthorityAndRuns(value);
280
+ validateV4Root(value.campaignProfileRoot, "$/campaignProfileRoot");
281
+ validateBuildAndPlan(value);
282
+ validateFaults(value.faultCampaign, "$/faultCampaign");
283
+ validateMetricsAndRollback(value);
284
+ const payload = structuredClone(value);
285
+ delete payload.reportRoot;
286
+ const expectedRoot = v4ContentRoot(
287
+ "stage-capsule-platform-qualification",
288
+ payload,
289
+ );
290
+ if (value.reportRoot !== expectedRoot)
291
+ fault(
292
+ "stage-capsule-qualification-root-mismatch",
293
+ "$/reportRoot",
294
+ "reportRoot does not bind the platform qualification",
295
+ );
296
+ return value;
297
+ }
298
+
299
+ export function qualifyV4StageCapsuleCampaign(
300
+ platformEvidence,
301
+ expectedConsumers = CONSUMERS,
302
+ ) {
303
+ if (
304
+ !Array.isArray(expectedConsumers) ||
305
+ expectedConsumers.length === 0 ||
306
+ new Set(expectedConsumers).size !== expectedConsumers.length
307
+ )
308
+ fault(
309
+ "invalid-stage-capsule-qualification-consumers",
310
+ "$/expectedConsumers",
311
+ "one or more unique consumers are required",
312
+ );
313
+ const requiredConsumers = [...expectedConsumers].sort();
314
+ for (const consumer of requiredConsumers)
315
+ token(consumer, "$/expectedConsumers");
316
+ if (
317
+ !Array.isArray(platformEvidence) ||
318
+ platformEvidence.length !== PLATFORMS.length * requiredConsumers.length
319
+ )
320
+ fault(
321
+ "incomplete-stage-capsule-platform-campaign",
322
+ "$/platformEvidence",
323
+ "every expected consumer must qualify on all three platforms",
324
+ );
325
+ const evidence = platformEvidence.map((entry) =>
326
+ structuredClone(validateV4StageCapsulePlatformQualification(entry)),
327
+ );
328
+ const expectedPairs = requiredConsumers.flatMap((consumer) =>
329
+ PLATFORMS.map((platform) => `${consumer}/${platform}`),
330
+ );
331
+ if (
332
+ evidence.some(
333
+ (entry, index) =>
334
+ `${entry.consumer}/${entry.platform}` !== expectedPairs[index],
335
+ )
336
+ )
337
+ fault(
338
+ "incomplete-stage-capsule-platform-campaign",
339
+ "$/platformEvidence",
340
+ "platform reports must be unique and byte-sorted",
341
+ );
342
+ const consumers = [
343
+ ...new Set(evidence.map(({ consumer }) => consumer)),
344
+ ].sort();
345
+ if (JSON.stringify(consumers) !== JSON.stringify(requiredConsumers))
346
+ fault(
347
+ "incomplete-stage-capsule-consumer-campaign",
348
+ "$/platformEvidence",
349
+ "the exact expected consumer set is required",
350
+ );
351
+ const body = {
352
+ schema: V4_STAGE_CAPSULE_QUALIFICATION_CONTRACT,
353
+ mode: "shadow-only",
354
+ productionAuthority: "v3",
355
+ platforms: evidence.map(({ platform, reportRoot }) => ({
356
+ platform,
357
+ reportRoot,
358
+ })),
359
+ consumers,
360
+ qualified: true,
361
+ falseReuseCount: evidence.reduce(
362
+ (total, entry) => total + entry.metrics.falseReuseCount,
363
+ 0,
364
+ ),
365
+ falseRebuildCount: evidence.reduce(
366
+ (total, entry) => total + entry.metrics.falseRebuildCount,
367
+ 0,
368
+ ),
369
+ productionWrites: false,
370
+ };
371
+ return {
372
+ ...body,
373
+ qualificationRoot: v4ContentRoot("stage-capsule-qualification", body),
374
+ };
375
+ }
376
+
377
+ export function reconcileV4StageCapsuleWave(request) {
378
+ exactKeys(
379
+ request,
380
+ ["schema", "qualificationRoot", "protectedDeliveryDrained", "children"],
381
+ "$",
382
+ );
383
+ if (request.schema !== V4_STAGE_CAPSULE_WAVE_RECONCILIATION_CONTRACT)
384
+ fault(
385
+ "unsupported-stage-capsule-wave-reconciliation",
386
+ "$/schema",
387
+ "unsupported reconciliation contract",
388
+ );
389
+ validateV4Root(request.qualificationRoot, "$/qualificationRoot");
390
+ if (request.protectedDeliveryDrained !== true)
391
+ fault(
392
+ "stage-capsule-protected-delivery-not-drained",
393
+ "$/protectedDeliveryDrained",
394
+ "protected delivery must be empty",
395
+ );
396
+ if (
397
+ !Array.isArray(request.children) ||
398
+ request.children.length !== CHILDREN.length
399
+ )
400
+ fault(
401
+ "incomplete-stage-capsule-wave",
402
+ "$/children",
403
+ "all five Wave 2 children are required",
404
+ );
405
+ for (const [index, child] of request.children.entries()) {
406
+ exactKeys(
407
+ child,
408
+ [
409
+ "id",
410
+ "nativeStatus",
411
+ "nativeGateRoot",
412
+ "sourceRevision",
413
+ "protectedMergeRevision",
414
+ "reviewRoot",
415
+ "warrantRoot",
416
+ ],
417
+ `$/children/${index}`,
418
+ );
419
+ if (
420
+ child.id !== CHILDREN[index] ||
421
+ child.nativeStatus !== "terminal" ||
422
+ !REVISION.test(child.sourceRevision) ||
423
+ !REVISION.test(child.protectedMergeRevision)
424
+ )
425
+ fault(
426
+ "incomplete-stage-capsule-wave",
427
+ `$/children/${index}`,
428
+ "child identity or terminal delivery is incomplete",
429
+ );
430
+ for (const name of ["nativeGateRoot", "reviewRoot", "warrantRoot"])
431
+ validateV4Root(child[name], `$/children/${index}/${name}`);
432
+ }
433
+ const body = {
434
+ schema: V4_STAGE_CAPSULE_WAVE_RECONCILIATION_CONTRACT,
435
+ wave: 2,
436
+ qualificationRoot: request.qualificationRoot,
437
+ protectedDeliveryDrained: true,
438
+ children: structuredClone(request.children),
439
+ productionAuthority: "v3",
440
+ productionReuseEnabled: false,
441
+ residualResponsibilitiesOnly: true,
442
+ terminal: true,
443
+ };
444
+ return {
445
+ ...body,
446
+ reconciliationRoot: v4ContentRoot(
447
+ "stage-capsule-wave-reconciliation",
448
+ body,
449
+ ),
450
+ };
451
+ }
452
+
453
+ export const V4_STAGE_CAPSULE_QUALIFICATION_PLATFORMS =
454
+ Object.freeze(PLATFORMS);
455
+ export const V4_STAGE_CAPSULE_QUALIFICATION_FAULTS = Object.freeze(FAULTS);
456
+ export const V4_STAGE_CAPSULE_WAVE_CHILDREN = Object.freeze(CHILDREN);