@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
@@ -1,532 +0,0 @@
1
- #!/usr/bin/env node
2
- // SPDX-License-Identifier: Apache-2.0
3
-
4
- import fs from "node:fs";
5
- import path from "node:path";
6
- import { pathToFileURL } from "node:url";
7
-
8
- import {
9
- runNextDevelopmentController,
10
- validateNextDevelopmentController,
11
- } from "../packages/core/next-development-controller.js";
12
- import {
13
- NEXT_DEVELOPMENT_TRANSITION_CONTRACT,
14
- nextDevelopmentRoot,
15
- } from "../packages/core/next-development-transition.js";
16
- import {
17
- DurableStore,
18
- HOSTED_READBACK_PATHS,
19
- PROTECTED_DEV_BRANCH,
20
- RECORDED_AT,
21
- VersionStateAdapterHarness,
22
- adapterTransition,
23
- anchorInput,
24
- exactRoot,
25
- exactSha,
26
- fixtureSha,
27
- repository,
28
- required,
29
- validateAdapterEvidence,
30
- validateAdapterOperation,
31
- validateRecoveryEvidence,
32
- validateSelfDogfoodRoute,
33
- } from "./next-development-self-dogfood-harness.mjs";
34
-
35
- export const NEXT_DEVELOPMENT_SELF_DOGFOOD_CHECKPOINT =
36
- "kungfu-buildchain-next-development-self-dogfood-checkpoint/v1";
37
- export const NEXT_DEVELOPMENT_SELF_DOGFOOD_EVIDENCE =
38
- "kungfu-buildchain-next-development-self-dogfood/v1";
39
- export const HOSTED_SELF_DOGFOOD_EVIDENCE =
40
- "kungfu-buildchain-alpha-self-dogfood";
41
-
42
- function checkpointBody(checkpoint) {
43
- const body = structuredClone(checkpoint);
44
- delete body.checkpointRoot;
45
- return body;
46
- }
47
-
48
- function evidenceBody(evidence) {
49
- const body = structuredClone(evidence);
50
- delete body.evidenceRoot;
51
- return body;
52
- }
53
-
54
- export function validateSelfDogfoodCheckpoint(checkpoint) {
55
- if (checkpoint?.contract !== NEXT_DEVELOPMENT_SELF_DOGFOOD_CHECKPOINT) {
56
- throw new Error("next-development self-dogfood checkpoint contract mismatch");
57
- }
58
- const runtimeSha = exactSha(checkpoint.route?.runtimeSha, "route.runtimeSha");
59
- exactRoot(checkpoint.route?.contractRoot, "route.contractRoot");
60
- const targetRepository = repository(checkpoint.route?.repository, "route.repository");
61
- if (
62
- checkpoint.route.runtimeRef !== "v3-alpha" ||
63
- checkpoint.route.publicWorkflow !==
64
- `${targetRepository}/.github/workflows/build.yml@v3-alpha` ||
65
- targetRepository !== "kungfu-systems/buildchain"
66
- ) {
67
- throw new Error("checkpoint requires the public owner/repo v3-alpha route");
68
- }
69
- if (runtimeSha !== checkpoint.route.runtimeSha) {
70
- throw new Error("checkpoint runtime SHA is not canonical");
71
- }
72
- required(checkpoint.faultRunnerId, "faultRunnerId");
73
- const semver = validateNextDevelopmentController(checkpoint.semver.controller);
74
- const anchored = validateNextDevelopmentController(checkpoint.anchored.controller);
75
- if (
76
- semver.transition.state.status !== "planned" ||
77
- semver.activeAttempt !== null ||
78
- checkpoint.semver.materializations !== 1 ||
79
- checkpoint.semver.adapterOperations?.length !== 1 ||
80
- checkpoint.semver.durableStateFailures !== 1
81
- ) {
82
- throw new Error("semver checkpoint must prove one transient durable-state failure");
83
- }
84
- checkpoint.semver.adapterOperations.forEach(validateAdapterOperation);
85
- if (
86
- anchored.transition.state.status !== "waiting-anchor" ||
87
- anchored.transition.target.version !== null ||
88
- checkpoint.anchored.materializations !== 0
89
- ) {
90
- throw new Error("anchored checkpoint must persist manual waiting");
91
- }
92
- if (checkpoint.alphaCandidateRebuilds !== 0) {
93
- throw new Error("post-Alpha proof must not rebuild the Alpha candidate");
94
- }
95
- if (checkpoint.checkpointRoot !== nextDevelopmentRoot(checkpointBody(checkpoint))) {
96
- throw new Error("next-development self-dogfood checkpoint root drifted");
97
- }
98
- return structuredClone(checkpoint);
99
- }
100
-
101
- export async function createSelfDogfoodCheckpoint({
102
- repository: targetRepository,
103
- runtimeRef,
104
- runtimeSha,
105
- contractRoot,
106
- runnerId,
107
- } = {}) {
108
- const routeRepository = repository(targetRepository);
109
- const route = {
110
- repository: routeRepository,
111
- publicWorkflow: `${routeRepository}/.github/workflows/build.yml@v3-alpha`,
112
- runtimeRef: required(runtimeRef, "runtimeRef"),
113
- runtimeSha: exactSha(runtimeSha, "runtimeSha"),
114
- contractRoot: exactRoot(contractRoot, "contractRoot"),
115
- protectedDevBranch: PROTECTED_DEV_BRANCH,
116
- hostedReadbackPaths: HOSTED_READBACK_PATHS,
117
- };
118
- if (
119
- route.repository !== "kungfu-systems/buildchain" ||
120
- route.runtimeRef !== "v3-alpha"
121
- ) {
122
- throw new Error("self-dogfood checkpoint requires the public kungfu-systems/buildchain v3-alpha route");
123
- }
124
-
125
- const semverStore = new DurableStore([], { transientFailures: 1 });
126
- const semverExecutor = new VersionStateAdapterHarness({ route });
127
- await runNextDevelopmentController(
128
- {
129
- transition: adapterTransition(route, "semver"),
130
- protectedDevBranch: PROTECTED_DEV_BRANCH,
131
- recordedAt: RECORDED_AT,
132
- },
133
- { store: semverStore, executor: semverExecutor },
134
- ).then(
135
- () => {
136
- throw new Error("transient durable-state fault injection did not run");
137
- },
138
- (error) => {
139
- if (!/injected transient durable-state write failure/u.test(error.message)) {
140
- throw error;
141
- }
142
- },
143
- );
144
-
145
- const anchoredStore = new DurableStore();
146
- const anchoredExecutor = new VersionStateAdapterHarness({ route });
147
- await runNextDevelopmentController(
148
- {
149
- transition: adapterTransition(route, "anchored"),
150
- protectedDevBranch: PROTECTED_DEV_BRANCH,
151
- recordedAt: RECORDED_AT,
152
- },
153
- { store: anchoredStore, executor: anchoredExecutor },
154
- );
155
-
156
- const checkpoint = {
157
- schemaVersion: 1,
158
- contract: NEXT_DEVELOPMENT_SELF_DOGFOOD_CHECKPOINT,
159
- route,
160
- faultRunnerId: required(runnerId, "runnerId"),
161
- alphaCandidateRebuilds: 0,
162
- semver: {
163
- controller: semverStore.only(),
164
- materializations: semverExecutor.materializations,
165
- adapterOperations: semverExecutor.operationRecords(),
166
- durableStateFailures: semverStore.transientFailures,
167
- },
168
- anchored: {
169
- controller: anchoredStore.only(),
170
- materializations: anchoredExecutor.materializations,
171
- },
172
- };
173
- checkpoint.checkpointRoot = nextDevelopmentRoot(checkpoint);
174
- return validateSelfDogfoodCheckpoint(checkpoint);
175
- }
176
-
177
- function assertVerifiedModel(model, label) {
178
- const controller = validateNextDevelopmentController(model?.controller);
179
- if (
180
- model.status !== "verified" ||
181
- controller.transition.state.status !== "verified" ||
182
- model.controllerRoot !== controller.controllerRoot ||
183
- model.readbackRoot !== nextDevelopmentRoot(controller.readback)
184
- ) {
185
- throw new Error(`${label} does not bind its verified controller and readback`);
186
- }
187
- return controller;
188
- }
189
-
190
- export function validateSelfDogfoodEvidence(evidence) {
191
- if (evidence?.contract !== NEXT_DEVELOPMENT_SELF_DOGFOOD_EVIDENCE) {
192
- throw new Error("next-development self-dogfood evidence contract mismatch");
193
- }
194
- exactRoot(evidence.checkpointRoot, "checkpointRoot");
195
- exactRoot(evidence.transactionRoot, "transactionRoot");
196
- exactRoot(evidence.protectedDevReadbackRoot, "protectedDevReadbackRoot");
197
- validateSelfDogfoodRoute(evidence.route);
198
- const semver = assertVerifiedModel(evidence.models?.semverAuto, "semver/auto");
199
- const anchored = assertVerifiedModel(evidence.models?.anchoredManual, "anchored/manual");
200
- if (evidence.status !== "passed") throw new Error("self-dogfood evidence did not pass");
201
- validateRecoveryEvidence(evidence.recovery);
202
- if (
203
- semver.controllerRoot !== evidence.transactionRoot ||
204
- nextDevelopmentRoot(semver.readback) !== evidence.protectedDevReadbackRoot ||
205
- evidence.models.anchoredManual.waitingStatus !== "waiting-anchor" ||
206
- evidence.models.anchoredManual.waitingControllerRoot === anchored.controllerRoot
207
- ) {
208
- throw new Error("both legal next-development models must be proved");
209
- }
210
- validateAdapterEvidence(evidence.adapter, semver, anchored);
211
- if (
212
- evidence.adoption?.coordinate !==
213
- "kungfu-systems/buildchain/.github/workflows/build.yml@v3" ||
214
- evidence.adoption?.exactShaProductionPin !== false
215
- ) {
216
- throw new Error("Kungfu adoption must use the floating v3 coordinate");
217
- }
218
- if (evidence.evidenceRoot !== nextDevelopmentRoot(evidenceBody(evidence))) {
219
- throw new Error("next-development self-dogfood evidence root drifted");
220
- }
221
- return structuredClone(evidence);
222
- }
223
-
224
- export async function resumeSelfDogfoodCheckpoint(checkpointInput, { runnerId } = {}) {
225
- const checkpoint = validateSelfDogfoodCheckpoint(checkpointInput);
226
- const resumeRunnerId = required(runnerId, "runnerId");
227
- if (resumeRunnerId === checkpoint.faultRunnerId) {
228
- throw new Error("post-Alpha recovery must run on a fresh runner identity");
229
- }
230
-
231
- const initialDevSha = fixtureSha("protected-dev:initial");
232
- const movedDevSha = fixtureSha("protected-dev:moved-during-recovery");
233
- const semverStore = new DurableStore([checkpoint.semver.controller]);
234
- const semverExecutor = new VersionStateAdapterHarness({
235
- route: checkpoint.route,
236
- operations: checkpoint.semver.adapterOperations,
237
- devSha: initialDevSha,
238
- movedDevSha,
239
- moveAfterRecoveredOperation: true,
240
- pullRequestReadsBeforeMerge: 2,
241
- });
242
- const input = {
243
- transition: adapterTransition(checkpoint.route, "semver"),
244
- protectedDevBranch: PROTECTED_DEV_BRANCH,
245
- recordedAt: RECORDED_AT,
246
- };
247
- const superseded = await runNextDevelopmentController(input, {
248
- store: semverStore,
249
- executor: semverExecutor,
250
- });
251
- const pending = await runNextDevelopmentController(input, {
252
- store: semverStore,
253
- executor: semverExecutor,
254
- });
255
- const delayed = await runNextDevelopmentController(input, {
256
- store: semverStore,
257
- executor: semverExecutor,
258
- });
259
- const semver = await runNextDevelopmentController(input, {
260
- store: semverStore,
261
- executor: semverExecutor,
262
- });
263
-
264
- const anchoredStore = new DurableStore([checkpoint.anchored.controller]);
265
- const anchoredExecutor = new VersionStateAdapterHarness({ route: checkpoint.route });
266
- const anchored = await runNextDevelopmentController(
267
- {
268
- transition: adapterTransition(checkpoint.route, "anchored"),
269
- protectedDevBranch: PROTECTED_DEV_BRANCH,
270
- reviewedInput: anchorInput(),
271
- recordedAt: RECORDED_AT,
272
- },
273
- { store: anchoredStore, executor: anchoredExecutor },
274
- );
275
-
276
- const semverReadbackRoot = nextDevelopmentRoot(semver.readback);
277
- const anchoredReadbackRoot = nextDevelopmentRoot(anchored.readback);
278
- const evidence = {
279
- schemaVersion: 1,
280
- contract: NEXT_DEVELOPMENT_SELF_DOGFOOD_EVIDENCE,
281
- status: "passed",
282
- route: checkpoint.route,
283
- checkpointRoot: checkpoint.checkpointRoot,
284
- transactionRoot: semver.controllerRoot,
285
- protectedDevReadbackRoot: semverReadbackRoot,
286
- recovery: {
287
- faultRunnerId: checkpoint.faultRunnerId,
288
- resumeRunnerId,
289
- freshRunner: true,
290
- transientDurableStateFailures: checkpoint.semver.durableStateFailures,
291
- recoveredAdapterOperations: semverExecutor.recoveredOperations,
292
- alphaCandidateRebuilds: 0,
293
- devMaterializationsBefore: checkpoint.semver.materializations,
294
- devMaterializationsAfter: semverExecutor.materializations,
295
- protectedDevMovement: {
296
- initialSha: initialDevSha,
297
- movedSha: movedDevSha,
298
- supersededAttempts: superseded.attempts.filter(
299
- (attempt) => attempt.status === "superseded",
300
- ).length,
301
- },
302
- protectedPrDelay: {
303
- status: pending.transition.state.status,
304
- delayedStatus: delayed.transition.state.status,
305
- unchangedControllerRoot: pending.controllerRoot === delayed.controllerRoot,
306
- },
307
- },
308
- adapter: {
309
- boundary: "materializeNextDevelopmentTransition",
310
- contract: NEXT_DEVELOPMENT_TRANSITION_CONTRACT,
311
- operations: [
312
- ...semverExecutor.operationRecords(),
313
- ...anchoredExecutor.operationRecords(),
314
- ],
315
- },
316
- models: {
317
- semverAuto: {
318
- status: semver.transition.state.status,
319
- targetVersion: semver.transition.target.version,
320
- controllerRoot: semver.controllerRoot,
321
- readbackRoot: semverReadbackRoot,
322
- controller: semver,
323
- },
324
- anchoredManual: {
325
- waitingStatus: checkpoint.anchored.controller.transition.state.status,
326
- waitingControllerRoot: checkpoint.anchored.controller.controllerRoot,
327
- status: anchored.transition.state.status,
328
- targetVersion: anchored.transition.target.version,
329
- controllerRoot: anchored.controllerRoot,
330
- readbackRoot: anchoredReadbackRoot,
331
- controller: anchored,
332
- },
333
- },
334
- adoption: {
335
- coordinate: "kungfu-systems/buildchain/.github/workflows/build.yml@v3",
336
- runtimeRef: "v3",
337
- exactShaProductionPin: false,
338
- },
339
- };
340
- evidence.evidenceRoot = nextDevelopmentRoot(evidence);
341
- return validateSelfDogfoodEvidence(evidence);
342
- }
343
-
344
- function normalizeHostedReadback(value, route) {
345
- const paths = (value?.versionRoots || [])
346
- .map((entry, index) => ({
347
- path: required(entry?.path, `hosted versionRoots[${index}].path`),
348
- gitBlobSha: exactSha(
349
- entry?.gitBlobSha,
350
- `hosted versionRoots[${index}].gitBlobSha`,
351
- ),
352
- }))
353
- .sort((left, right) => left.path.localeCompare(right.path));
354
- if (JSON.stringify(paths.map((entry) => entry.path)) !== JSON.stringify(route.hostedReadbackPaths)) {
355
- throw new Error("hosted protected Dev readback must exactly cover declared paths");
356
- }
357
- const body = {
358
- repository: repository(value?.repository, "hosted readback repository"),
359
- branch: required(value?.branch, "hosted readback branch"),
360
- commitSha: exactSha(value?.commitSha, "hosted readback commitSha"),
361
- treeSha: exactSha(value?.treeSha, "hosted readback treeSha"),
362
- versionRoots: paths,
363
- };
364
- if (body.repository !== route.repository || body.branch !== route.protectedDevBranch) {
365
- throw new Error("hosted protected Dev readback route drifted");
366
- }
367
- return { ...body, evidenceRoot: nextDevelopmentRoot(body) };
368
- }
369
-
370
- export function createHostedSelfDogfoodEvidence({ nextDevelopment, observation } = {}) {
371
- const proof = validateSelfDogfoodEvidence(nextDevelopment);
372
- const hostedProtectedDevReadback = normalizeHostedReadback(
373
- observation?.protectedDevReadback,
374
- proof.route,
375
- );
376
- const observed = structuredClone(observation?.observed || {});
377
- const failures = [];
378
- if (observed.alpha?.ref !== "v3-alpha") failures.push("alpha runtime ref mismatch");
379
- if (observed.alpha?.class !== "alpha") failures.push("alpha runtime class mismatch");
380
- if (observed.alpha?.sha !== observed.alpha?.expectedSha) failures.push("alpha runtime SHA mismatch");
381
- if (observed.alpha?.sha !== proof.route.runtimeSha) failures.push("next-development runtime SHA mismatch");
382
- if (observed.stable?.ref !== "v3") failures.push("stable runtime ref mismatch");
383
- if (observed.stable?.class !== "stable") failures.push("stable runtime class mismatch");
384
- if (observed.stable?.sha !== observed.stable?.expectedSha) failures.push("stable runtime SHA mismatch");
385
- for (const [lane, item] of Object.entries(observed)) {
386
- exactSha(item?.sha, `observed ${lane} SHA`);
387
- exactSha(item?.expectedSha, `expected ${lane} SHA`);
388
- }
389
- const evidence = {
390
- schemaVersion: 1,
391
- contract: HOSTED_SELF_DOGFOOD_EVIDENCE,
392
- repository: repository(observation?.repository),
393
- callerSha: exactSha(observation?.callerSha, "callerSha"),
394
- checkedAt: required(observation?.checkedAt, "checkedAt"),
395
- status: failures.length === 0 ? "passed" : "failed",
396
- observed,
397
- nextDevelopment: proof,
398
- hostedProtectedDevReadback,
399
- failures,
400
- };
401
- if (evidence.repository !== proof.route.repository) {
402
- throw new Error("hosted evidence repository differs from the public route");
403
- }
404
- evidence.evidenceRoot = nextDevelopmentRoot(evidence);
405
- return evidence;
406
- }
407
-
408
- export function validateHostedSelfDogfoodEvidence(evidence) {
409
- if (evidence?.contract !== HOSTED_SELF_DOGFOOD_EVIDENCE) {
410
- throw new Error("hosted self-dogfood evidence contract mismatch");
411
- }
412
- const proof = validateSelfDogfoodEvidence(evidence.nextDevelopment);
413
- repository(evidence.repository);
414
- exactSha(evidence.callerSha, "callerSha");
415
- required(evidence.checkedAt, "checkedAt");
416
- for (const [lane, item] of Object.entries(evidence.observed || {})) {
417
- exactSha(item?.sha, `observed ${lane} SHA`);
418
- exactSha(item?.expectedSha, `expected ${lane} SHA`);
419
- }
420
- const readback = normalizeHostedReadback(
421
- evidence.hostedProtectedDevReadback,
422
- proof.route,
423
- );
424
- if (
425
- readback.evidenceRoot !== evidence.hostedProtectedDevReadback?.evidenceRoot ||
426
- evidence.evidenceRoot !== nextDevelopmentRoot(evidenceBody(evidence))
427
- ) {
428
- throw new Error("hosted self-dogfood evidence root drifted");
429
- }
430
- if (
431
- evidence.status !== "passed" ||
432
- evidence.failures?.length !== 0 ||
433
- evidence.repository !== proof.route.repository ||
434
- evidence.observed?.alpha?.ref !== "v3-alpha" ||
435
- evidence.observed?.alpha?.class !== "alpha" ||
436
- evidence.observed?.alpha?.sha !== evidence.observed?.alpha?.expectedSha ||
437
- evidence.observed?.alpha?.sha !== proof.route.runtimeSha ||
438
- evidence.observed?.stable?.ref !== "v3" ||
439
- evidence.observed?.stable?.class !== "stable" ||
440
- evidence.observed?.stable?.sha !== evidence.observed?.stable?.expectedSha
441
- ) {
442
- throw new Error("hosted self-dogfood evidence is not a passing exact readback");
443
- }
444
- return structuredClone(evidence);
445
- }
446
-
447
- function parseArgs(argv) {
448
- const options = {};
449
- for (let index = 0; index < argv.length; index += 1) {
450
- const name = argv[index];
451
- if (!name.startsWith("--") || index + 1 >= argv.length) {
452
- throw new Error(`invalid argument: ${name}`);
453
- }
454
- options[name.slice(2).replace(/-([a-z])/gu, (_, letter) => letter.toUpperCase())] = argv[index + 1];
455
- index += 1;
456
- }
457
- return options;
458
- }
459
-
460
- function readJson(filePath) {
461
- return JSON.parse(fs.readFileSync(path.resolve(filePath), "utf8"));
462
- }
463
-
464
- function writeJson(filePath, value) {
465
- const output = path.resolve(filePath);
466
- fs.mkdirSync(path.dirname(output), { recursive: true });
467
- fs.writeFileSync(output, `${JSON.stringify(value, null, 2)}\n`);
468
- }
469
-
470
- function writeActionsOutputs(value) {
471
- const output = process.env.GITHUB_OUTPUT;
472
- if (!output) return;
473
- fs.appendFileSync(
474
- output,
475
- [
476
- `transaction-root=${value.transactionRoot || value.nextDevelopment?.transactionRoot || ""}`,
477
- `protected-dev-readback-root=${value.protectedDevReadbackRoot || value.hostedProtectedDevReadback?.evidenceRoot || ""}`,
478
- `evidence-root=${value.evidenceRoot || value.checkpointRoot || ""}`,
479
- ].join("\n") + "\n",
480
- );
481
- }
482
-
483
- async function main(argv = process.argv.slice(2)) {
484
- const command = argv.shift();
485
- const options = parseArgs(argv);
486
- if (command === "checkpoint") {
487
- const checkpoint = await createSelfDogfoodCheckpoint({
488
- repository: options.repository,
489
- runtimeRef: options.runtimeRef,
490
- runtimeSha: options.runtimeSha,
491
- contractRoot: options.contractRoot,
492
- runnerId: options.runnerId,
493
- });
494
- writeJson(required(options.output, "output"), checkpoint);
495
- writeActionsOutputs(checkpoint);
496
- return checkpoint;
497
- }
498
- if (command === "resume") {
499
- const evidence = await resumeSelfDogfoodCheckpoint(
500
- readJson(required(options.input, "input")),
501
- { runnerId: options.runnerId },
502
- );
503
- writeJson(required(options.output, "output"), evidence);
504
- writeActionsOutputs(evidence);
505
- return evidence;
506
- }
507
- if (command === "attest-hosted") {
508
- const evidence = createHostedSelfDogfoodEvidence({
509
- nextDevelopment: readJson(required(options.input, "input")),
510
- observation: readJson(required(options.observation, "observation")),
511
- });
512
- writeJson(required(options.output, "output"), evidence);
513
- writeActionsOutputs(evidence);
514
- return evidence;
515
- }
516
- if (command === "verify") {
517
- return validateSelfDogfoodEvidence(readJson(required(options.input, "input")));
518
- }
519
- if (command === "verify-hosted") {
520
- return validateHostedSelfDogfoodEvidence(readJson(required(options.input, "input")));
521
- }
522
- throw new Error(
523
- "usage: next-development-self-dogfood.mjs checkpoint|resume|attest-hosted|verify|verify-hosted ...",
524
- );
525
- }
526
-
527
- if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
528
- main().catch((error) => {
529
- process.stderr.write(`next-development self-dogfood: ${error.message}\n`);
530
- process.exitCode = 1;
531
- });
532
- }
@@ -1,47 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import fs from "node:fs";
4
- import path from "node:path";
5
- import { pathToFileURL } from "node:url";
6
-
7
- import { materializeNextDevelopmentTransition } from "../packages/core/next-development-transition.js";
8
-
9
- function flag(args, name, fallback = "") {
10
- const index = args.indexOf(`--${name}`);
11
- return index === -1 ? fallback : String(args[index + 1] || "");
12
- }
13
-
14
- function usage() {
15
- return `usage: node scripts/next-development-transition.mjs materialize --input <request.json> [--cwd <checkout>] [--write]\n`;
16
- }
17
-
18
- export function runNextDevelopmentAdapter(args = process.argv.slice(2)) {
19
- const [command] = args;
20
- if (command !== "materialize") throw new Error(usage().trim());
21
- const inputPath = flag(args, "input");
22
- if (!inputPath)
23
- throw new Error(
24
- "next-development materialize requires --input <request.json>",
25
- );
26
- const cwd = path.resolve(flag(args, "cwd", process.cwd()));
27
- const request = JSON.parse(fs.readFileSync(path.resolve(inputPath), "utf8"));
28
- return materializeNextDevelopmentTransition({
29
- cwd,
30
- request,
31
- write: args.includes("--write"),
32
- });
33
- }
34
-
35
- if (
36
- process.argv[1] &&
37
- import.meta.url === pathToFileURL(process.argv[1]).href
38
- ) {
39
- try {
40
- process.stdout.write(
41
- `${JSON.stringify(runNextDevelopmentAdapter(), null, 2)}\n`,
42
- );
43
- } catch (error) {
44
- process.stderr.write(`next-development transition: ${error.message}\n`);
45
- process.exitCode = 1;
46
- }
47
- }