@kungfu-tech/buildchain 3.0.9-alpha.9 → 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 (262) 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 -10
  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 -4
  65. package/dist/site/artifact-schemas.json +0 -8
  66. package/dist/site/buildchain-contract.json +103 -397
  67. package/dist/site/buildchain-site.json +302 -386
  68. package/dist/site/capability-registry.json +9 -11
  69. package/dist/site/cli-registry.json +8 -53
  70. package/dist/site/controller-registry.json +48 -8
  71. package/dist/site/kfd-claims.json +129 -167
  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 +4345 -7345
  75. package/dist/site/page-registry.json +278 -346
  76. package/dist/site/public-surface-audit.json +85 -404
  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 -9
  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 +78 -35
  83. package/docs/MAP.md +8 -5
  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 -213
  87. package/docs/cli.md +14 -14
  88. package/docs/dev-alpha-candidate-patrol.md +3 -11
  89. package/docs/dev-delivery-warrant.md +29 -194
  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 -554
  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 -5
  111. package/package.json +19 -19
  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-channel-identity.js +3 -2
  119. package/packages/core/buildchain-config.js +4 -69
  120. package/packages/core/buildchain-contract.js +232 -46
  121. package/packages/core/buildchain-kfd-claims.js +1 -1
  122. package/packages/core/channel-candidate.js +0 -8
  123. package/packages/core/channel-promotion-baseline.js +0 -52
  124. package/packages/core/controller-evidence.js +3 -4
  125. package/packages/core/dev-alpha-candidate-selection.js +2 -10
  126. package/packages/core/dev-delivery-warrant-cancellation.js +0 -1
  127. package/packages/core/dev-delivery-warrant-settlement.js +20 -67
  128. package/packages/core/dev-delivery-warrant.js +50 -138
  129. package/packages/core/diagnostics.js +3 -8
  130. package/packages/core/github-governance-authority.js +3 -1
  131. package/packages/core/kfd-adopter-category-driver.js +167 -0
  132. package/packages/core/kfd-adopter-manifest.js +47 -46
  133. package/packages/core/kfd-gate.js +15 -45
  134. package/packages/core/paper-agent-entry.js +7 -16
  135. package/packages/core/paper-fleet.js +2 -2
  136. package/packages/core/paper-repository.js +2 -3
  137. package/packages/core/paper-scaffold-content.js +2 -23
  138. package/packages/core/paper.js +11 -43
  139. package/packages/core/publication-reproducibility.js +4 -4
  140. package/packages/core/release-line-bootstrap.js +21 -8
  141. package/packages/core/release-passport-contract.js +5 -5
  142. package/packages/core/release-passport.js +20 -131
  143. package/packages/core/self-dogfood-version.js +48 -35
  144. package/packages/core/spawn-command.js +232 -8
  145. package/packages/core/v4-adopter-delivery-parity.js +219 -0
  146. package/packages/core/v4-canonical-contracts.js +284 -0
  147. package/packages/core/v4-delivery-warrant-fixture-runner.js +371 -0
  148. package/packages/core/v4-delivery-warrant-read-candidate.js +279 -0
  149. package/packages/core/v4-delivery-warrant-semantic-diff-gate.js +352 -0
  150. package/packages/core/v4-delivery-warrant-shadow-adapter.js +447 -0
  151. package/packages/core/v4-partial-mutation-recovery-qualification.js +395 -0
  152. package/packages/core/v4-platform-stage-checkpoints.js +471 -0
  153. package/packages/core/v4-provider-operation-journal.js +531 -0
  154. package/packages/core/v4-provider-readback-idempotency.js +394 -0
  155. package/packages/core/v4-release-activation-shadow.js +519 -0
  156. package/packages/core/v4-stable-publication-fence.js +357 -0
  157. package/packages/core/v4-stage-capsule-local-store.js +426 -0
  158. package/packages/core/v4-stage-capsule-qualification-campaign.js +512 -0
  159. package/packages/core/v4-stage-capsule-qualification.js +456 -0
  160. package/packages/core/v4-stage-capsule-resume-planner.js +397 -0
  161. package/packages/core/v4-stage-capsule-store.js +401 -0
  162. package/packages/core/v4-stage-capsule.js +319 -0
  163. package/scripts/assemble-self-publication-admission.mjs +1 -1
  164. package/scripts/audit-publication-control-plane.mjs +5 -5
  165. package/scripts/auditable-demo-bundle-verification.mjs +3 -2
  166. package/scripts/auditable-demo-platform.mjs +2 -2
  167. package/scripts/auditable-demo-renditions.mjs +1 -1
  168. package/scripts/auditable-demo.mjs +2 -2
  169. package/scripts/aws-macos-jit-controller-core.mjs +13 -346
  170. package/scripts/aws-macos-jit-controller-runtime.mjs +2 -210
  171. package/scripts/aws-macos-jit-controller.mjs +37 -275
  172. package/scripts/aws-macos-jit-core.mjs +3 -41
  173. package/scripts/aws-macos-jit.mjs +0 -12
  174. package/scripts/aws-windows-jit-campaign.mjs +2 -2
  175. package/scripts/aws-windows-jit-controller-core.mjs +1 -1
  176. package/scripts/aws-windows-jit-controller.mjs +3 -3
  177. package/scripts/build-contract-core.mjs +3 -8
  178. package/scripts/build-standalone-binary.mjs +3 -14
  179. package/scripts/buildchain-channel-router.mjs +4 -0
  180. package/scripts/buildchain-cli-help.mjs +7 -16
  181. package/scripts/buildchain-contract-lock.mjs +0 -6
  182. package/scripts/check-action-bundles.mjs +3 -4
  183. package/scripts/check-internal-architecture.mjs +7 -6
  184. package/scripts/check-inventory.mjs +30 -25
  185. package/scripts/check-v4-public-dogfood-contract.mjs +270 -0
  186. package/scripts/create-release-bundle.mjs +8 -4
  187. package/scripts/dev-alpha-candidate-patrol.mjs +1 -22
  188. package/scripts/dev-delivery-proof.mjs +2 -64
  189. package/scripts/dev-delivery-warrant.mjs +61 -86
  190. package/scripts/dev-pr-auto-merge.mjs +4 -30
  191. package/scripts/dev-pr-delivery-warrant.mjs +0 -55
  192. package/scripts/dispatch-artifact-signing-authority.mjs +7 -4
  193. package/scripts/generate-buildchain-kfd-witnesses.mjs +94 -88
  194. package/scripts/generate-channel-build-workflow.mjs +54 -24
  195. package/scripts/generate-channel-promotion-workflow.mjs +15 -6
  196. package/scripts/generate-site-bundle.mjs +8 -27
  197. package/scripts/git-fetch-process-tree.mjs +34 -1
  198. package/scripts/init-repo.mjs +64 -159
  199. package/scripts/inspect-artifact-signing-requests.mjs +0 -6
  200. package/scripts/locked-source-checkout.mjs +3 -4
  201. package/scripts/maintainability-metrics.mjs +8 -2
  202. package/scripts/npm-publish-dry-run.mjs +2 -2
  203. package/scripts/npm-publish-transaction.mjs +2 -2
  204. package/scripts/publication-commit-evidence.mjs +23 -69
  205. package/scripts/release-candidate-resolver.mjs +11 -17
  206. package/scripts/release-tail.mjs +3 -49
  207. package/scripts/resume-from-candidate-run.mjs +9 -123
  208. package/scripts/run-lifecycle-core.mjs +12 -13
  209. package/scripts/seal-artifact-signing-requests.mjs +17 -21
  210. package/scripts/site-capability-metadata.mjs +3 -20
  211. package/scripts/stable-candidate-qualification.mjs +10 -10
  212. package/scripts/v4-architecture.mjs +12 -2
  213. package/scripts/v4-bridge-bootstrap.mjs +141 -0
  214. package/scripts/v4-bridge-evidence.mjs +141 -0
  215. package/scripts/v4-host-adapter.mjs +182 -0
  216. package/scripts/v4-platform-stage-checkpoint-rehearsal.mjs +207 -0
  217. package/scripts/v4-stage-capsule-qualification.mjs +528 -0
  218. package/scripts/v4-stage-capsule-resume-rehearsal.mjs +57 -0
  219. package/scripts/v4-warrant-shadow-plan.mjs +601 -0
  220. package/scripts/verify-golden-path.mjs +5 -5
  221. package/scripts/web-surface-cloudfront-rewrite.mjs +15 -15
  222. package/scripts/web-surface-core.mjs +2 -8
  223. package/scripts/workflow-call-contract.mjs +5 -184
  224. package/contracts/dev-delivery-authority-v2.schema.json +0 -253
  225. package/contracts/fixtures/kfd-adopter-release-v1/kfd-4-perspective.json +0 -16
  226. package/contracts/fixtures/kfd-adopter-release-v1/kfd-4-replay.json +0 -57
  227. package/contracts/fixtures/next-development-transition-v1/anchored-manual-waiting.json +0 -47
  228. package/contracts/fixtures/next-development-transition-v1/semver-auto-planned.json +0 -47
  229. package/contracts/fixtures/next-development-transition-v1/version-model-cases.json +0 -40
  230. package/contracts/next-development-request-v1.schema.json +0 -66
  231. package/contracts/next-development-transition-v1.schema.json +0 -292
  232. package/contracts/publication-rehearsal-capsule-v1.schema.json +0 -173
  233. package/dist/site/schemas/dev-delivery-authority-v2.schema.json +0 -442
  234. package/dist/site/schemas/publication-rehearsal-capsule-v1.schema.json +0 -269
  235. package/dist/site/schemas/release-tail-capabilities-v1.schema.json +0 -353
  236. package/dist/site/schemas/release-tail-provider-bindings-v1.schema.json +0 -94
  237. package/docs/dev-delivery-qualification-landing-adr.md +0 -137
  238. package/docs/next-development-transition.md +0 -119
  239. package/docs/publication-rehearsal.md +0 -94
  240. package/packages/core/buildchain-compatibility-proof.js +0 -631
  241. package/packages/core/dev-delivery-authority.js +0 -996
  242. package/packages/core/dev-delivery-native-proof.js +0 -418
  243. package/packages/core/dev-delivery-warrant-shadow.js +0 -502
  244. package/packages/core/next-development-candidate-reservation.js +0 -186
  245. package/packages/core/next-development-controller.js +0 -726
  246. package/packages/core/next-development-projection.js +0 -288
  247. package/packages/core/next-development-transition.js +0 -738
  248. package/packages/core/publication-rehearsal-projection.js +0 -173
  249. package/packages/core/publication-rehearsal-runtime.js +0 -921
  250. package/scripts/aws-macos-jit-instance-rehydrate.mjs +0 -260
  251. package/scripts/aws-macos-jit-source-rebind.mjs +0 -724
  252. package/scripts/dev-delivery-authority.mjs +0 -368
  253. package/scripts/dev-delivery-native-run.mjs +0 -235
  254. package/scripts/dev-delivery-two-phase-resume.mjs +0 -90
  255. package/scripts/dev-delivery-two-phase.mjs +0 -577
  256. package/scripts/generate-next-development-guidance.mjs +0 -49
  257. package/scripts/materialize-self-release-candidate-version.mjs +0 -137
  258. package/scripts/next-development-self-dogfood-harness.mjs +0 -409
  259. package/scripts/next-development-self-dogfood.mjs +0 -532
  260. package/scripts/next-development-transition.mjs +0 -47
  261. package/scripts/release-candidate-tail-reseal.mjs +0 -426
  262. package/templates/native-dev-delivery.yml +0 -86
@@ -1,137 +0,0 @@
1
- #!/usr/bin/env node
2
- import path from "node:path";
3
- import { pathToFileURL } from "node:url";
4
- import {
5
- getVersionStrategy,
6
- loadConfiguredAnchorManifest,
7
- discoverConfiguredDerivedVersionMaterial,
8
- } from "../packages/core/buildchain-config.js";
9
- import {
10
- alignMajorBootstrapReleaseImpact,
11
- currentConfiguredVersion,
12
- discoverVersionStateFiles,
13
- runVersionVerification,
14
- updateVersionStateContents,
15
- versionVerificationAllowedPathsForPromotion,
16
- versionVerificationEnv,
17
- } from "../actions/promote-buildchain-ref/internal/version-state.js";
18
-
19
- function required(value, name) {
20
- const normalized = String(value || "").trim();
21
- if (!normalized) throw new Error(`${name} is required`);
22
- return normalized;
23
- }
24
-
25
- function parseArgs(argv) {
26
- const options = {};
27
- for (let index = 0; index < argv.length; index += 1) {
28
- const argument = argv[index];
29
- if (!argument.startsWith("--")) throw new Error(`unexpected argument: ${argument}`);
30
- const name = argument.slice(2);
31
- const value = argv[index + 1];
32
- if (!value || value.startsWith("--")) throw new Error(`--${name} requires a value`);
33
- options[name] = value;
34
- index += 1;
35
- }
36
- return options;
37
- }
38
-
39
- export function materializeSelfReleaseCandidateVersion({
40
- cwd = process.cwd(),
41
- version,
42
- channel,
43
- sourceSha,
44
- generatedAt,
45
- } = {}) {
46
- const resolvedVersion = required(version, "version");
47
- if (!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(resolvedVersion)) {
48
- throw new Error(`version must be an exact semantic version: ${resolvedVersion}`);
49
- }
50
- const resolvedChannel = required(channel, "channel");
51
- if (!new Set(["alpha", "release", "major"]).has(resolvedChannel)) {
52
- throw new Error(`channel must be alpha, release, or major: ${resolvedChannel}`);
53
- }
54
- const resolvedSourceSha = required(sourceSha, "sourceSha");
55
- if (!/^[0-9a-f]{40}$/i.test(resolvedSourceSha)) {
56
- throw new Error("sourceSha must be a 40-character Git SHA");
57
- }
58
- const resolvedGeneratedAt = required(generatedAt, "generatedAt");
59
- if (Number.isNaN(Date.parse(resolvedGeneratedAt))) {
60
- throw new Error(`generatedAt must be an ISO timestamp: ${resolvedGeneratedAt}`);
61
- }
62
-
63
- const discovered = discoverVersionStateFiles(cwd);
64
- if (discovered.files.length === 0) {
65
- throw new Error("self-release candidate requires declared version state");
66
- }
67
- const discoveredPaths = discovered.files.map((file) => file.path);
68
- const derivedPaths = discoverConfiguredDerivedVersionMaterial(
69
- cwd,
70
- discovered.config,
71
- ).map((file) => file.path);
72
- const versionStrategy = getVersionStrategy(discovered.config);
73
- const anchorManifest = loadConfiguredAnchorManifest(cwd, discovered.config);
74
- const lifecycleEnv = versionVerificationEnv(versionStrategy, anchorManifest, {
75
- generatedAt: resolvedGeneratedAt,
76
- sourceSha: resolvedSourceSha,
77
- });
78
- if (resolvedChannel === "major") {
79
- lifecycleEnv.BUILDCHAIN_MAJOR_VERSION_BOOTSTRAP = "true";
80
- }
81
-
82
- let changedFiles = updateVersionStateContents(discovered.files, resolvedVersion);
83
- if (resolvedChannel === "major") {
84
- changedFiles = alignMajorBootstrapReleaseImpact(changedFiles, {
85
- version: resolvedVersion,
86
- });
87
- }
88
- const materializedFiles = runVersionVerification({
89
- cwd,
90
- loadedConfig: discovered.config,
91
- version: resolvedVersion,
92
- changedFiles,
93
- allowedPaths: versionVerificationAllowedPathsForPromotion(
94
- resolvedChannel,
95
- discoveredPaths,
96
- derivedPaths,
97
- ),
98
- env: lifecycleEnv,
99
- runLifecycleVerify: false,
100
- });
101
- const materialized = discoverVersionStateFiles(cwd);
102
- const actualVersion = currentConfiguredVersion(materialized.files);
103
- if (actualVersion !== resolvedVersion) {
104
- throw new Error(
105
- `materialized self-release candidate version mismatch: expected ${resolvedVersion}, got ${actualVersion || "<empty>"}`,
106
- );
107
- }
108
- return {
109
- schemaVersion: 1,
110
- contract: "kungfu-buildchain-self-release-candidate-version/v1",
111
- version: resolvedVersion,
112
- channel: resolvedChannel,
113
- sourceSha: resolvedSourceSha,
114
- generatedAt: resolvedGeneratedAt,
115
- files: materializedFiles.map((file) => file.path),
116
- };
117
- }
118
-
119
- export function materializeSelfReleaseCandidateVersionCli(argv = process.argv.slice(2)) {
120
- const options = parseArgs(argv);
121
- const result = materializeSelfReleaseCandidateVersion({
122
- cwd: path.resolve(options.cwd || process.cwd()),
123
- version: options.version,
124
- channel: options.channel,
125
- sourceSha: options["source-sha"],
126
- generatedAt: options["generated-at"],
127
- });
128
- process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
129
- return result;
130
- }
131
-
132
- if (
133
- process.argv[1] &&
134
- import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href
135
- ) {
136
- materializeSelfReleaseCandidateVersionCli();
137
- }
@@ -1,409 +0,0 @@
1
- // SPDX-License-Identifier: Apache-2.0
2
-
3
- import crypto from "node:crypto";
4
- import fs from "node:fs";
5
- import os from "node:os";
6
- import path from "node:path";
7
-
8
- import { validateNextDevelopmentController } from "../packages/core/next-development-controller.js";
9
- import {
10
- NEXT_DEVELOPMENT_REQUEST_CONTRACT,
11
- NEXT_DEVELOPMENT_TRANSITION_CONTRACT,
12
- materializeNextDevelopmentTransition,
13
- nextDevelopmentRoot,
14
- } from "../packages/core/next-development-transition.js";
15
-
16
- const ROOT = /^sha256:[0-9a-f]{64}$/u;
17
- const SHA = /^[0-9a-f]{40}$/u;
18
- const REPOSITORY = /^[^/\s]+\/[^/\s]+$/u;
19
- const ANCHOR_BYTES = '{"upstream":"v22.1.0"}\n';
20
-
21
- export const RECORDED_AT = "2026-08-11T02:00:00.000Z";
22
- export const PROTECTED_DEV_BRANCH = "dev/v3/v3.0";
23
- export const HOSTED_READBACK_PATHS = [
24
- ".buildchain/release-impact.json",
25
- "dist/site/buildchain-contract.json",
26
- "package.json",
27
- ];
28
-
29
- export function required(value, label) {
30
- const normalized = String(value || "").trim();
31
- if (!normalized) throw new Error(`${label} is required`);
32
- return normalized;
33
- }
34
-
35
- export function exactRoot(value, label) {
36
- const normalized = required(value, label).toLowerCase();
37
- if (!ROOT.test(normalized)) throw new Error(`${label} must be a sha256 root`);
38
- return normalized;
39
- }
40
-
41
- export function exactSha(value, label) {
42
- const normalized = required(value, label).toLowerCase();
43
- if (!SHA.test(normalized)) {
44
- throw new Error(`${label} must be an exact 40-character Git SHA`);
45
- }
46
- return normalized;
47
- }
48
-
49
- export function repository(value, label = "repository") {
50
- const normalized = required(value, label);
51
- if (!REPOSITORY.test(normalized)) throw new Error(`${label} must be owner/repo`);
52
- return normalized;
53
- }
54
-
55
- export function fixtureSha(label) {
56
- return nextDevelopmentRoot({ label }).slice("sha256:".length, 40 + 7);
57
- }
58
-
59
- function completedAlpha({ runtimeSha, contractRoot, model }) {
60
- const version = model === "anchored" ? "22.0.0-alpha.1" : "3.0.9-alpha.1";
61
- return {
62
- outcome: "succeeded",
63
- version,
64
- exactTag: `v${version}`,
65
- releaseSha: runtimeSha,
66
- treeSha: fixtureSha(`completed-alpha-tree:${model}`),
67
- publicationRoot: nextDevelopmentRoot({ runtimeSha, contractRoot, model }),
68
- completedAt: "2026-08-11T01:00:00.000Z",
69
- };
70
- }
71
-
72
- function adapterCheckout(model, version) {
73
- const cwd = fs.mkdtempSync(
74
- path.join(os.tmpdir(), `buildchain-next-development-self-dogfood-${model}-`),
75
- );
76
- fs.mkdirSync(path.join(cwd, ".buildchain"), { recursive: true });
77
- fs.writeFileSync(
78
- path.join(cwd, ".buildchain", "buildchain.toml"),
79
- `schema = 1
80
-
81
- [version]
82
- required = true
83
- strategy = "${model === "anchored" ? "anchored" : "semver"}"
84
- next = "${model === "anchored" ? "manual" : "auto"}"
85
- ${model === "anchored" ? 'manifest = "release.json"\n' : ""}
86
- [[version.files]]
87
- type = "json"
88
- path = "package.json"
89
- key = "version"
90
- `,
91
- );
92
- fs.writeFileSync(
93
- path.join(cwd, "package.json"),
94
- `${JSON.stringify({ name: "self-dogfood-fixture", version }, null, 2)}\n`,
95
- );
96
- if (model === "anchored") fs.writeFileSync(path.join(cwd, "release.json"), ANCHOR_BYTES);
97
- return cwd;
98
- }
99
-
100
- export function anchorInput() {
101
- return {
102
- targetVersion: "22.1.0",
103
- anchor: {
104
- manifestPath: "release.json",
105
- manifestRoot: `sha256:${crypto.createHash("sha256").update(ANCHOR_BYTES).digest("hex")}`,
106
- },
107
- };
108
- }
109
-
110
- function adapterRequest(route, model, reviewedInput) {
111
- return {
112
- contract: NEXT_DEVELOPMENT_REQUEST_CONTRACT,
113
- repository: route.repository,
114
- completedAlpha: completedAlpha({ ...route, model }),
115
- recordedAt: RECORDED_AT,
116
- ...(reviewedInput || {}),
117
- };
118
- }
119
-
120
- export function adapterTransition(route, model) {
121
- const alpha = completedAlpha({ ...route, model });
122
- const cwd = adapterCheckout(model, alpha.version);
123
- try {
124
- return materializeNextDevelopmentTransition({
125
- cwd,
126
- request: adapterRequest(route, model),
127
- });
128
- } finally {
129
- fs.rmSync(cwd, { recursive: true, force: true });
130
- }
131
- }
132
-
133
- function operationBody(record) {
134
- const body = structuredClone(record);
135
- delete body.operationRoot;
136
- return body;
137
- }
138
-
139
- export function validateAdapterOperation(record) {
140
- exactRoot(record?.operationKey, "adapter operation key");
141
- exactRoot(record?.idempotencyKey, "adapter idempotency key");
142
- exactRoot(record?.materializationRoot, "adapter materialization root");
143
- if (
144
- record?.adapterContract !== NEXT_DEVELOPMENT_TRANSITION_CONTRACT ||
145
- !["semver", "anchored"].includes(record?.model)
146
- ) {
147
- throw new Error("real version-state adapter operation contract mismatch");
148
- }
149
- if (record.operationRoot !== nextDevelopmentRoot(operationBody(record))) {
150
- throw new Error("real version-state adapter operation root drifted");
151
- }
152
- return structuredClone(record);
153
- }
154
-
155
- export function validateSelfDogfoodRoute(route) {
156
- exactSha(route?.runtimeSha, "route.runtimeSha");
157
- const targetRepository = repository(route?.repository, "route.repository");
158
- if (
159
- targetRepository !== "kungfu-systems/buildchain" ||
160
- route.runtimeRef !== "v3-alpha" ||
161
- route.publicWorkflow !==
162
- `${targetRepository}/.github/workflows/build.yml@v3-alpha` ||
163
- route.protectedDevBranch !== PROTECTED_DEV_BRANCH ||
164
- JSON.stringify(route.hostedReadbackPaths) !==
165
- JSON.stringify(HOSTED_READBACK_PATHS)
166
- ) {
167
- throw new Error("next-development evidence public route drifted");
168
- }
169
- return targetRepository;
170
- }
171
-
172
- export function validateRecoveryEvidence(recovery) {
173
- const sameRunner =
174
- required(recovery?.faultRunnerId, "faultRunnerId") ===
175
- required(recovery?.resumeRunnerId, "resumeRunnerId");
176
- const unchangedDev =
177
- exactSha(recovery?.protectedDevMovement?.initialSha, "protected Dev initial SHA") ===
178
- exactSha(recovery?.protectedDevMovement?.movedSha, "protected Dev moved SHA");
179
- if (
180
- recovery?.freshRunner !== true ||
181
- sameRunner ||
182
- recovery?.transientDurableStateFailures !== 1 ||
183
- recovery?.recoveredAdapterOperations !== 1 ||
184
- recovery?.alphaCandidateRebuilds !== 0 ||
185
- recovery?.devMaterializationsBefore !== 1 ||
186
- recovery?.devMaterializationsAfter !== 2 ||
187
- recovery?.protectedDevMovement?.supersededAttempts !== 1 ||
188
- unchangedDev ||
189
- recovery?.protectedPrDelay?.status !== "pr-pending" ||
190
- recovery?.protectedPrDelay?.delayedStatus !== "pr-pending" ||
191
- recovery?.protectedPrDelay?.unchangedControllerRoot !== true
192
- ) {
193
- throw new Error("fresh-runner failure, Dev movement, or protected-PR delay proof is incomplete");
194
- }
195
- }
196
-
197
- export function validateAdapterEvidence(adapter, semver, anchored) {
198
- const operations = adapter?.operations || [];
199
- operations.forEach(validateAdapterOperation);
200
- const expectedKeys = [...semver.attempts, ...anchored.attempts]
201
- .map((entry) => entry.operationKey)
202
- .sort();
203
- const observedKeys = operations.map((entry) => entry.operationKey).sort();
204
- if (
205
- adapter?.boundary !== "materializeNextDevelopmentTransition" ||
206
- adapter?.contract !== NEXT_DEVELOPMENT_TRANSITION_CONTRACT ||
207
- operations.length !== 3 ||
208
- new Set(operations.map((entry) => entry.model)).size !== 2 ||
209
- JSON.stringify(observedKeys) !== JSON.stringify(expectedKeys)
210
- ) {
211
- throw new Error("real version-state adapter boundary proof is incomplete");
212
- }
213
- }
214
-
215
- export class DurableStore {
216
- constructor(records = [], { transientFailures = 0 } = {}) {
217
- this.records = new Map(
218
- records.map((record) => {
219
- const current = validateNextDevelopmentController(record);
220
- return [current.childKey, current];
221
- }),
222
- );
223
- this.transientFailuresRemaining = transientFailures;
224
- this.transientFailures = 0;
225
- }
226
-
227
- async readChild(key) {
228
- return structuredClone(this.records.get(key) || null);
229
- }
230
-
231
- async createChild(key, record) {
232
- if (!this.records.has(key)) this.records.set(key, structuredClone(record));
233
- return { record: structuredClone(this.records.get(key)) };
234
- }
235
-
236
- async compareAndSwapChild(key, expectedRoot, record) {
237
- if (this.transientFailuresRemaining > 0) {
238
- this.transientFailuresRemaining -= 1;
239
- this.transientFailures += 1;
240
- throw new Error("injected transient durable-state write failure");
241
- }
242
- const current = this.records.get(key);
243
- if (!current || current.controllerRoot !== expectedRoot) {
244
- throw new Error("self-dogfood durable store compare-and-swap failed");
245
- }
246
- this.records.set(key, structuredClone(record));
247
- return { record: structuredClone(record) };
248
- }
249
-
250
- only() {
251
- if (this.records.size !== 1) {
252
- throw new Error("self-dogfood durable store expected exactly one child");
253
- }
254
- return structuredClone([...this.records.values()][0]);
255
- }
256
- }
257
-
258
- export class VersionStateAdapterHarness {
259
- constructor({
260
- route,
261
- operations = [],
262
- devSha = fixtureSha("protected-dev:initial"),
263
- movedDevSha = "",
264
- moveAfterRecoveredOperation = false,
265
- pullRequestReadsBeforeMerge = 0,
266
- } = {}) {
267
- this.operations = new Map(
268
- operations.map((record) => {
269
- const current = validateAdapterOperation(record);
270
- return [current.operationKey, current];
271
- }),
272
- );
273
- this.route = route ? structuredClone(route) : null;
274
- this.devSha = devSha;
275
- this.movedDevSha = movedDevSha;
276
- this.moveAfterRecoveredOperation = moveAfterRecoveredOperation;
277
- this.pullRequestReadsBeforeMerge = pullRequestReadsBeforeMerge;
278
- this.materializations = operations.length;
279
- this.recoveredOperations = 0;
280
- this.pullRequestReads = 0;
281
- this.pullRequest = null;
282
- }
283
-
284
- async readProtectedDev() {
285
- return { sha: this.devSha };
286
- }
287
-
288
- async materialize({ operationKey, repository: targetRepository, baseDevSha, targetVersion, anchor }) {
289
- const existing = this.operations.get(operationKey);
290
- if (existing) {
291
- this.recoveredOperations += 1;
292
- if (this.moveAfterRecoveredOperation && this.movedDevSha) {
293
- this.devSha = this.movedDevSha;
294
- this.moveAfterRecoveredOperation = false;
295
- }
296
- return structuredClone(existing.result);
297
- }
298
- const model = anchor ? "anchored" : "semver";
299
- const route = this.route || {
300
- repository: targetRepository,
301
- runtimeSha: model === "anchored" ? fixtureSha("anchored-runtime") : fixtureSha("semver-runtime"),
302
- contractRoot: nextDevelopmentRoot({ model, targetRepository }),
303
- };
304
- const alpha = completedAlpha({ ...route, model });
305
- const cwd = adapterCheckout(model, alpha.version);
306
- let materialized;
307
- try {
308
- materialized = materializeNextDevelopmentTransition({
309
- cwd,
310
- request: adapterRequest(
311
- route,
312
- model,
313
- model === "anchored" ? { targetVersion, anchor } : undefined,
314
- ),
315
- write: true,
316
- });
317
- } finally {
318
- fs.rmSync(cwd, { recursive: true, force: true });
319
- }
320
- if (materialized.state.status !== "materialized" || materialized.target.version !== targetVersion) {
321
- throw new Error("real version-state adapter did not materialize the target");
322
- }
323
- const result = {
324
- baseDevSha,
325
- commitSha: fixtureSha(`prepared:${operationKey}:${materialized.materialization.materializationRoot}`),
326
- treeSha: fixtureSha(`prepared-tree:${operationKey}:${materialized.materialization.materializationRoot}`),
327
- sourceRoots: materialized.materialization.paths.map((entry) => ({
328
- path: entry.path,
329
- beforeRoot: entry.beforeRoot,
330
- afterRoot: entry.afterRoot,
331
- version: targetVersion,
332
- })),
333
- derivedRoots: [],
334
- changedPaths: materialized.materialization.paths
335
- .filter((entry) => entry.changed)
336
- .map((entry) => entry.path)
337
- .sort(),
338
- lifecycleEvidenceRoot: materialized.materialization.materializationRoot,
339
- };
340
- const record = {
341
- operationKey,
342
- model,
343
- adapterContract: materialized.contract,
344
- idempotencyKey: materialized.idempotencyKey,
345
- materializationRoot: materialized.materialization.materializationRoot,
346
- result,
347
- };
348
- record.operationRoot = nextDevelopmentRoot(record);
349
- this.operations.set(operationKey, validateAdapterOperation(record));
350
- this.materializations += 1;
351
- return structuredClone(result);
352
- }
353
-
354
- async ensurePullRequest({ baseBranch, headSha }) {
355
- this.pullRequest = {
356
- number: 91,
357
- url: "https://github.com/kungfu-systems/buildchain/pull/91",
358
- baseBranch,
359
- headSha,
360
- status: "open",
361
- evidenceRoot: nextDevelopmentRoot({ baseBranch, headSha, pullRequest: 91 }),
362
- };
363
- return structuredClone(this.pullRequest);
364
- }
365
-
366
- async readPullRequest({ number }) {
367
- if (!this.pullRequest) throw new Error(`self-dogfood pull request ${number} was not restored`);
368
- this.pullRequestReads += 1;
369
- if (this.pullRequestReads > this.pullRequestReadsBeforeMerge) {
370
- this.pullRequest.status = "merged";
371
- this.devSha = fixtureSha(`protected-merge:${this.pullRequest.headSha}`);
372
- }
373
- return structuredClone(this.pullRequest);
374
- }
375
-
376
- async readProtectedVersionState({ sourcePaths, derivedPaths, targetVersion, preparedCommitSha }) {
377
- const operation = [...this.operations.values()].find(
378
- (entry) => entry.result.commitSha === preparedCommitSha,
379
- );
380
- if (!operation) throw new Error("protected readback has no rooted adapter operation");
381
- const sourceRoots = Object.fromEntries(
382
- operation.result.sourceRoots.map((entry) => [entry.path, entry.afterRoot]),
383
- );
384
- const derivedRoots = Object.fromEntries(
385
- operation.result.derivedRoots.map((entry) => [entry.path, entry.root]),
386
- );
387
- const body = {
388
- branch: PROTECTED_DEV_BRANCH,
389
- devSha: this.devSha,
390
- preparedCommitSha,
391
- targetVersion,
392
- versionRoots: sourcePaths.map((filePath) => ({ path: filePath, root: sourceRoots[filePath] })),
393
- derivedRoots: derivedPaths.map((filePath) => ({ path: filePath, root: derivedRoots[filePath] })),
394
- };
395
- return {
396
- devSha: this.devSha,
397
- treeSha: fixtureSha(`protected-readback-tree:${preparedCommitSha}`),
398
- version: targetVersion,
399
- containsPreparedCommit: true,
400
- versionRoots: body.versionRoots,
401
- derivedRoots: body.derivedRoots,
402
- evidenceRoot: nextDevelopmentRoot(body),
403
- };
404
- }
405
-
406
- operationRecords() {
407
- return [...this.operations.values()].map((entry) => structuredClone(entry));
408
- }
409
- }