@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,368 +0,0 @@
1
- #!/usr/bin/env node
2
- import fs from "node:fs";
3
- import path from "node:path";
4
-
5
- import {
6
- acquireDevDeliveryLandingWarrant,
7
- acquireDevDeliveryQualificationLease,
8
- admitDevDeliveryMergeGroup,
9
- completeDevDeliveryQualification,
10
- createDevDeliveryAuthorityState,
11
- heartbeatDevDeliveryLandingWarrant,
12
- heartbeatDevDeliveryQualificationLease,
13
- migrateDevDeliveryAuthorityState,
14
- observeDevDeliveryAuthorityState,
15
- recoverDevDeliveryAuthority,
16
- settleDevDeliveryAuthorityCandidate,
17
- submitDevDeliveryAuthorityCandidate,
18
- } from "../packages/core/dev-delivery-authority.js";
19
- import { GitHubDevDeliveryStore } from "./dev-delivery-warrant.mjs";
20
-
21
- const STATE_REF_PREFIX = "buildchain/dev-delivery-authority/";
22
-
23
- function text(value = "") {
24
- return String(value ?? "").trim();
25
- }
26
-
27
- function positiveInteger(value, label, fallback = 0) {
28
- const parsed = Number(value || fallback);
29
- if (!Number.isInteger(parsed) || parsed < 1) {
30
- throw new Error(`${label} must be a positive integer`);
31
- }
32
- return parsed;
33
- }
34
-
35
- function nonNegativeInteger(value, label, fallback = 0) {
36
- const parsed = Number(value === undefined || value === "" ? fallback : value);
37
- if (!Number.isInteger(parsed) || parsed < 0) throw new Error(`${label} must be a non-negative integer`);
38
- return parsed;
39
- }
40
-
41
- function bool(value, fallback = false) {
42
- if (value === undefined || value === null || value === "") return fallback;
43
- return ["1", "true", "yes", "on"].includes(text(value).toLowerCase());
44
- }
45
-
46
- function repository(value) {
47
- const normalized = text(value);
48
- if (!/^[^/\s]+\/[^/\s]+$/.test(normalized)) {
49
- throw new Error("repository must be owner/repo");
50
- }
51
- return normalized;
52
- }
53
-
54
- function branch(value) {
55
- const normalized = text(value).replace(/^refs\/heads\//, "");
56
- if (!/^dev\/v\d+\/v\d+\.\d+$/.test(normalized)) {
57
- throw new Error("branch must be dev/vN/vN.M");
58
- }
59
- return normalized;
60
- }
61
-
62
- export function defaultDevDeliveryAuthorityStateRef(value) {
63
- return `${STATE_REF_PREFIX}${branch(value).replaceAll("/", "-")}`;
64
- }
65
-
66
- function stateRef(value, protectedBranch) {
67
- const normalized = text(value || defaultDevDeliveryAuthorityStateRef(protectedBranch)).replace(/^refs\/heads\//, "");
68
- if (!normalized.startsWith(STATE_REF_PREFIX) || normalized.includes("..")) {
69
- throw new Error(`state ref must remain under ${STATE_REF_PREFIX}`);
70
- }
71
- return normalized;
72
- }
73
-
74
- function identity(state, options) {
75
- return {
76
- candidateId: options.candidateId,
77
- token: options.authorityToken,
78
- generation: options.authorityGeneration,
79
- };
80
- }
81
-
82
- function rootedList(value) {
83
- if (Array.isArray(value)) return value;
84
- let parsed;
85
- try {
86
- parsed = JSON.parse(value || "[]");
87
- } catch (cause) {
88
- throw new Error(`qualification domains must be a JSON array: ${cause.message}`);
89
- }
90
- if (!Array.isArray(parsed)) throw new Error("qualification domains must be a JSON array");
91
- return parsed;
92
- }
93
-
94
- function transitionFor(command, state, options) {
95
- if (command === "migrate") {
96
- if (!options.legacyState) {
97
- throw new Error("migrate requires --legacy-state <v1-queue.json>");
98
- }
99
- return migrateDevDeliveryAuthorityState(options.legacyState, {
100
- now: options.now,
101
- policy: state.policy,
102
- });
103
- }
104
- if (command === "submit") {
105
- return submitDevDeliveryAuthorityCandidate(
106
- state,
107
- {
108
- pullRequestNumber: options.pullRequestNumber,
109
- sourceHead: options.sourceHead,
110
- assignmentRoot: options.assignmentRoot,
111
- initiativeRoot: options.initiativeRoot,
112
- sourceIdentityRoot: options.sourceIdentityRoot,
113
- sourcePatchRoot: options.sourcePatchRoot,
114
- sourceProofRoot: options.sourceProofRoot,
115
- planRoot: options.planRoot,
116
- closureRoot: options.closureRoot,
117
- dependencyRoot: options.dependencyRoot,
118
- toolchainRoot: options.toolchainRoot,
119
- deliveryClass: options.deliveryClass,
120
- qualificationDomains: rootedList(options.qualificationDomains),
121
- },
122
- { now: options.now },
123
- );
124
- }
125
- if (command === "lease-qualification") {
126
- return acquireDevDeliveryQualificationLease(state, {
127
- now: options.now,
128
- leaseSeconds: options.leaseSeconds,
129
- });
130
- }
131
- if (command === "complete-qualification") {
132
- return completeDevDeliveryQualification(state, identity(state, options), {
133
- evidenceRoot: options.evidenceRoot,
134
- now: options.now,
135
- });
136
- }
137
- if (command === "heartbeat-qualification") {
138
- return heartbeatDevDeliveryQualificationLease(state, identity(state, options), {
139
- now: options.now,
140
- leaseSeconds: options.leaseSeconds,
141
- });
142
- }
143
- if (command === "lease-landing") {
144
- return acquireDevDeliveryLandingWarrant(state, {
145
- now: options.now,
146
- leaseSeconds: options.leaseSeconds,
147
- });
148
- }
149
- if (command === "heartbeat-landing") {
150
- return heartbeatDevDeliveryLandingWarrant(state, identity(state, options), {
151
- now: options.now,
152
- leaseSeconds: options.leaseSeconds,
153
- });
154
- }
155
- if (command === "recover") return recoverDevDeliveryAuthority(state, { now: options.now });
156
- if (command === "settle") {
157
- return settleDevDeliveryAuthorityCandidate(
158
- state,
159
- {
160
- pullRequestNumber: options.pullRequestNumber,
161
- sourceHead: options.sourceHead,
162
- outcome: options.outcome,
163
- evidenceRoot: options.evidenceRoot,
164
- reason: options.reason,
165
- authorityToken: options.authorityToken,
166
- authorityGeneration: options.authorityGeneration,
167
- },
168
- { now: options.now },
169
- );
170
- }
171
- throw new Error(`unsupported dev authority command ${command || "<empty>"}`);
172
- }
173
-
174
- export async function runDevDeliveryAuthorityCommand(optionsInput = {}, clientInput) {
175
- const options = {
176
- ...optionsInput,
177
- repository: repository(optionsInput.repository),
178
- branch: branch(optionsInput.branch),
179
- now: new Date(optionsInput.now || Date.now()).toISOString(),
180
- execute: bool(optionsInput.execute),
181
- };
182
- options.stateRef = stateRef(optionsInput.stateRef, options.branch);
183
- const store =
184
- clientInput ||
185
- new GitHubDevDeliveryStore({
186
- repository: options.repository,
187
- token: options.token || process.env.GITHUB_TOKEN,
188
- apiUrl: options.apiUrl || process.env.GITHUB_API_URL || "https://api.github.com",
189
- createInitialState: ({ repository: repositoryInput, protectedBase, now }) =>
190
- createDevDeliveryAuthorityState({
191
- repository: repositoryInput,
192
- protectedBase,
193
- policy: {
194
- maxQualificationLeases: positiveInteger(options.maxQualificationLeases, "maxQualificationLeases", 2),
195
- qualificationLeaseSeconds: positiveInteger(options.qualificationLeaseSeconds, "qualificationLeaseSeconds", 3600),
196
- landingLeaseSeconds: positiveInteger(options.landingLeaseSeconds, "landingLeaseSeconds", 900),
197
- maxLandingOvertakes: nonNegativeInteger(options.maxLandingOvertakes, "maxLandingOvertakes", 2),
198
- maxQualificationAttempts: positiveInteger(options.maxQualificationAttempts, "maxQualificationAttempts", 3),
199
- },
200
- now,
201
- }),
202
- });
203
- const loaded = await store.read({
204
- stateRef: options.stateRef,
205
- protectedBase: options.branch,
206
- now: options.now,
207
- });
208
- if (options.command === "migrate" && loaded.exists) {
209
- throw new Error("migration target state ref already exists");
210
- }
211
- if (options.expectedOldStateRoot && loaded.queue.stateRoot !== options.expectedOldStateRoot) {
212
- throw new Error(`expected-old state drift: ${loaded.queue.stateRoot} != ${options.expectedOldStateRoot}`);
213
- }
214
- if (options.command === "observe") {
215
- return {
216
- schema: "kungfu.buildchain.dev-delivery-authority-command-result/v1",
217
- ok: true,
218
- mode: "observe",
219
- stateRef: options.stateRef,
220
- stateCommit: loaded.commitSha,
221
- observation: observeDevDeliveryAuthorityState(loaded.queue, {
222
- now: options.now,
223
- }),
224
- };
225
- }
226
- if (options.command === "admit-merge-group") {
227
- const admitted = admitDevDeliveryMergeGroup(loaded.queue, identity(loaded.queue, options), { mergeGroupHead: options.mergeGroupHead, now: options.now });
228
- return {
229
- schema: "kungfu.buildchain.dev-delivery-authority-command-result/v1",
230
- ok: true,
231
- mode: "admission-check",
232
- command: options.command,
233
- stateRef: options.stateRef,
234
- before: {
235
- commitSha: loaded.commitSha,
236
- stateRoot: loaded.queue.stateRoot,
237
- },
238
- after: { commitSha: loaded.commitSha, stateRoot: loaded.queue.stateRoot },
239
- mutationAuthorized: false,
240
- mutationApplied: false,
241
- ...admitted,
242
- observation: observeDevDeliveryAuthorityState(loaded.queue, {
243
- now: options.now,
244
- }),
245
- };
246
- }
247
- if (options.legacyStatePath) {
248
- options.legacyState = JSON.parse(fs.readFileSync(path.resolve(options.legacyStatePath), "utf8"));
249
- }
250
- const changed = transitionFor(options.command, loaded.queue, options);
251
- if (changed.state.repository !== options.repository || changed.state.protectedBase !== options.branch) {
252
- throw new Error("authority transition repository or protected base drift");
253
- }
254
- const mutates = changed.state.stateRoot !== loaded.queue.stateRoot;
255
- let write = null;
256
- if (options.execute && mutates) {
257
- if (options.command !== "migrate" && changed.receipt.expectedOldStateRoot !== loaded.queue.stateRoot) {
258
- throw new Error("transition expected-old root does not match loaded authority");
259
- }
260
- write = await store.write({
261
- stateRef: options.stateRef,
262
- queue: changed.state,
263
- expectedCommitSha: loaded.commitSha,
264
- expectedStateRoot: loaded.queue.stateRoot,
265
- receiptRoot: changed.receiptRoot,
266
- });
267
- }
268
- return {
269
- schema: "kungfu.buildchain.dev-delivery-authority-command-result/v1",
270
- ok: true,
271
- mode: options.execute ? "execute" : "plan",
272
- command: options.command,
273
- stateRef: options.stateRef,
274
- before: { commitSha: loaded.commitSha, stateRoot: loaded.queue.stateRoot },
275
- after: {
276
- commitSha: write?.commitSha || loaded.commitSha,
277
- stateRoot: changed.state.stateRoot,
278
- },
279
- mutationAuthorized: options.execute,
280
- mutationApplied: Boolean(write),
281
- receipt: changed.receipt,
282
- receiptRoot: changed.receiptRoot,
283
- lease: changed.lease || null,
284
- warrant: changed.warrant || changed.state.landingWarrant || null,
285
- observation: observeDevDeliveryAuthorityState(changed.state, {
286
- now: options.now,
287
- }),
288
- };
289
- }
290
-
291
- function flag(args, name, fallback = "") {
292
- const index = args.indexOf(`--${name}`);
293
- return index === -1 ? fallback : args[index + 1] || "";
294
- }
295
-
296
- function hasFlag(args, name) {
297
- return args.includes(`--${name}`);
298
- }
299
-
300
- export function devDeliveryAuthorityCliOptions(args = [], environment = process.env) {
301
- const [command = "", ...rest] = args;
302
- return {
303
- command,
304
- repository: flag(rest, "repository", environment.GITHUB_REPOSITORY),
305
- branch: flag(rest, "branch", environment.BUILDCHAIN_DEV_DELIVERY_BRANCH || environment.GITHUB_BASE_REF),
306
- stateRef: flag(rest, "state-ref", environment.BUILDCHAIN_DEV_AUTHORITY_STATE_REF),
307
- expectedOldStateRoot: flag(rest, "expected-old", environment.BUILDCHAIN_DEV_AUTHORITY_EXPECTED_OLD),
308
- pullRequestNumber: flag(rest, "pull-request", environment.BUILDCHAIN_DEV_DELIVERY_PR_NUMBER),
309
- candidateId: flag(rest, "candidate-id", environment.BUILDCHAIN_DEV_DELIVERY_CANDIDATE_ID),
310
- sourceHead: flag(rest, "source-head", environment.BUILDCHAIN_DEV_DELIVERY_SOURCE_HEAD),
311
- assignmentRoot: flag(rest, "assignment-root", environment.BUILDCHAIN_DEV_DELIVERY_ASSIGNMENT_ROOT),
312
- initiativeRoot: flag(rest, "initiative-root", environment.BUILDCHAIN_DEV_DELIVERY_INITIATIVE_ROOT),
313
- sourceIdentityRoot: flag(rest, "source-identity-root", environment.BUILDCHAIN_DEV_DELIVERY_SOURCE_IDENTITY_ROOT),
314
- sourcePatchRoot: flag(rest, "source-patch-root", environment.BUILDCHAIN_DEV_DELIVERY_SOURCE_PATCH_ROOT),
315
- sourceProofRoot: flag(rest, "source-proof-root", environment.BUILDCHAIN_DEV_DELIVERY_SOURCE_PROOF_ROOT),
316
- planRoot: flag(rest, "plan-root", environment.BUILDCHAIN_DEV_DELIVERY_PLAN_ROOT),
317
- closureRoot: flag(rest, "closure-root", environment.BUILDCHAIN_DEV_DELIVERY_CLOSURE_ROOT),
318
- dependencyRoot: flag(rest, "dependency-root", environment.BUILDCHAIN_DEV_DELIVERY_DEPENDENCY_ROOT),
319
- toolchainRoot: flag(rest, "toolchain-root", environment.BUILDCHAIN_DEV_DELIVERY_TOOLCHAIN_ROOT),
320
- legacyStatePath: flag(rest, "legacy-state", environment.BUILDCHAIN_DEV_AUTHORITY_LEGACY_STATE),
321
- deliveryClass: flag(rest, "delivery-class", environment.BUILDCHAIN_DEV_DELIVERY_CLASS),
322
- qualificationDomains: flag(rest, "qualification-domains", environment.BUILDCHAIN_DEV_QUALIFICATION_DOMAINS || "[]"),
323
- authorityToken: flag(rest, "authority-token", environment.BUILDCHAIN_DEV_AUTHORITY_TOKEN),
324
- authorityGeneration: flag(rest, "authority-generation", environment.BUILDCHAIN_DEV_AUTHORITY_GENERATION),
325
- evidenceRoot: flag(rest, "evidence-root", environment.BUILDCHAIN_DEV_DELIVERY_EVIDENCE_ROOT),
326
- mergeGroupHead: flag(rest, "merge-group-head", environment.BUILDCHAIN_DEV_MERGE_GROUP_HEAD),
327
- outcome: flag(rest, "outcome", environment.BUILDCHAIN_DEV_DELIVERY_OUTCOME),
328
- reason: flag(rest, "reason", environment.BUILDCHAIN_DEV_DELIVERY_REASON),
329
- leaseSeconds: flag(rest, "lease-seconds", environment.BUILDCHAIN_DEV_AUTHORITY_LEASE_SECONDS),
330
- maxQualificationLeases: flag(rest, "max-qualification-leases", environment.BUILDCHAIN_DEV_MAX_QUALIFICATION_LEASES || "2"),
331
- qualificationLeaseSeconds: flag(rest, "qualification-lease-seconds", environment.BUILDCHAIN_DEV_QUALIFICATION_LEASE_SECONDS || "3600"),
332
- landingLeaseSeconds: flag(rest, "landing-lease-seconds", environment.BUILDCHAIN_DEV_LANDING_LEASE_SECONDS || "900"),
333
- maxLandingOvertakes: flag(rest, "max-landing-overtakes", environment.BUILDCHAIN_DEV_MAX_LANDING_OVERTAKES || "2"),
334
- maxQualificationAttempts: flag(rest, "max-qualification-attempts", environment.BUILDCHAIN_DEV_MAX_QUALIFICATION_ATTEMPTS || "3"),
335
- now: flag(rest, "now", environment.BUILDCHAIN_DEV_DELIVERY_NOW),
336
- outputPath: flag(rest, "output", environment.BUILDCHAIN_DEV_DELIVERY_OUTPUT || ".buildchain/dev-delivery/authority-result.json"),
337
- execute: hasFlag(rest, "execute"),
338
- json: hasFlag(rest, "json"),
339
- };
340
- }
341
-
342
- function usage() {
343
- return "Usage: buildchain dev authority <migrate|submit|lease-qualification|heartbeat-qualification|complete-qualification|lease-landing|heartbeat-landing|recover|admit-merge-group|settle|observe> --repository <owner/repo> --branch <dev/vN/vN.M> [--qualification-domains <json>] [--legacy-state <v1-queue.json>] [--execute] [--output <file>] [--json]\n";
344
- }
345
-
346
- async function main() {
347
- const args = process.argv.slice(2);
348
- if (args.length === 0 || hasFlag(args, "help")) {
349
- process.stdout.write(usage());
350
- return;
351
- }
352
- const options = devDeliveryAuthorityCliOptions(args);
353
- if (!["submit", "migrate", "lease-qualification", "heartbeat-qualification", "complete-qualification", "lease-landing", "heartbeat-landing", "recover", "admit-merge-group", "settle", "observe"].includes(options.command)) {
354
- throw new Error(usage().trim());
355
- }
356
- const result = await runDevDeliveryAuthorityCommand(options);
357
- fs.mkdirSync(path.dirname(options.outputPath), { recursive: true });
358
- fs.writeFileSync(options.outputPath, `${JSON.stringify(result, null, 2)}\n`);
359
- if (options.json) process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
360
- else process.stdout.write(`Buildchain dev authority ${options.command}: ${result.mode}\nResult: ${options.outputPath}\n`);
361
- }
362
-
363
- if (import.meta.url === `file://${process.argv[1]}`) {
364
- main().catch((error) => {
365
- console.error(`buildchain dev authority: ${error.message}`);
366
- process.exit(1);
367
- });
368
- }
@@ -1,235 +0,0 @@
1
- #!/usr/bin/env node
2
- import { spawn } from "node:child_process";
3
- import fs from "node:fs";
4
- import path from "node:path";
5
-
6
- import { devDeliveryContentRoot } from "../packages/core/dev-delivery-warrant.js";
7
- import { runDevDeliveryCommand } from "./dev-delivery-warrant.mjs";
8
-
9
- function flag(args, name, fallback = "") {
10
- const index = args.indexOf(`--${name}`);
11
- return index === -1 ? fallback : args[index + 1] || "";
12
- }
13
-
14
- function positiveInteger(value, label, fallback) {
15
- const parsed = Number(value || fallback);
16
- if (!Number.isInteger(parsed) || parsed < 1) {
17
- throw new Error(`${label} must be a positive integer`);
18
- }
19
- return parsed;
20
- }
21
-
22
- function exactRoot(value, label) {
23
- const normalized = String(value || "")
24
- .trim()
25
- .toLowerCase();
26
- if (!/^sha256:[0-9a-f]{64}$/u.test(normalized)) {
27
- throw new Error(`${label} must be a sha256 content root`);
28
- }
29
- return normalized;
30
- }
31
-
32
- export async function runNativeWithHeartbeat({
33
- command,
34
- cwd = process.cwd(),
35
- heartbeat,
36
- executionBinding = {},
37
- intervalMs = 30_000,
38
- terminationGraceMs = 10_000,
39
- terminationKillMs = 5_000,
40
- spawnImpl = spawn,
41
- now = () => new Date().toISOString(),
42
- } = {}) {
43
- if (!String(command || "").trim()) {
44
- throw new Error("native command is required");
45
- }
46
- if (typeof heartbeat !== "function") {
47
- throw new Error("heartbeat callback is required");
48
- }
49
- const startedAt = now();
50
- try {
51
- await heartbeat();
52
- } catch (error) {
53
- throw new Error(`native heartbeat failed: ${error.message}`);
54
- }
55
- let heartbeatCount = 1;
56
- let heartbeatError = null;
57
- let heartbeatRunning = false;
58
- let childExited = false;
59
- let forceKillTimer = null;
60
- let terminationTimer = null;
61
- let rejectTermination;
62
- const terminationFailure = new Promise((_, reject) => {
63
- rejectTermination = reject;
64
- });
65
- const child = spawnImpl("bash", ["-lc", command], {
66
- cwd,
67
- env: process.env,
68
- stdio: "inherit",
69
- detached: process.platform !== "win32",
70
- });
71
-
72
- const signalChild = (signal) => {
73
- if (childExited) return;
74
- if (process.platform !== "win32" && Number.isInteger(child.pid)) {
75
- try {
76
- process.kill(-child.pid, signal);
77
- return;
78
- } catch {
79
- // Fall through to the direct child handle for mocked or already-exiting processes.
80
- }
81
- }
82
- child.kill(signal);
83
- };
84
-
85
- const terminateForFenceLoss = () => {
86
- signalChild("SIGTERM");
87
- forceKillTimer = setTimeout(() => {
88
- signalChild("SIGKILL");
89
- terminationTimer = setTimeout(() => {
90
- if (!childExited)
91
- rejectTermination(
92
- new Error("native worker did not stop after fencing loss"),
93
- );
94
- }, terminationKillMs);
95
- terminationTimer.unref?.();
96
- }, terminationGraceMs);
97
- forceKillTimer.unref?.();
98
- };
99
-
100
- const beat = async () => {
101
- if (heartbeatRunning || heartbeatError) return;
102
- heartbeatRunning = true;
103
- try {
104
- await heartbeat();
105
- heartbeatCount += 1;
106
- } catch (error) {
107
- heartbeatError = error;
108
- terminateForFenceLoss();
109
- } finally {
110
- heartbeatRunning = false;
111
- }
112
- };
113
- const timer = setInterval(beat, intervalMs);
114
- const exitPromise = new Promise((resolve, reject) => {
115
- child.once("error", reject);
116
- child.once("exit", (code, signal) => {
117
- childExited = true;
118
- resolve({ code, signal });
119
- });
120
- });
121
- const exit = await Promise.race([exitPromise, terminationFailure]).finally(
122
- () => {
123
- clearInterval(timer);
124
- if (forceKillTimer) clearTimeout(forceKillTimer);
125
- if (terminationTimer) clearTimeout(terminationTimer);
126
- },
127
- );
128
- while (heartbeatRunning) {
129
- await new Promise((resolve) => setTimeout(resolve, 10));
130
- }
131
- if (heartbeatError) {
132
- throw new Error(`native heartbeat failed: ${heartbeatError.message}`);
133
- }
134
- if (exit.code !== 0) {
135
- throw new Error(
136
- `native command failed with ${exit.signal || `exit ${exit.code}`}`,
137
- );
138
- }
139
- await beat();
140
- const completedAt = now();
141
- const receipt = {
142
- schema: "kungfu.buildchain.native-heartbeat-run-receipt/v1",
143
- outcome: "succeeded",
144
- commandRoot: devDeliveryContentRoot({ command }),
145
- executionBindingRoot: devDeliveryContentRoot(executionBinding),
146
- startedAt,
147
- completedAt,
148
- heartbeatCount,
149
- };
150
- return { ...receipt, receiptRoot: devDeliveryContentRoot(receipt) };
151
- }
152
-
153
- async function main() {
154
- const args = process.argv.slice(2);
155
- const repository = flag(args, "repository", process.env.GITHUB_REPOSITORY);
156
- const branch = flag(
157
- args,
158
- "branch",
159
- process.env.BUILDCHAIN_DEV_DELIVERY_BRANCH || process.env.GITHUB_BASE_REF,
160
- );
161
- const command = flag(
162
- args,
163
- "command",
164
- process.env.BUILDCHAIN_DEV_DELIVERY_NATIVE_COMMAND,
165
- );
166
- const cwd = path.resolve(
167
- flag(args, "working-directory", process.env.GITHUB_WORKSPACE),
168
- );
169
- const fencingToken = exactRoot(
170
- flag(
171
- args,
172
- "fencing-token",
173
- process.env.BUILDCHAIN_DEV_DELIVERY_FENCING_TOKEN,
174
- ),
175
- "fencingToken",
176
- );
177
- const leaseGeneration = positiveInteger(
178
- flag(
179
- args,
180
- "lease-generation",
181
- process.env.BUILDCHAIN_DEV_DELIVERY_LEASE_GENERATION,
182
- ),
183
- "leaseGeneration",
184
- );
185
- const leaseSeconds = positiveInteger(
186
- flag(
187
- args,
188
- "lease-seconds",
189
- process.env.BUILDCHAIN_DEV_DELIVERY_LEASE_SECONDS,
190
- ),
191
- "leaseSeconds",
192
- 3600,
193
- );
194
- const heartbeatSeconds = positiveInteger(
195
- flag(
196
- args,
197
- "heartbeat-seconds",
198
- process.env.BUILDCHAIN_DEV_DELIVERY_HEARTBEAT_SECONDS,
199
- ),
200
- "heartbeatSeconds",
201
- Math.max(15, Math.floor(leaseSeconds / 3)),
202
- );
203
- if (heartbeatSeconds >= leaseSeconds) {
204
- throw new Error("heartbeatSeconds must be less than leaseSeconds");
205
- }
206
- const output = path.resolve(
207
- flag(args, "output", ".buildchain/dev-delivery/native-heartbeat-run.json"),
208
- );
209
- const result = await runNativeWithHeartbeat({
210
- command,
211
- cwd,
212
- intervalMs: heartbeatSeconds * 1000,
213
- heartbeat: async () => {
214
- await runDevDeliveryCommand({
215
- command: "heartbeat",
216
- repository,
217
- branch,
218
- fencingToken,
219
- leaseGeneration,
220
- leaseSeconds,
221
- execute: true,
222
- });
223
- },
224
- });
225
- fs.mkdirSync(path.dirname(output), { recursive: true });
226
- fs.writeFileSync(output, `${JSON.stringify(result, null, 2)}\n`);
227
- process.stdout.write(`Native heartbeat run: ${result.receiptRoot}\n`);
228
- }
229
-
230
- if (import.meta.url === `file://${process.argv[1]}`) {
231
- main().catch((error) => {
232
- console.error(`buildchain dev native: ${error.message}`);
233
- process.exit(1);
234
- });
235
- }
@@ -1,90 +0,0 @@
1
- import { createNativeProofReuseDecision } from "../packages/core/dev-delivery-warrant.js";
2
-
3
- const ROOT_PATTERN = /^sha256:[0-9a-f]{64}$/u;
4
-
5
- export function attributedGitHubBaseDelta(data, previousBase) {
6
- const files = Array.isArray(data?.files) ? data.files : [];
7
- const graphKnown =
8
- data?.status === "ahead" &&
9
- data?.merge_base_commit?.sha === previousBase &&
10
- files.length < 300;
11
- const renames = files
12
- .filter((entry) => entry.status === "renamed")
13
- .map((entry) => ({
14
- from: String(entry.previous_filename || ""),
15
- to: String(entry.filename || ""),
16
- }));
17
- const attributionComplete =
18
- graphKnown && renames.every((entry) => entry.from && entry.to);
19
- return {
20
- graphKnown,
21
- attributionComplete,
22
- changedPaths: attributionComplete
23
- ? [
24
- ...new Set(
25
- files
26
- .flatMap((entry) => [
27
- String(entry.filename || ""),
28
- String(entry.previous_filename || ""),
29
- ])
30
- .filter(Boolean),
31
- ),
32
- ].sort()
33
- : [],
34
- renames: attributionComplete ? renames : [],
35
- };
36
- }
37
-
38
- export async function replayQualifiedNativeWarrant({
39
- warrant,
40
- pullRequestNumber,
41
- expectedHead,
42
- exactPullRequestHead,
43
- }) {
44
- if (warrant.phase !== "qualified") return null;
45
- if (
46
- !ROOT_PATTERN.test(warrant.nativeProofRoot || "") ||
47
- !ROOT_PATTERN.test(warrant.nativeProofReuseRoot || "")
48
- ) {
49
- throw new Error("qualified Warrant is missing rooted native evidence");
50
- }
51
- await exactPullRequestHead(pullRequestNumber, expectedHead);
52
- return {
53
- schema: "kungfu.buildchain.two-phase-delivery-result/v1",
54
- ok: true,
55
- outcome: "already-qualified-warrant",
56
- nativeAttempts: 0,
57
- nativeProofRoot: warrant.nativeProofRoot,
58
- nativeReuseDecisionRoot: warrant.nativeProofReuseRoot,
59
- qualificationReceiptRoot: null,
60
- landingAuthority: false,
61
- qualifiedWarrant: warrant,
62
- };
63
- }
64
-
65
- export async function classifyNativeProofAgainstCurrent(
66
- proof,
67
- options,
68
- client,
69
- ) {
70
- const currentBase = await client.baseSha(options.branch);
71
- const delta = await client.baseDelta(proof.qualifiedBase, currentBase);
72
- const current = {
73
- sourceIdentityRoot: options.sourceIdentityRoot,
74
- sourcePatchRoot: options.sourcePatchRoot,
75
- planRoot: options.planRoot,
76
- closureRoot: options.closureRoot,
77
- dependencyRoot: options.dependencyRoot,
78
- toolchainRoot: options.toolchainRoot,
79
- environmentRoot: options.environmentRoot,
80
- currentBase,
81
- graphKnown: delta.graphKnown,
82
- attributionComplete: delta.attributionComplete,
83
- changedPaths: delta.changedPaths,
84
- renames: delta.renames,
85
- };
86
- return {
87
- current,
88
- decision: createNativeProofReuseDecision({ proof, current }),
89
- };
90
- }