@kungfu-tech/buildchain 3.0.9-alpha.9 → 4.0.0-alpha.1

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 +301 -388
  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 +3 -6
  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 +21 -40
  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
@@ -6,21 +6,14 @@ import {
6
6
  AWS_MACOS_JIT_CONTROLLER_CONTRACT,
7
7
  createMacosJitCampaignPlan,
8
8
  createMacosJitClosePlan,
9
- createMacosJitInstanceRehydratePlan,
10
9
  createMacosJitJobPlan,
11
- createMacosJitSourceRebindPlan,
12
10
  macosAllocateHostsArgs,
13
11
  macosReleaseHostsArgs,
14
12
  macosRunInstancesArgs,
15
13
  } from "./aws-macos-jit-controller-core.mjs";
16
- import { MACOS_EC2_JIT_REGIONS } from "./aws-macos-jit-core.mjs";
17
- import { executeMacosJitInstanceRehydrate } from "./aws-macos-jit-instance-rehydrate.mjs";
18
14
  import { executeMacosJitJob } from "./aws-macos-jit-job-controller.mjs";
19
- import { executeMacosJitSourceRebind } from "./aws-macos-jit-source-rebind.mjs";
20
15
  import {
21
16
  assertDryRun,
22
- assertAllowedPolicySimulation,
23
- assertMacosBudgetLaunchGate,
24
17
  assertOwnership,
25
18
  awsArgs,
26
19
  awsJson,
@@ -38,21 +31,7 @@ function flag(name) {
38
31
  return process.argv.includes(`--${name}`);
39
32
  }
40
33
 
41
- function jsonArrayArg(name) {
42
- let parsed;
43
- try {
44
- parsed = JSON.parse(arg(name));
45
- } catch {
46
- throw new Error(`--${name} must be valid JSON`);
47
- }
48
- if (!Array.isArray(parsed)) {
49
- throw new Error(`--${name} must be a JSON array`);
50
- }
51
- return parsed;
52
- }
53
-
54
34
  function assertCampaignLaunchPreflight(plan, profile) {
55
- const launchGate = assertMacosBudgetLaunchGate(plan, profile);
56
35
  const commit = ghJson(
57
36
  ["api", `repos/${plan.repository}/commits/${plan.source.sha}`],
58
37
  undefined,
@@ -61,51 +40,43 @@ function assertCampaignLaunchPreflight(plan, profile) {
61
40
  if (String(commit.sha || "").toLowerCase() !== plan.source.sha) {
62
41
  throw new Error("GitHub did not resolve the exact campaign source SHA");
63
42
  }
64
- const regionalPlans = Object.keys(MACOS_EC2_JIT_REGIONS).map((region) => ({
65
- ...plan,
66
- aws: { ...plan.aws, region },
67
- }));
68
- const activeHosts = regionalPlans.flatMap(
69
- (regionalPlan) =>
70
- awsJson(
71
- regionalPlan,
72
- profile,
73
- [
74
- "ec2",
75
- "describe-hosts",
76
- "--filter",
77
- "Name=tag:kungfu:plane,Values=aws-us-elastic-runner-burst",
78
- "Name=tag:kungfu:provider,Values=macos-ec2-jit",
79
- "Name=state,Values=available,pending,under-assessment",
80
- "--output",
81
- "json",
82
- ],
83
- `active macOS JIT host preflight in ${regionalPlan.aws.region}`,
84
- ).Hosts || [],
85
- );
86
- if (activeHosts.length >= plan.safety.activeHostCeiling) {
87
- throw new Error("macOS JIT active Dedicated Host ceiling is reached");
88
- }
89
- const instances = regionalPlans.flatMap((regionalPlan) => {
90
- const active = awsJson(
91
- regionalPlan,
43
+ const activeHosts =
44
+ awsJson(
45
+ plan,
92
46
  profile,
93
47
  [
94
48
  "ec2",
95
- "describe-instances",
96
- "--filters",
49
+ "describe-hosts",
50
+ "--filter",
97
51
  "Name=tag:kungfu:plane,Values=aws-us-elastic-runner-burst",
98
52
  "Name=tag:kungfu:provider,Values=macos-ec2-jit",
99
- "Name=instance-state-name,Values=pending,running,stopping,stopped,shutting-down",
53
+ "Name=state,Values=available,pending,under-assessment",
100
54
  "--output",
101
55
  "json",
102
56
  ],
103
- `active macOS JIT instance preflight in ${regionalPlan.aws.region}`,
104
- );
105
- return (active.Reservations || []).flatMap(
106
- (reservation) => reservation.Instances || [],
107
- );
108
- });
57
+ "active macOS JIT host preflight",
58
+ ).Hosts || [];
59
+ if (activeHosts.length >= plan.safety.activeHostCeiling) {
60
+ throw new Error("macOS JIT active Dedicated Host ceiling is reached");
61
+ }
62
+ const active = awsJson(
63
+ plan,
64
+ profile,
65
+ [
66
+ "ec2",
67
+ "describe-instances",
68
+ "--filters",
69
+ "Name=tag:kungfu:plane,Values=aws-us-elastic-runner-burst",
70
+ "Name=tag:kungfu:provider,Values=macos-ec2-jit",
71
+ "Name=instance-state-name,Values=pending,running,stopping,stopped,shutting-down",
72
+ "--output",
73
+ "json",
74
+ ],
75
+ "active macOS JIT instance preflight",
76
+ );
77
+ const instances = (active.Reservations || []).flatMap(
78
+ (reservation) => reservation.Instances || [],
79
+ );
109
80
  if (instances.length >= plan.safety.activeInstanceCeiling) {
110
81
  throw new Error("macOS JIT active instance ceiling is reached");
111
82
  }
@@ -149,7 +120,6 @@ function assertCampaignLaunchPreflight(plan, profile) {
149
120
  );
150
121
  }
151
122
  return {
152
- ...launchGate,
153
123
  exactCommit: plan.source.sha,
154
124
  activeHosts: activeHosts.length,
155
125
  activeInstances: instances.length,
@@ -166,11 +136,12 @@ export function executeMacosJitCampaignLaunch(plan, { profile = "" } = {}) {
166
136
  throw new Error("macOS JIT campaign launch plan contract is invalid");
167
137
  }
168
138
  const preflight = assertCampaignLaunchPreflight(plan, profile);
169
- const allocationPermission = assertAllowedPolicySimulation(
170
- plan,
171
- profile,
172
- preflight.principalArn,
173
- "ec2:AllocateHosts",
139
+ assertDryRun(
140
+ commandResult(
141
+ "aws",
142
+ awsArgs(plan, profile, macosAllocateHostsArgs(plan, { dryRun: true })),
143
+ ),
144
+ "EC2 AllocateHosts DryRun",
174
145
  );
175
146
  const hostId = awsJson(
176
147
  plan,
@@ -252,8 +223,8 @@ export function executeMacosJitCampaignLaunch(plan, { profile = "" } = {}) {
252
223
  imageId: instance.ImageId,
253
224
  launchTime: new Date(instance.LaunchTime).toISOString(),
254
225
  },
255
- preflight: { ...preflight, allocationPermission },
256
- dryRuns: ["RunInstances:DryRunOperation"],
226
+ preflight,
227
+ dryRuns: ["AllocateHosts:DryRunOperation", "RunInstances:DryRunOperation"],
257
228
  planDigest: plan.digest,
258
229
  };
259
230
  }
@@ -491,7 +462,6 @@ export function executeMacosJitCampaignClose(plan, { profile = "" } = {}) {
491
462
  function commonValues(execute) {
492
463
  return {
493
464
  execute,
494
- accountId: arg("account-id"),
495
465
  repository: arg("repository", "kungfu-systems/kungfu"),
496
466
  campaignId: arg("campaign-id"),
497
467
  sourceSha: arg("source-sha"),
@@ -508,20 +478,6 @@ function commonValues(execute) {
508
478
  };
509
479
  }
510
480
 
511
- function confirmHistoricalPreflightFailures(plan) {
512
- const confirmed = flag("confirm-historical-preflight-failure-runs-json")
513
- ? jsonArrayArg("confirm-historical-preflight-failure-runs-json")
514
- : [];
515
- if (
516
- JSON.stringify(confirmed) !==
517
- JSON.stringify(plan.github.historicalPreflightFailureRuns)
518
- ) {
519
- throw new Error(
520
- "--confirm-historical-preflight-failure-runs-json must equal the exact historical preflight failure inventory",
521
- );
522
- }
523
- }
524
-
525
481
  function confirm(plan) {
526
482
  if (arg("confirm-source-sha") !== plan.source.sha) {
527
483
  throw new Error("--confirm-source-sha must equal the exact source SHA");
@@ -529,131 +485,6 @@ function confirm(plan) {
529
485
  if (arg("confirm-campaign-id") !== plan.campaign.id) {
530
486
  throw new Error("--confirm-campaign-id must equal the campaign id");
531
487
  }
532
- if (plan.kind === "campaign-source-rebind-plan") {
533
- if (arg("confirm-previous-source-sha") !== plan.previousSource.sha) {
534
- throw new Error(
535
- "--confirm-previous-source-sha must equal previousSourceSha",
536
- );
537
- }
538
- if (arg("confirm-host-id") !== plan.aws.hostId) {
539
- throw new Error("--confirm-host-id must equal the exact host id");
540
- }
541
- if (arg("confirm-instance-id") !== plan.aws.instanceId) {
542
- throw new Error("--confirm-instance-id must equal the exact instance id");
543
- }
544
- if (!flag("confirm-zero-allocation")) {
545
- throw new Error("--confirm-zero-allocation is required");
546
- }
547
- if (plan.github.priorRunPolicy === "terminal-failure") {
548
- const confirmed = jsonArrayArg(
549
- "confirm-terminal-failure-run-ids-json",
550
- ).map(String);
551
- if (
552
- JSON.stringify(confirmed) !==
553
- JSON.stringify(plan.github.terminalFailureRunIds)
554
- ) {
555
- throw new Error(
556
- "--confirm-terminal-failure-run-ids-json must equal the exact failed run inventory",
557
- );
558
- }
559
- const confirmedStartupFailures = flag("confirm-startup-failure-runs-json")
560
- ? jsonArrayArg("confirm-startup-failure-runs-json")
561
- : [];
562
- if (
563
- JSON.stringify(confirmedStartupFailures) !==
564
- JSON.stringify(plan.github.startupFailureRuns)
565
- ) {
566
- throw new Error(
567
- "--confirm-startup-failure-runs-json must equal the exact startup failure inventory",
568
- );
569
- }
570
- const confirmedHistoricalTerminalFailures = flag(
571
- "confirm-historical-terminal-failure-runs-json",
572
- )
573
- ? jsonArrayArg("confirm-historical-terminal-failure-runs-json")
574
- : [];
575
- if (
576
- JSON.stringify(confirmedHistoricalTerminalFailures) !==
577
- JSON.stringify(plan.github.historicalTerminalFailureRuns)
578
- ) {
579
- throw new Error(
580
- "--confirm-historical-terminal-failure-runs-json must equal the exact historical terminal failure inventory",
581
- );
582
- }
583
- const confirmedSuccessfulRuns = flag("confirm-successful-run-ids-json")
584
- ? jsonArrayArg("confirm-successful-run-ids-json").map(String)
585
- : [];
586
- if (
587
- JSON.stringify(confirmedSuccessfulRuns) !==
588
- JSON.stringify(plan.github.successfulRunIds)
589
- ) {
590
- throw new Error(
591
- "--confirm-successful-run-ids-json must equal the exact successful run inventory",
592
- );
593
- }
594
- } else if (plan.github.priorRunPolicy === "preflight-failure") {
595
- const confirmed = jsonArrayArg(
596
- "confirm-preflight-failure-run-ids-json",
597
- ).map(String);
598
- if (
599
- JSON.stringify(confirmed) !==
600
- JSON.stringify(plan.github.preflightFailureRunIds)
601
- ) {
602
- throw new Error(
603
- "--confirm-preflight-failure-run-ids-json must equal the exact preflight failure inventory",
604
- );
605
- }
606
- const confirmedStartupFailures = flag("confirm-startup-failure-runs-json")
607
- ? jsonArrayArg("confirm-startup-failure-runs-json")
608
- : [];
609
- if (
610
- JSON.stringify(confirmedStartupFailures) !==
611
- JSON.stringify(plan.github.startupFailureRuns)
612
- ) {
613
- throw new Error(
614
- "--confirm-startup-failure-runs-json must equal the exact startup failure inventory",
615
- );
616
- }
617
- const confirmedHistoricalTerminalFailures = flag(
618
- "confirm-historical-terminal-failure-runs-json",
619
- )
620
- ? jsonArrayArg("confirm-historical-terminal-failure-runs-json")
621
- : [];
622
- if (
623
- JSON.stringify(confirmedHistoricalTerminalFailures) !==
624
- JSON.stringify(plan.github.historicalTerminalFailureRuns)
625
- ) {
626
- throw new Error(
627
- "--confirm-historical-terminal-failure-runs-json must equal the exact historical terminal failure inventory",
628
- );
629
- }
630
- const confirmedSuccessfulRuns = flag("confirm-successful-run-ids-json")
631
- ? jsonArrayArg("confirm-successful-run-ids-json").map(String)
632
- : [];
633
- if (
634
- JSON.stringify(confirmedSuccessfulRuns) !==
635
- JSON.stringify(plan.github.successfulRunIds)
636
- ) {
637
- throw new Error(
638
- "--confirm-successful-run-ids-json must equal the exact successful run inventory",
639
- );
640
- }
641
- }
642
- confirmHistoricalPreflightFailures(plan);
643
- }
644
- if (plan.kind === "instance-rehydrate-plan") {
645
- if (arg("confirm-host-id") !== plan.aws.hostId) {
646
- throw new Error("--confirm-host-id must equal the exact host id");
647
- }
648
- if (arg("confirm-replaces-instance-id") !== plan.aws.replacesInstanceId) {
649
- throw new Error(
650
- "--confirm-replaces-instance-id must equal replacesInstanceId",
651
- );
652
- }
653
- if (!flag("confirm-no-host-allocation")) {
654
- throw new Error("--confirm-no-host-allocation is required");
655
- }
656
- }
657
488
  }
658
489
 
659
490
  function emit(plan, mode, execute, operation) {
@@ -679,75 +510,6 @@ export function main() {
679
510
  executeMacosJitCampaignLaunch(plan, { profile: arg("aws-profile") }),
680
511
  );
681
512
  }
682
- if (["plan-rehydrate", "rehydrate-instance"].includes(mode)) {
683
- const plan = createMacosJitInstanceRehydratePlan({
684
- ...commonValues(execute),
685
- hostId: arg("host-id"),
686
- hostAllocatedAt: arg("host-allocated-at"),
687
- replacesInstanceId: arg("replaces-instance-id"),
688
- rehydrationId: arg("rehydration-id"),
689
- });
690
- return emit(plan, mode, execute, () =>
691
- executeMacosJitInstanceRehydrate(plan, {
692
- profile: arg("aws-profile"),
693
- }),
694
- );
695
- }
696
- if (
697
- [
698
- "plan-rebind",
699
- "rebind-campaign",
700
- "plan-rebind-after-failure",
701
- "rebind-campaign-after-failure",
702
- "plan-rebind-after-preflight-failure",
703
- "rebind-campaign-after-preflight-failure",
704
- ].includes(mode)
705
- ) {
706
- const afterFailure = mode.endsWith("after-failure");
707
- const afterPreflightFailure = mode.endsWith("after-preflight-failure");
708
- const plan = createMacosJitSourceRebindPlan({
709
- ...commonValues(execute),
710
- previousSourceSha: arg("previous-source-sha"),
711
- previousSourceRef: arg("previous-source-ref"),
712
- workflowId: arg("workflow-id"),
713
- hostId: arg("host-id"),
714
- instanceId: arg("instance-id"),
715
- priorRunPolicy: afterPreflightFailure
716
- ? "preflight-failure"
717
- : afterFailure
718
- ? "terminal-failure"
719
- : "unused",
720
- terminalFailureRunIds: afterFailure
721
- ? jsonArrayArg("terminal-failure-run-ids-json")
722
- : [],
723
- preflightFailureRunIds: afterPreflightFailure
724
- ? jsonArrayArg("preflight-failure-run-ids-json")
725
- : [],
726
- startupFailureRuns:
727
- (afterFailure || afterPreflightFailure) &&
728
- flag("startup-failure-runs-json")
729
- ? jsonArrayArg("startup-failure-runs-json")
730
- : [],
731
- historicalTerminalFailureRuns:
732
- (afterFailure || afterPreflightFailure) &&
733
- flag("historical-terminal-failure-runs-json")
734
- ? jsonArrayArg("historical-terminal-failure-runs-json")
735
- : [],
736
- historicalPreflightFailureRuns:
737
- (afterFailure || afterPreflightFailure) &&
738
- flag("historical-preflight-failure-runs-json")
739
- ? jsonArrayArg("historical-preflight-failure-runs-json")
740
- : [],
741
- successfulRunIds:
742
- (afterFailure || afterPreflightFailure) &&
743
- flag("successful-run-ids-json")
744
- ? jsonArrayArg("successful-run-ids-json")
745
- : [],
746
- });
747
- return emit(plan, mode, execute, () =>
748
- executeMacosJitSourceRebind(plan, { profile: arg("aws-profile") }),
749
- );
750
- }
751
513
  if (["plan-job", "run-job"].includes(mode)) {
752
514
  const plan = createMacosJitJobPlan({
753
515
  ...commonValues(execute),
@@ -2,29 +2,13 @@ import { digest } from "./aws-runner-burst-core.mjs";
2
2
 
3
3
  export const AWS_MACOS_JIT_CONTRACT = "kungfu-buildchain-aws-macos-jit/v1";
4
4
 
5
- export const MACOS_EC2_JIT_REGIONS = Object.freeze({
6
- "us-east-1": Object.freeze({
7
- stack: "kungfu-buildchain-macos-jit",
8
- }),
9
- "us-east-2": Object.freeze({
10
- stack: "kungfu-buildchain-macos-jit-us-east-2",
11
- }),
12
- });
13
-
14
5
  export const MACOS_EC2_JIT = Object.freeze({
15
6
  phase: "macos-ec2-jit",
16
7
  region: "us-east-1",
17
8
  repository: "kungfu-systems/kungfu",
18
- workflowId: "323846928",
19
9
  stack: "kungfu-buildchain-macos-jit",
20
- budgetName: "kungfu-buildchain-macos-jit-actual-spend",
21
- budgetUsageTypes: Object.freeze([
22
- "HostUsage:mac2",
23
- "USE2-HostUsage:mac2",
24
- ]),
25
- budgetOperation: "RunInstances",
26
10
  instanceType: "mac2.metal",
27
- pricePerHourUsd: 0.65,
11
+ pricePerHourUsd: 0.6498,
28
12
  minimumHostAllocationHours: 24,
29
13
  maximumHostAllocationHours: 30,
30
14
  maxAcceptedHosts: 1,
@@ -39,22 +23,6 @@ export const MACOS_EC2_JIT = Object.freeze({
39
23
  jitParameterPrefix: "/kungfu/burst/macos/",
40
24
  });
41
25
 
42
- export function macosJitRegionConfig(region) {
43
- const resolved = String(region || MACOS_EC2_JIT.region).trim();
44
- const config = MACOS_EC2_JIT_REGIONS[resolved];
45
- if (!config) {
46
- throw new Error(
47
- `region must be one of ${Object.keys(MACOS_EC2_JIT_REGIONS).join(", ")}`,
48
- );
49
- }
50
- return {
51
- ...config,
52
- budgetName: MACOS_EC2_JIT.budgetName,
53
- budgetUsageTypes: MACOS_EC2_JIT.budgetUsageTypes,
54
- budgetRegions: Object.keys(MACOS_EC2_JIT_REGIONS),
55
- };
56
- }
57
-
58
26
  function exactSha(value, label) {
59
27
  const normalized = String(value || "")
60
28
  .trim()
@@ -355,14 +323,8 @@ export function verifyMacosEc2JitQualification({
355
323
  }
356
324
  let allocationHours = 0;
357
325
  try {
358
- const allocatedAt = iso(
359
- hostLifecycle.allocatedAt,
360
- "hostLifecycle.allocatedAt",
361
- );
362
- const releasedAt = iso(
363
- hostLifecycle.releasedAt,
364
- "hostLifecycle.releasedAt",
365
- );
326
+ const allocatedAt = iso(hostLifecycle.allocatedAt, "hostLifecycle.allocatedAt");
327
+ const releasedAt = iso(hostLifecycle.releasedAt, "hostLifecycle.releasedAt");
366
328
  allocationHours = elapsedHours(allocatedAt, releasedAt);
367
329
  if (
368
330
  hostLifecycle.status !== "passed" ||
@@ -25,17 +25,6 @@ function writeJson(file, value) {
25
25
  return resolved;
26
26
  }
27
27
 
28
- export function writeMacosJitQualificationEnvironment(
29
- githubEnv = process.env.GITHUB_ENV,
30
- ) {
31
- if (!githubEnv) return false;
32
- fs.appendFileSync(
33
- path.resolve(githubEnv),
34
- "BUILDCHAIN_SIGNING_REQUESTS_ENABLED=false\n",
35
- );
36
- return true;
37
- }
38
-
39
28
  export function main() {
40
29
  const mode = process.argv[2] || "plan";
41
30
  if (mode === "plan") {
@@ -75,7 +64,6 @@ export function main() {
75
64
  ".buildchain/aws-macos-jit.json",
76
65
  result,
77
66
  );
78
- writeMacosJitQualificationEnvironment();
79
67
  process.stdout.write(`${output}\n`);
80
68
  return result;
81
69
  }
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
- import { spawnSync } from "node:child_process";
5
4
  import { pathToFileURL } from "node:url";
5
+ import { spawnSyncCommand } from "../packages/core/spawn-command.js";
6
6
  import {
7
7
  createWindowsJitCampaignArmPlan,
8
8
  windowsCampaignArmItems,
@@ -16,7 +16,7 @@ function arg(name, fallback = "") {
16
16
 
17
17
  function aws(plan, serviceArgs) {
18
18
  const profile = arg("aws-profile");
19
- const result = spawnSync(
19
+ const result = spawnSyncCommand(
20
20
  "aws",
21
21
  [
22
22
  ...(profile ? ["--profile", profile] : []),
@@ -230,7 +230,7 @@ export function windowsRunInstancesArgs(
230
230
  }
231
231
  const resolvedBootstrap = exact(
232
232
  bootstrapPath,
233
- /^(?:<rendered-bootstrap>|\/[^\0]+)$/,
233
+ /^(?:<rendered-bootstrap>|\/[^\0]+|[A-Za-z]:[\\/][^\0]+)$/,
234
234
  "bootstrapPath",
235
235
  );
236
236
  const args = [
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
- import { spawnSync } from "node:child_process";
5
4
  import fs from "node:fs";
6
5
  import os from "node:os";
7
6
  import path from "node:path";
8
7
  import { pathToFileURL } from "node:url";
8
+ import { spawnSyncCommand } from "../packages/core/spawn-command.js";
9
9
  import {
10
10
  AWS_WINDOWS_JIT_CONTROLLER_CONTRACT,
11
11
  createWindowsJitLaunchPlan,
@@ -27,7 +27,7 @@ function flag(name) {
27
27
  }
28
28
 
29
29
  function commandResult(command, args, options = {}) {
30
- const result = spawnSync(command, args, {
30
+ const result = spawnSyncCommand(command, args, {
31
31
  encoding: "utf8",
32
32
  maxBuffer: 16 * 1024 * 1024,
33
33
  stdio: [options.input === undefined ? "ignore" : "pipe", "pipe", "pipe"],
@@ -164,7 +164,7 @@ function assertLivePreflight(plan, profile) {
164
164
  throw new Error("Windows AMI identity or availability mismatch");
165
165
  }
166
166
  return {
167
- budgetGuard: jsonResult(commandResult("/bin/bash", ["scripts/aws-windows-jit-operator.sh", "launch-gate", "--region", plan.aws.region, ...(profile ? ["--aws-profile", profile] : [])]), "provider Budget launch gate"),
167
+ budgetGuard: jsonResult(commandResult("bash", ["scripts/aws-windows-jit-operator.sh", "launch-gate", "--region", plan.aws.region, ...(profile ? ["--aws-profile", profile] : [])]), "provider Budget launch gate"),
168
168
  runStatus: run.status,
169
169
  jobStatus: job.status,
170
170
  activeInstances: activeInstances.length,
@@ -1209,14 +1209,9 @@ export function writeGitHubOutputs(outputs) {
1209
1209
  }
1210
1210
  return;
1211
1211
  }
1212
- const lines = Object.entries(outputs).map(([key, value]) => {
1213
- const text = String(value);
1214
- if (!/[\r\n]/.test(text)) return `${key}=${text}`;
1215
- const valueLines = new Set(text.split(/\r?\n/));
1216
- let delimiter = "BUILDCHAIN_OUTPUT";
1217
- while (valueLines.has(delimiter)) delimiter += "_";
1218
- return `${key}<<${delimiter}\n${text}\n${delimiter}`;
1219
- });
1212
+ const lines = Object.entries(outputs).map(
1213
+ ([key, value]) => `${key}=${value}`,
1214
+ );
1220
1215
  fs.appendFileSync(outputPath, `${lines.join("\n")}\n`);
1221
1216
  }
1222
1217
 
@@ -2,6 +2,7 @@
2
2
  import { spawnSync } from "node:child_process";
3
3
  import crypto from "node:crypto";
4
4
  import fs from "node:fs";
5
+ import os from "node:os";
5
6
  import path from "node:path";
6
7
  import { pathToFileURL } from "node:url";
7
8
  import { createBuildchainLogger } from "../packages/core/logging.js";
@@ -223,16 +224,16 @@ function postjectArgs(binaryPath, blobPath) {
223
224
  return args;
224
225
  }
225
226
 
226
- function buildStandaloneBinaryInTemp({
227
+ export function buildStandaloneBinary({
227
228
  cwd = process.cwd(),
228
229
  outputDir = "dist/binary",
229
230
  name = "buildchain",
230
231
  version = "",
231
232
  packageManagerInstall = false,
232
233
  logPath = undefined,
233
- tempDir,
234
234
  } = {}) {
235
235
  const resolvedOutputDir = path.resolve(cwd, outputDir);
236
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "buildchain-sea-"));
236
237
  const triple = platformTriple();
237
238
  const archiveBase = `${name}-${triple}`;
238
239
  const logger = createBuildchainLogger({
@@ -383,18 +384,6 @@ function buildStandaloneBinaryInTemp({
383
384
  return manifest;
384
385
  }
385
386
 
386
- export function buildStandaloneBinary(options = {}) {
387
- const cwd = path.resolve(options.cwd || process.cwd());
388
- const tempRoot = path.join(cwd, ".buildchain", "tmp");
389
- fs.mkdirSync(tempRoot, { recursive: true });
390
- const tempDir = fs.mkdtempSync(path.join(tempRoot, "sea-"));
391
- try {
392
- return buildStandaloneBinaryInTemp({ ...options, cwd, tempDir });
393
- } finally {
394
- fs.rmSync(tempDir, { recursive: true, force: true });
395
- }
396
- }
397
-
398
387
  if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
399
388
  try {
400
389
  const result = buildStandaloneBinary({
@@ -79,6 +79,7 @@ function selected(channel, major, source, reason) {
79
79
  channel,
80
80
  major,
81
81
  buildchainRef: channel === "alpha" ? `v${major}-alpha` : `v${major}`,
82
+ runtimeOverride: false,
82
83
  selectionSource: source,
83
84
  reason,
84
85
  };
@@ -120,6 +121,7 @@ export function resolveBuildchainChannel({
120
121
  ...lane,
121
122
  major,
122
123
  buildchainRef: explicitRef.ref,
124
+ runtimeOverride: true,
123
125
  selectionSource: "explicit-buildchain-ref+channel-evidence",
124
126
  reason: `trusted runtime override ${explicitRef.ref} bound to ${lane.channel}`,
125
127
  };
@@ -128,6 +130,7 @@ export function resolveBuildchainChannel({
128
130
  channel: explicitRef.kind,
129
131
  major,
130
132
  buildchainRef: explicitRef.ref,
133
+ runtimeOverride: false,
131
134
  selectionSource: "explicit-buildchain-ref",
132
135
  reason: `explicit Buildchain runtime ref ${explicitRef.ref}`,
133
136
  };
@@ -197,6 +200,7 @@ function appendOutputs(file, result) {
197
200
  channel: result.channel,
198
201
  major: String(result.major),
199
202
  "buildchain-ref": result.buildchainRef,
203
+ "runtime-override": String(result.runtimeOverride),
200
204
  "selection-source": result.selectionSource,
201
205
  reason: result.reason,
202
206
  };