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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (255) hide show
  1. package/AGENTS.md +39 -0
  2. package/README.md +17 -13
  3. package/actions/promote-buildchain-ref/README.md +0 -10
  4. package/actions/release-tail/README.md +6 -10
  5. package/architecture/internal-capabilities.json +502 -0
  6. package/architecture/maintainability-baseline.json +59 -0
  7. package/architecture/maintainability-policy.json +1384 -0
  8. package/architecture/release-tail-contract-inventory.json +587 -0
  9. package/architecture/v3-core-mechanism-inventory.json +1043 -0
  10. package/architecture/v3-core-mechanism-inventory.md +67 -0
  11. package/architecture/v4-adopter-delivery-parity.json +47 -0
  12. package/architecture/v4-architecture-constitution.md +210 -0
  13. package/architecture/v4-bootstrap-authority.json +56 -0
  14. package/architecture/v4-canonical-contract-fixtures.json +105 -0
  15. package/architecture/v4-capability-state-machine-manifest.json +480 -0
  16. package/architecture/v4-capability-state-machine-manifest.schema.json +202 -0
  17. package/architecture/v4-delivery-warrant-shadow-bootstrap-plan.json +830 -0
  18. package/architecture/v4-delivery-warrant-shadow-bootstrap-plan.md +223 -0
  19. package/architecture/v4-delivery-warrant-shadow-bootstrap-plan.schema.json +318 -0
  20. package/architecture/v4-delivery-warrant-shadow-fixtures.json +227 -0
  21. package/architecture/v4-delivery-warrant-shadow-fixtures.schema.json +67 -0
  22. package/architecture/v4-exception-ledger.json +5 -0
  23. package/architecture/v4-exception-ledger.schema.json +56 -0
  24. package/architecture/v4-partial-mutation-recovery-qualification.json +65 -0
  25. package/architecture/v4-platform-stage-checkpoints.json +97 -0
  26. package/architecture/v4-provider-operation-journal-contract.json +113 -0
  27. package/architecture/v4-release-activation-shadow-domain.json +61 -0
  28. package/architecture/v4-release-train-parity.json +68 -0
  29. package/architecture/v4-rust-libnode-bridge-evaluation.json +107 -0
  30. package/architecture/v4-rust-libnode-bridge-spike.md +85 -0
  31. package/architecture/v4-stable-publication-fence.json +66 -0
  32. package/architecture/v4-stage-capsule-contract.json +90 -0
  33. package/architecture/v4-stage-capsule-qualification.json +99 -0
  34. package/architecture/v4-stage-capsule-resume-planner.json +52 -0
  35. package/architecture/v4-stage-capsule-store-contract.json +72 -0
  36. package/bin/buildchain.mjs +15 -6
  37. package/contracts/auditable-demo-scenario-v1.schema.json +1 -1
  38. package/contracts/buildchain-v2-residuals-v1.json +2 -2
  39. package/contracts/fixtures/v4-delivery-warrant-trace-v1/golden.json +158 -0
  40. package/contracts/fixtures/v4-delivery-warrant-trace-v1/property.json +380 -0
  41. package/contracts/fixtures/v4-delivery-warrant-trace-v1/replay.json +163 -0
  42. package/contracts/fixtures/v4-partial-mutation-recovery-v1/shared.json +155 -0
  43. package/contracts/fixtures/v4-provider-operation-journal-v1/shared.json +457 -0
  44. package/contracts/fixtures/v4-provider-readback-idempotency-v1/shared.json +682 -0
  45. package/contracts/fixtures/v4-release-activation-shadow-v1/shared.json +53 -0
  46. package/contracts/fixtures/v4-stable-publication-fence-v1/shared.json +56 -0
  47. package/contracts/fixtures/v4-stage-capsule-resume-v1/late-platform-failure.json +176 -0
  48. package/contracts/fixtures/v4-stage-capsule-store-v1/shared.json +132 -0
  49. package/contracts/fixtures/v4-stage-capsule-v1/shared.json +111 -0
  50. package/contracts/v4-canonical-contracts-v1.schema.json +182 -0
  51. package/contracts/v4-delivery-warrant-semantic-diff-report-v1.schema.json +284 -0
  52. package/contracts/v4-delivery-warrant-trace-v1.schema.json +215 -0
  53. package/contracts/v4-host-contract-v1.schema.json +135 -0
  54. package/contracts/v4-partial-mutation-recovery-v1.schema.json +168 -0
  55. package/contracts/v4-provider-operation-journal-v1.schema.json +381 -0
  56. package/contracts/v4-release-activation-shadow-v1.schema.json +186 -0
  57. package/contracts/v4-stable-publication-fence-v1.schema.json +125 -0
  58. package/contracts/v4-stage-capsule-resume-v1.schema.json +225 -0
  59. package/contracts/v4-stage-capsule-store-v1.schema.json +154 -0
  60. package/contracts/v4-stage-capsule-v1.schema.json +178 -0
  61. package/crates/buildchain-v4-bridge/Cargo.lock +213 -0
  62. package/crates/buildchain-v4-bridge/Cargo.toml +12 -0
  63. package/crates/buildchain-v4-bridge/src/main.rs +495 -0
  64. package/dist/site/agent-index.json +0 -3
  65. package/dist/site/artifact-schemas.json +0 -6
  66. package/dist/site/buildchain-contract.json +103 -397
  67. package/dist/site/buildchain-site.json +302 -270
  68. package/dist/site/capability-registry.json +9 -11
  69. package/dist/site/cli-registry.json +8 -30
  70. package/dist/site/controller-registry.json +48 -8
  71. package/dist/site/kfd-claims.json +129 -142
  72. package/dist/site/kfd-upstream-aggregate.json +9 -9
  73. package/dist/site/manual-registry.json +18 -49
  74. package/dist/site/node-api-registry.json +1882 -4118
  75. package/dist/site/page-registry.json +278 -230
  76. package/dist/site/public-surface-audit.json +87 -185
  77. package/dist/site/publication-authority-registry.json +11 -1
  78. package/dist/site/publication-registry.json +4 -4
  79. package/dist/site/release-provenance.json +3 -7
  80. package/dist/site/schemas/kfd-support-projection-v1.schema.json +106 -0
  81. package/dist/site/site-manifest.json +22 -38
  82. package/dist/site/workflow-registry.json +80 -35
  83. package/docs/MAP.md +8 -4
  84. package/docs/auditable-demo.md +2 -2
  85. package/docs/aws-us-elastic-runner-burst-plane.md +7 -59
  86. package/docs/cli-reference.md +15 -92
  87. package/docs/cli.md +14 -14
  88. package/docs/dev-alpha-candidate-patrol.md +3 -11
  89. package/docs/dev-delivery-warrant.md +28 -100
  90. package/docs/engineering-housekeeper.md +12 -4
  91. package/docs/getting-started.md +1 -1
  92. package/docs/install.md +5 -5
  93. package/docs/kfd-support.md +2 -7
  94. package/docs/lifecycle-protocol.md +2 -4
  95. package/docs/node-api-reference.md +414 -523
  96. package/docs/release-flow.md +31 -31
  97. package/docs/release-governance.md +16 -28
  98. package/docs/release-passport.md +2 -15
  99. package/docs/release-tail-contract.md +13 -6
  100. package/docs/release-tail-provider-plane.md +13 -19
  101. package/docs/release-train.md +4 -4
  102. package/docs/reusable-build-surface.md +14 -27
  103. package/docs/site-bundle-contract.md +1 -5
  104. package/docs/stable-candidate-patrol.md +7 -7
  105. package/docs/v4-canonical-contracts.md +92 -0
  106. package/docs/v4-delivery-warrant-read-candidate.md +73 -0
  107. package/docs/v4-delivery-warrant-semantic-diff.md +75 -0
  108. package/docs/v4-production-release.md +63 -0
  109. package/docs/v4-stage-capsule.md +193 -0
  110. package/docs/versioning.md +3 -3
  111. package/package.json +19 -17
  112. package/packages/core/adopter-delivery-gate.js +576 -0
  113. package/packages/core/adopter-delivery-json.js +66 -0
  114. package/packages/core/artifact-signing.js +0 -61
  115. package/packages/core/artifact-verification-envelope.js +5 -5
  116. package/packages/core/build-facts.js +12 -4
  117. package/packages/core/buildchain-agent-manuals.js +0 -2
  118. package/packages/core/buildchain-config.js +4 -69
  119. package/packages/core/buildchain-contract.js +232 -46
  120. package/packages/core/buildchain-kfd-claims.js +1 -1
  121. package/packages/core/channel-candidate.js +0 -8
  122. package/packages/core/channel-promotion-baseline.js +0 -52
  123. package/packages/core/controller-evidence.js +3 -4
  124. package/packages/core/dev-alpha-candidate-selection.js +2 -10
  125. package/packages/core/dev-delivery-warrant-cancellation.js +0 -1
  126. package/packages/core/dev-delivery-warrant-settlement.js +1 -5
  127. package/packages/core/dev-delivery-warrant.js +12 -52
  128. package/packages/core/diagnostics.js +3 -8
  129. package/packages/core/github-governance-authority.js +3 -1
  130. package/packages/core/kfd-adopter-category-driver.js +167 -0
  131. package/packages/core/kfd-adopter-manifest.js +47 -46
  132. package/packages/core/kfd-gate.js +15 -45
  133. package/packages/core/paper-agent-entry.js +7 -16
  134. package/packages/core/paper-fleet.js +2 -2
  135. package/packages/core/paper-repository.js +2 -3
  136. package/packages/core/paper-scaffold-content.js +2 -23
  137. package/packages/core/paper.js +11 -43
  138. package/packages/core/publication-reproducibility.js +4 -4
  139. package/packages/core/release-line-bootstrap.js +21 -8
  140. package/packages/core/release-passport-contract.js +5 -5
  141. package/packages/core/release-passport.js +20 -131
  142. package/packages/core/self-dogfood-version.js +48 -35
  143. package/packages/core/spawn-command.js +232 -8
  144. package/packages/core/v4-adopter-delivery-parity.js +219 -0
  145. package/packages/core/v4-canonical-contracts.js +284 -0
  146. package/packages/core/v4-delivery-warrant-fixture-runner.js +371 -0
  147. package/packages/core/v4-delivery-warrant-read-candidate.js +279 -0
  148. package/packages/core/v4-delivery-warrant-semantic-diff-gate.js +352 -0
  149. package/packages/core/v4-delivery-warrant-shadow-adapter.js +447 -0
  150. package/packages/core/v4-partial-mutation-recovery-qualification.js +395 -0
  151. package/packages/core/v4-platform-stage-checkpoints.js +471 -0
  152. package/packages/core/v4-provider-operation-journal.js +531 -0
  153. package/packages/core/v4-provider-readback-idempotency.js +394 -0
  154. package/packages/core/v4-release-activation-shadow.js +519 -0
  155. package/packages/core/v4-stable-publication-fence.js +357 -0
  156. package/packages/core/v4-stage-capsule-local-store.js +426 -0
  157. package/packages/core/v4-stage-capsule-qualification-campaign.js +512 -0
  158. package/packages/core/v4-stage-capsule-qualification.js +456 -0
  159. package/packages/core/v4-stage-capsule-resume-planner.js +397 -0
  160. package/packages/core/v4-stage-capsule-store.js +401 -0
  161. package/packages/core/v4-stage-capsule.js +319 -0
  162. package/scripts/assemble-self-publication-admission.mjs +1 -1
  163. package/scripts/audit-publication-control-plane.mjs +5 -5
  164. package/scripts/auditable-demo-bundle-verification.mjs +3 -2
  165. package/scripts/auditable-demo-platform.mjs +2 -2
  166. package/scripts/auditable-demo-renditions.mjs +1 -1
  167. package/scripts/auditable-demo.mjs +2 -2
  168. package/scripts/aws-macos-jit-controller-core.mjs +13 -346
  169. package/scripts/aws-macos-jit-controller-runtime.mjs +2 -210
  170. package/scripts/aws-macos-jit-controller.mjs +37 -275
  171. package/scripts/aws-macos-jit-core.mjs +3 -41
  172. package/scripts/aws-macos-jit.mjs +0 -12
  173. package/scripts/aws-windows-jit-campaign.mjs +2 -2
  174. package/scripts/aws-windows-jit-controller-core.mjs +1 -1
  175. package/scripts/aws-windows-jit-controller.mjs +3 -3
  176. package/scripts/build-contract-core.mjs +3 -8
  177. package/scripts/build-standalone-binary.mjs +3 -14
  178. package/scripts/buildchain-channel-router.mjs +4 -0
  179. package/scripts/buildchain-cli-help.mjs +7 -13
  180. package/scripts/buildchain-contract-lock.mjs +0 -6
  181. package/scripts/check-action-bundles.mjs +3 -4
  182. package/scripts/check-internal-architecture.mjs +7 -6
  183. package/scripts/check-inventory.mjs +30 -25
  184. package/scripts/check-v4-public-dogfood-contract.mjs +270 -0
  185. package/scripts/create-release-bundle.mjs +8 -4
  186. package/scripts/dev-alpha-candidate-patrol.mjs +1 -22
  187. package/scripts/dev-delivery-proof.mjs +2 -54
  188. package/scripts/dev-delivery-warrant.mjs +59 -77
  189. package/scripts/dev-pr-auto-merge.mjs +4 -30
  190. package/scripts/dev-pr-delivery-warrant.mjs +0 -55
  191. package/scripts/dispatch-artifact-signing-authority.mjs +7 -4
  192. package/scripts/generate-buildchain-kfd-witnesses.mjs +94 -88
  193. package/scripts/generate-channel-build-workflow.mjs +54 -24
  194. package/scripts/generate-channel-promotion-workflow.mjs +15 -6
  195. package/scripts/generate-site-bundle.mjs +5 -21
  196. package/scripts/git-fetch-process-tree.mjs +34 -1
  197. package/scripts/init-repo.mjs +64 -159
  198. package/scripts/inspect-artifact-signing-requests.mjs +0 -6
  199. package/scripts/locked-source-checkout.mjs +3 -4
  200. package/scripts/maintainability-metrics.mjs +8 -2
  201. package/scripts/npm-publish-dry-run.mjs +2 -2
  202. package/scripts/npm-publish-transaction.mjs +2 -2
  203. package/scripts/publication-commit-evidence.mjs +23 -69
  204. package/scripts/release-candidate-resolver.mjs +11 -17
  205. package/scripts/release-tail.mjs +3 -49
  206. package/scripts/resume-from-candidate-run.mjs +9 -123
  207. package/scripts/run-lifecycle-core.mjs +12 -13
  208. package/scripts/seal-artifact-signing-requests.mjs +17 -21
  209. package/scripts/site-capability-metadata.mjs +2 -7
  210. package/scripts/stable-candidate-qualification.mjs +10 -10
  211. package/scripts/v4-architecture.mjs +12 -2
  212. package/scripts/v4-bridge-bootstrap.mjs +141 -0
  213. package/scripts/v4-bridge-evidence.mjs +141 -0
  214. package/scripts/v4-host-adapter.mjs +182 -0
  215. package/scripts/v4-platform-stage-checkpoint-rehearsal.mjs +207 -0
  216. package/scripts/v4-stage-capsule-qualification.mjs +528 -0
  217. package/scripts/v4-stage-capsule-resume-rehearsal.mjs +57 -0
  218. package/scripts/v4-warrant-shadow-plan.mjs +601 -0
  219. package/scripts/verify-golden-path.mjs +5 -5
  220. package/scripts/web-surface-cloudfront-rewrite.mjs +15 -15
  221. package/scripts/web-surface-core.mjs +2 -8
  222. package/scripts/workflow-call-contract.mjs +5 -184
  223. package/contracts/fixtures/kfd-adopter-release-v1/kfd-4-perspective.json +0 -16
  224. package/contracts/fixtures/kfd-adopter-release-v1/kfd-4-replay.json +0 -57
  225. package/contracts/fixtures/next-development-transition-v1/anchored-manual-waiting.json +0 -47
  226. package/contracts/fixtures/next-development-transition-v1/semver-auto-planned.json +0 -47
  227. package/contracts/fixtures/next-development-transition-v1/version-model-cases.json +0 -40
  228. package/contracts/next-development-request-v1.schema.json +0 -66
  229. package/contracts/next-development-transition-v1.schema.json +0 -292
  230. package/contracts/publication-rehearsal-capsule-v1.schema.json +0 -173
  231. package/dist/site/schemas/publication-rehearsal-capsule-v1.schema.json +0 -269
  232. package/dist/site/schemas/release-tail-capabilities-v1.schema.json +0 -353
  233. package/dist/site/schemas/release-tail-provider-bindings-v1.schema.json +0 -94
  234. package/docs/next-development-transition.md +0 -119
  235. package/docs/publication-rehearsal.md +0 -94
  236. package/packages/core/buildchain-compatibility-proof.js +0 -631
  237. package/packages/core/dev-delivery-native-proof.js +0 -333
  238. package/packages/core/dev-delivery-warrant-shadow.js +0 -502
  239. package/packages/core/next-development-candidate-reservation.js +0 -186
  240. package/packages/core/next-development-controller.js +0 -726
  241. package/packages/core/next-development-projection.js +0 -288
  242. package/packages/core/next-development-transition.js +0 -738
  243. package/packages/core/publication-rehearsal-projection.js +0 -173
  244. package/packages/core/publication-rehearsal-runtime.js +0 -921
  245. package/scripts/aws-macos-jit-instance-rehydrate.mjs +0 -260
  246. package/scripts/aws-macos-jit-source-rebind.mjs +0 -724
  247. package/scripts/dev-delivery-native-run.mjs +0 -187
  248. package/scripts/dev-delivery-two-phase.mjs +0 -598
  249. package/scripts/generate-next-development-guidance.mjs +0 -49
  250. package/scripts/materialize-self-release-candidate-version.mjs +0 -137
  251. package/scripts/next-development-self-dogfood-harness.mjs +0 -409
  252. package/scripts/next-development-self-dogfood.mjs +0 -532
  253. package/scripts/next-development-transition.mjs +0 -47
  254. package/scripts/release-candidate-tail-reseal.mjs +0 -426
  255. package/templates/native-dev-delivery.yml +0 -82
@@ -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
  };