@kungfu-tech/buildchain 4.1.0-alpha.0 → 4.1.0-alpha.2

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 (295) hide show
  1. package/AGENTS.md +30 -41
  2. package/CONTRIBUTING.md +6 -7
  3. package/architecture/action-taxonomy.json +5 -21
  4. package/architecture/agent-change-map.md +74 -56
  5. package/architecture/build-orchestration.json +8 -1
  6. package/architecture/ci-lane-change-budget.json +179 -69
  7. package/architecture/floating-consumer-policy.json +7 -17
  8. package/architecture/internal-capabilities.json +58 -72
  9. package/architecture/maintainability-debt.json +138 -52
  10. package/architecture/maintainability-policy.json +6 -15
  11. package/architecture/promotion-job-topology.json +39 -20
  12. package/architecture/release-topology.json +26 -37
  13. package/architecture/runtime-entry.json +26 -0
  14. package/architecture/runtime-resume-lineage.json +23 -0
  15. package/architecture/stage-capsule-qualification.json +2 -2
  16. package/architecture/universal-workflow-bootstrap.json +10 -25
  17. package/architecture/universal-workflow-capability-policy.json +61 -0
  18. package/architecture/universal-workflow-fault-campaign.json +18 -24
  19. package/architecture/workflow-taxonomy.json +0 -11
  20. package/contracts/fixtures/{v4-runtime-ref-resume-authority-v1 → runtime-resume-lineage-v2}/scenario.json +2 -3
  21. package/contracts/fixtures/v4-floating-consumer-policy-v1/cases.json +2 -2
  22. package/contracts/fixtures/v4-tail-reseal-v1/valid.json +1 -1
  23. package/contracts/promotion-invocation-v1.schema.json +0 -44
  24. package/contracts/promotion-request-v1.schema.json +0 -39
  25. package/contracts/runtime-resume-lineage-v2.schema.json +182 -0
  26. package/dist/site/buildchain-contract.json +472 -361
  27. package/dist/site/buildchain-site.json +99 -99
  28. package/dist/site/capability-registry.json +3 -3
  29. package/dist/site/cli-registry.json +4 -4
  30. package/dist/site/controller-registry.json +94 -78
  31. package/dist/site/kfd-claims.json +224 -343
  32. package/dist/site/kfd-upstream-aggregate.json +1 -1
  33. package/dist/site/manual-registry.json +15 -15
  34. package/dist/site/node-api-registry.json +239 -354
  35. package/dist/site/page-registry.json +80 -80
  36. package/dist/site/public-surface-audit.json +203 -254
  37. package/dist/site/publication-authority-registry.json +1 -24
  38. package/dist/site/publication-registry.json +4 -4
  39. package/dist/site/release-provenance.json +1 -1
  40. package/dist/site/site-manifest.json +19 -19
  41. package/dist/site/workflow-registry.json +197 -357
  42. package/docs/MAP.md +3 -3
  43. package/docs/auditable-demo.md +4 -4
  44. package/docs/cli-reference.md +2 -2
  45. package/docs/code-organization.md +5 -4
  46. package/docs/controller-evidence.md +2 -2
  47. package/docs/dev-alpha-candidate-patrol.md +5 -5
  48. package/docs/dev-delivery-warrant.md +14 -24
  49. package/docs/engineering-housekeeper.md +3 -3
  50. package/docs/github-artifact-attestation.md +9 -12
  51. package/docs/github-governance-authority.md +4 -4
  52. package/docs/node-api-reference.md +153 -167
  53. package/docs/publication-artifacts.md +3 -4
  54. package/docs/publication-authority.md +2 -2
  55. package/docs/release-candidate.md +21 -27
  56. package/docs/release-governance.md +10 -10
  57. package/docs/release-promotion-request.md +11 -18
  58. package/docs/release-propagation.md +5 -6
  59. package/docs/release-tail-provider-plane.md +2 -3
  60. package/docs/reusable-build-surface.md +13 -7
  61. package/docs/runtime-entry.md +122 -0
  62. package/docs/runtime-train-validation.md +30 -41
  63. package/docs/v4-publication-rehearsal.md +5 -5
  64. package/docs/v4-stage-capsule.md +9 -10
  65. package/docs/web-surface-deployments.md +16 -20
  66. package/docs/workflow-catalog.md +0 -1
  67. package/package.json +6 -6
  68. package/packages/core/adoption/commands/init-repo.mjs +2 -2
  69. package/packages/core/adoption/cross-platform-adopter-qualification.js +2 -13
  70. package/packages/core/adoption/qualification/actions.js +3 -5
  71. package/packages/core/adoption/qualification/admission.js +2 -3
  72. package/packages/core/build/artifact/attestation.js +0 -1
  73. package/packages/core/build/artifact/contracts.js +1 -4
  74. package/packages/core/build/artifact/store.js +6 -5
  75. package/packages/core/build/artifact-signing.js +4 -10
  76. package/packages/core/build/binary/actions.js +15 -9
  77. package/packages/core/build/binary-publication-dispatch.js +2 -6
  78. package/packages/core/build/demo/action-context.js +2 -11
  79. package/packages/core/build/demo/binary-action.js +8 -10
  80. package/packages/core/build/gate/controller.js +0 -2
  81. package/packages/core/build/github-attestation/action.js +2 -7
  82. package/packages/core/build/github-attestation/admission.js +0 -8
  83. package/packages/core/build/github-attestation/transaction.js +1 -2
  84. package/packages/core/build/lifecycle/stage-action.js +2 -0
  85. package/packages/core/build/lifecycle/stage.js +6 -3
  86. package/packages/core/build/macos-credential-island/dmg-assembly.js +0 -2
  87. package/packages/core/build/macos-credential-island/lib.js +2 -6
  88. package/packages/core/build/plan/action-context.js +0 -7
  89. package/packages/core/build/plan/action.js +7 -11
  90. package/packages/core/build/plan/admission.js +6 -73
  91. package/packages/core/build/plan/configuration.js +1 -1
  92. package/packages/core/build/plan/environment.js +1 -1
  93. package/packages/core/build/plan/identity.js +1 -5
  94. package/packages/core/build/plan/resolve.js +7 -1
  95. package/packages/core/build/recovery/checkpoint.js +158 -0
  96. package/packages/core/build/recovery/transaction.js +51 -0
  97. package/packages/core/build/signing/authority-actions.js +2 -11
  98. package/packages/core/build/signing/control.js +0 -5
  99. package/packages/core/build/signing/controller-transaction.js +0 -1
  100. package/packages/core/build/signing/delegation.js +2 -4
  101. package/packages/core/build/signing/dispatch.js +10 -56
  102. package/packages/core/build/signing/intake.js +0 -4
  103. package/packages/core/build/signing/prepare.js +1 -1
  104. package/packages/core/build/signing/request.js +3 -8
  105. package/packages/core/build/source/checkout-action.js +6 -10
  106. package/packages/core/build/source/controller.js +1 -4
  107. package/packages/core/build/source/lifecycle.js +3 -13
  108. package/packages/core/build/stage-capsule/actions.js +3 -13
  109. package/packages/core/build/stage-capsule/campaign/resume.js +10 -5
  110. package/packages/core/build/stage-capsule/rehearsal/verify.js +3 -4
  111. package/packages/core/build/stage-capsule-resume-planner.js +0 -1
  112. package/packages/core/build/summary/aggregation.js +5 -5
  113. package/packages/core/build/summary/finalization.js +1 -1
  114. package/packages/core/build/verification/actions.js +3 -12
  115. package/packages/core/build/verification/runner.js +22 -20
  116. package/packages/core/consumer/floating-consumer-evidence.js +3 -21
  117. package/packages/core/consumer/floating-consumer-policy.js +2 -93
  118. package/packages/core/consumer/floating-consumer-release-passport.js +1 -34
  119. package/packages/core/consumer/policy-admission.js +1 -3
  120. package/packages/core/contracts/buildchain-contract.js +12 -146
  121. package/packages/core/contracts/workflow-yaml-contract.js +11 -1
  122. package/packages/core/dev-delivery/candidate/admission.js +3 -4
  123. package/packages/core/dev-delivery/candidate/coordinates.js +0 -8
  124. package/packages/core/dev-delivery/commands/dev-delivery-request.sh +5 -13
  125. package/packages/core/dev-delivery/commands/dev-delivery-source-proof-reuse.mjs +0 -3
  126. package/packages/core/dev-delivery/dev-delivery-contract-surface.js +4 -52
  127. package/packages/core/dev-delivery/dev-delivery-execution-transfer.js +2 -15
  128. package/packages/core/dev-delivery/native/action-context.js +4 -32
  129. package/packages/core/dev-delivery/native/provider-boundary.js +0 -2
  130. package/packages/core/dev-delivery/native/transactions.js +1 -2
  131. package/packages/core/dev-delivery/queue/reconciliation-action.js +6 -10
  132. package/packages/core/dev-delivery/source-proof/predicates.js +0 -6
  133. package/packages/core/dev-delivery/source-proof/reuse.js +0 -2
  134. package/packages/core/dev-delivery/source-proof/seal.js +0 -2
  135. package/packages/core/governance/alpha-candidate/action.js +1 -10
  136. package/packages/core/governance/audit/actions.js +1 -3
  137. package/packages/core/governance/audit/collection.js +1 -3
  138. package/packages/core/governance/audit/identity.js +3 -31
  139. package/packages/core/governance/audit/transactions.js +2 -4
  140. package/packages/core/governance/buildchain-publication-authority.js +0 -1
  141. package/packages/core/governance/commands/audit-github-governance.mjs +3 -2
  142. package/packages/core/governance/github-governance-authority.js +0 -5
  143. package/packages/core/governance/receipt-admission.js +0 -15
  144. package/packages/core/index.js +1 -1
  145. package/packages/core/observability/controller/identity.js +4 -5
  146. package/packages/core/observability/controller-evidence.js +5 -10
  147. package/packages/core/paper/commands/paper.mjs +6 -6
  148. package/packages/core/paper/operations/plans.js +2 -2
  149. package/packages/core/paper/operations/provisioning-validation.js +1 -1
  150. package/packages/core/paper/operations/scaffold-workflows.js +29 -12
  151. package/packages/core/paper/operations/scaffold.js +97 -69
  152. package/packages/core/paper/paper-agent-entry.js +0 -11
  153. package/packages/core/paper/paper-runtime-channels.js +21 -66
  154. package/packages/core/paper/paper-scaffold-content.js +1 -1
  155. package/packages/core/paper/paper.js +9 -5
  156. package/packages/core/paper/publication/candidate.js +0 -9
  157. package/packages/core/paper/publication-controller.js +2 -4
  158. package/packages/core/providers/github/artifact-attestation.js +1 -1
  159. package/packages/core/publication/authority/actions.js +9 -8
  160. package/packages/core/publication/authority/admission.js +0 -11
  161. package/packages/core/publication/authority/assembly.js +2 -7
  162. package/packages/core/publication/authority/control-plane.js +2 -2
  163. package/packages/core/publication/authority/governance.js +2 -9
  164. package/packages/core/publication/authority/request.js +7 -2
  165. package/packages/core/publication/authority/verification.js +3 -18
  166. package/packages/core/publication/binary/action.js +5 -7
  167. package/packages/core/publication/candidate/qualification-action.js +1 -6
  168. package/packages/core/publication/candidate/stage-capsules.js +1 -1
  169. package/packages/core/publication/npm/preview-action.js +9 -15
  170. package/packages/core/publication/oci/preview-actions.js +1 -10
  171. package/packages/core/publication/publication-artifact-candidate.js +2 -2
  172. package/packages/core/publication/publication-authority.js +2 -2
  173. package/packages/core/publication/publication-rehearsal-projection.js +3 -3
  174. package/packages/core/publication/settlement/actions.js +2 -11
  175. package/packages/core/release/binary/coordinates-action.js +0 -13
  176. package/packages/core/release/binary/coordinates.js +2 -19
  177. package/packages/core/release/commands/promotion-channel-router.mjs +12 -56
  178. package/packages/core/release/commands/resume-from-candidate-run.mjs +2 -3
  179. package/packages/core/release/dev-alpha-active-release-train.js +0 -5
  180. package/packages/core/release/line/action.js +2 -13
  181. package/packages/core/release/next-development/actions.js +2 -5
  182. package/packages/core/release/passport/consumer-validation.js +1 -28
  183. package/packages/core/release/promote-candidate/development-source.js +7 -8
  184. package/packages/core/release/promotion/actions.js +7 -38
  185. package/packages/core/release/promotion/admission.js +3 -50
  186. package/packages/core/release/promotion/candidate.js +2 -4
  187. package/packages/core/release/promotion/channel.js +13 -101
  188. package/packages/core/release/promotion/qualification-action.js +2 -13
  189. package/packages/core/release/promotion/routing.js +16 -81
  190. package/packages/core/release/promotion/selection.js +1 -9
  191. package/packages/core/release/promotion-request.js +1 -40
  192. package/packages/core/release/qualification/actions.js +0 -8
  193. package/packages/core/release/qualification/public-build.js +1 -1
  194. package/packages/core/release/recovery/candidate.js +15 -21
  195. package/packages/core/release/recovery/capsules.js +2 -10
  196. package/packages/core/release/recovery/lineage.js +305 -0
  197. package/packages/core/release/recovery/provenance.js +1 -2
  198. package/packages/core/release/recovery/publication.js +4 -14
  199. package/packages/core/release/recovery/readback.js +19 -32
  200. package/packages/core/release/recovery/runtime.js +4 -95
  201. package/packages/core/release/release-candidate-recovery.js +4 -9
  202. package/packages/core/release/release-candidate.js +2 -5
  203. package/packages/core/release/reseal/actions.js +3 -22
  204. package/packages/core/release/reseal/admission.js +0 -2
  205. package/packages/core/release/reseal/finalize-platform.js +0 -2
  206. package/packages/core/release/tail-reseal-github.js +1 -2
  207. package/packages/core/release/tail-reseal-receipt.js +0 -1
  208. package/packages/core/release/tail-reseal.js +2 -20
  209. package/packages/core/release/version-state.js +16 -13
  210. package/packages/core/runtime/buildchain-domain.wasm +0 -0
  211. package/packages/core/runtime/checkout-identity.js +0 -13
  212. package/packages/core/runtime/domain-wasm-artifact.js +2 -2
  213. package/packages/core/runtime/entry/actions.js +121 -0
  214. package/packages/core/runtime/entry/activation.js +86 -0
  215. package/packages/core/runtime/entry/github.js +55 -0
  216. package/packages/core/runtime/entry/recovery.js +37 -0
  217. package/packages/core/runtime/entry/selection.js +110 -0
  218. package/packages/core/web/controller.js +1 -1
  219. package/packages/core/web/publication-admission-action.js +1 -8
  220. package/packages/core/web/web-surface-publication-candidate.js +2 -5
  221. package/packages/core/workflow/admission/actions.js +6 -26
  222. package/packages/core/workflow/admission/recovery.js +3 -43
  223. package/packages/core/workflow/admission/transactions.js +8 -24
  224. package/packages/core/workflow/commands/buildchain-cli-help.mjs +1 -1
  225. package/packages/core/workflow/commands/universal-workflow-engine.mjs +2 -7
  226. package/packages/core/workflow/dogfood/actions.js +0 -17
  227. package/packages/core/workflow/engine/action.js +0 -5
  228. package/packages/core/workflow/engine/conformance.js +1 -1
  229. package/packages/core/workflow/engine/execution.js +2 -6
  230. package/packages/core/workflow/engine/identity.js +1 -6
  231. package/packages/core/workflow/engine/release-environment.js +11 -35
  232. package/packages/core/workflow/engine/release-promotion.js +2 -2
  233. package/packages/core/workflow/settlement/actions.js +0 -12
  234. package/packages/core/workflow/universal-self-dogfood.js +2 -16
  235. package/packages/core/workflow/universal-workflow-bootstrap.js +16 -241
  236. package/packages/core/workflow/workflow-taxonomy.mjs +2 -2
  237. package/scripts/check-dev-delivery-actions.mjs +17 -8
  238. package/scripts/check-floating-consumer-policy-contract.mjs +6 -6
  239. package/scripts/check-inventory.mjs +1 -10
  240. package/scripts/check-public-dogfood-contract.mjs +34 -21
  241. package/scripts/check-release-topology.mjs +2 -6
  242. package/scripts/check-runtime-entry.mjs +133 -0
  243. package/scripts/check-universal-workflow-bootstrap.mjs +45 -281
  244. package/scripts/check-workflows.sh +0 -7
  245. package/scripts/generate-bootstrap-admission.mjs +1 -1
  246. package/scripts/generate-channel-promotion-workflow.mjs +4 -4
  247. package/scripts/inventory/binary.mjs +4 -4
  248. package/scripts/inventory/promotion.mjs +5 -3
  249. package/scripts/runtime-source-boundaries.mjs +70 -0
  250. package/scripts/site-capability-metadata.mjs +2 -2
  251. package/scripts/workflow-action-graph.mjs +5 -18
  252. package/scripts/workflow-self-reference.mjs +20 -0
  253. package/templates/native-dev-delivery.yml +4 -4
  254. package/templates/universal-buildchain-bootstrap.yml +12 -2
  255. package/architecture/runtime-ref-resume-authority.json +0 -64
  256. package/architecture/universal-workflow-train-admission.json +0 -76
  257. package/contracts/v4-runtime-ref-resume-authority-v1.schema.json +0 -235
  258. package/docs/v4-runtime-ref-resume-authority.md +0 -69
  259. package/packages/core/consumer/channel-selection.js +0 -211
  260. package/packages/core/consumer/commands/buildchain-channel-router.mjs +0 -81
  261. package/packages/core/consumer/invocation-selector.js +0 -4
  262. package/packages/core/consumer/runtime-ref-resume-authority.js +0 -621
  263. package/packages/core/consumer/workflow-definition-authority.js +0 -64
  264. package/packages/core/contracts/runtime-contract-action.js +0 -48
  265. package/packages/core/release/commands/promotion-identity-resolver.mjs +0 -77
  266. package/packages/core/release/commands/verify-promotion-router-binding.sh +0 -36
  267. package/packages/core/release/promotion/identities.js +0 -56
  268. package/packages/core/release/runtime-override-authorization.js +0 -242
  269. package/packages/core/runtime/commands/runtime-ref-core.mjs +0 -171
  270. package/packages/core/runtime/provider-closure.js +0 -60
  271. package/packages/core/runtime/runtime-selection-action.js +0 -34
  272. package/packages/core/runtime/runtime-selection.js +0 -136
  273. package/packages/core/runtime/workflow-runtime.js +0 -11
  274. package/packages/core/workflow/admission/review.js +0 -188
  275. package/packages/core/workflow/commands/universal-workflow-backflow.mjs +0 -26
  276. package/packages/core/workflow/installation.js +0 -33
  277. package/packages/core/workflow/settlement/backflow.js +0 -187
  278. package/scripts/generate-bootstrap-recovery.mjs +0 -94
  279. package/templates/bootstrap-recovery/actions/build/source/admit/action.yml +0 -17
  280. package/templates/bootstrap-recovery/actions/build/source/admit/dist/index.js +0 -63
  281. package/templates/bootstrap-recovery/actions/runtime/dependencies/install/action.yml +0 -18
  282. package/templates/bootstrap-recovery/actions/runtime/dependencies/install/dist/index.js +0 -63
  283. package/templates/bootstrap-recovery/actions/runtime/environment/prepare/action.yml +0 -21
  284. package/templates/bootstrap-recovery/actions/workflow/admission/inspect/action.yml +0 -27
  285. package/templates/bootstrap-recovery/actions/workflow/admission/inspect/dist/index.js +0 -64
  286. package/templates/bootstrap-recovery/actions/workflow/admission/review/action.yml +0 -15
  287. package/templates/bootstrap-recovery/actions/workflow/admission/review/dist/index.js +0 -65
  288. package/templates/bootstrap-recovery/actions/workflow/recovery/admit/action.yml +0 -47
  289. package/templates/bootstrap-recovery/actions/workflow/recovery/execute/action.yml +0 -48
  290. package/templates/bootstrap-recovery/actions/workflow/recovery/settle/action.yml +0 -54
  291. package/templates/bootstrap-recovery/actions/workflow/settlement/seal/action.yml +0 -17
  292. package/templates/bootstrap-recovery/actions/workflow/settlement/seal/dist/index.js +0 -65
  293. package/templates/bootstrap-recovery/manifest.json +0 -68
  294. package/templates/bootstrap-recovery/package.json +0 -9
  295. package/templates/universal-buildchain-bootstrap-recovery.yml +0 -115
@@ -1,36 +1,8 @@
1
- import { readOnlyJson } from "./files.js";
2
- import { readPublicResumeState } from "./readback.js";
3
- import { resolveRuntimeResumePublicRuntimeSha } from "./readback.js";
4
1
  import fs from "node:fs";
5
2
  import path from "node:path";
6
- import { execFileSync } from "node:child_process";
7
- import { authorizeRuntimeSelection } from "../../consumer/runtime-ref-resume-authority.js";
8
- import { createRuntimeResumeLineage } from "../../consumer/runtime-ref-resume-authority.js";
9
- import { scanRuntimeSelectorPersistence } from "../../consumer/runtime-ref-resume-authority.js";
10
- import { runtimeResumeDocumentRoot } from "../../consumer/runtime-ref-resume-authority.js";
11
- import { verifyRuntimeAuthorizationReceipt } from "../../consumer/runtime-ref-resume-authority.js";
3
+ import { readPublicResumeState } from "./readback.js";
4
+ import { createRuntimeResumeLineage, runtimeResumeDocumentRoot } from "./lineage.js";
12
5
  import { splitRepository } from "../candidate/selection.js";
13
- import { installationRoot } from "../../runtime/installation-root.js";
14
- export function trackedRuntimePersistenceScan({
15
- runtimeRoot = installationRoot(import.meta.url),
16
- } = {}) {
17
- const paths = execFileSync(
18
- "git",
19
- [
20
- "-C",
21
- runtimeRoot,
22
- "ls-files",
23
- ".github/workflows",
24
- "actions",
25
- ".buildchain",
26
- ],
27
- { encoding: "utf8" },
28
- )
29
- .split(/\r?\n/)
30
- .filter((entry) => /\.(?:json|toml|ya?ml)$/u.test(entry));
31
- return scanRuntimeSelectorPersistence({ root: runtimeRoot, paths });
32
- }
33
-
34
6
  export function prepareRuntimeResumeEvidence({
35
7
  repoInfo,
36
8
  targetRef,
@@ -41,61 +13,9 @@ export function prepareRuntimeResumeEvidence({
41
13
  stageCapsules,
42
14
  recovery,
43
15
  outputDir,
44
- runtimeRoot,
45
16
  recoveryRunId,
46
17
  recoveryRunAttempt,
47
- authorizationPath,
48
- authorizationJson,
49
- authorizationRoot,
50
18
  }) {
51
- const delegatedRaw = String(authorizationJson || "").trim();
52
- const delegatedRoot = String(authorizationRoot || "").trim();
53
- const authorizationFileExists =
54
- authorizationPath && fs.existsSync(authorizationPath);
55
- if (!authorizationFileExists && (!delegatedRaw || !delegatedRoot))
56
- throw new Error(
57
- "cross-runtime recovery requires a fresh runtime authorization receipt",
58
- );
59
- const delegated = authorizationFileExists
60
- ? readOnlyJson(
61
- [{ absolutePath: authorizationPath }],
62
- "runtime authorization",
63
- )
64
- : JSON.parse(delegatedRaw);
65
- if (!authorizationFileExists && delegated.receiptRoot !== delegatedRoot)
66
- throw new Error(
67
- "fresh recovery runtime authorization handoff root mismatch",
68
- );
69
- const delegatedVerification = verifyRuntimeAuthorizationReceipt({
70
- receipt: delegated.receipt,
71
- receiptRoot: delegated.receiptRoot,
72
- repository: repoInfo.fullName,
73
- runtimeSha,
74
- });
75
- if (!delegatedVerification.ok) {
76
- throw new Error(
77
- `fresh recovery runtime authorization rejected: ${delegatedVerification.failures.join(", ")}`,
78
- );
79
- }
80
- const policy = passport.consumerPolicy.receipt;
81
- const authorization = authorizeRuntimeSelection({
82
- repository: repoInfo.fullName,
83
- eventName: "workflow_dispatch",
84
- mode: "resume",
85
- actor: delegated.receipt.actor.login,
86
- actorPermission: delegated.receipt.actor.permission,
87
- reason: `resume sealed candidate run ${passport.workflow.runId} from a tree-equivalent protected source`,
88
- authorizedAt: new Date().toISOString(),
89
- sourceSha: sidecar.source.sha,
90
- sourceTreeSha: sidecar.source.treeSha,
91
- requestedRef: delegated.receipt.request.ref,
92
- resolvedRuntimeSha: runtimeSha,
93
- approvedRefReadbacks: delegated.receipt.runtime.reachableFrom,
94
- stableContractLockRoot: policy.contractLocks.stable.root,
95
- alphaContractLockRoot: policy.contractLocks.alpha.root,
96
- consumerPolicyReceiptRoot: sidecar.consumerPolicyReceiptRoot,
97
- persistenceScan: trackedRuntimePersistenceScan({ runtimeRoot }),
98
- });
99
19
  const planBody = {
100
20
  schemaVersion: 1,
101
21
  contract: "kungfu-buildchain-v4-runtime-resume-plan/v1",
@@ -115,8 +35,6 @@ export function prepareRuntimeResumeEvidence({
115
35
  targetRef,
116
36
  runtimeSha,
117
37
  version,
118
- authorization: authorization.receipt,
119
- authorizationRoot: authorization.receiptRoot,
120
38
  buildAttempt: sidecar.buildAttempt,
121
39
  resumeAttempt: {
122
40
  id: `github-run:${recoveryRunId}:attempt:${recoveryRunAttempt}`,
@@ -127,10 +45,7 @@ export function prepareRuntimeResumeEvidence({
127
45
  requiredPlatforms: stageCapsules.map((entry) => entry.platform),
128
46
  stageCapsules,
129
47
  resumePlanRoot: plan.root,
130
- floatingRefBefore: {
131
- ref: "v4-alpha",
132
- sha: sidecar.buildAttempt.runtimeSha,
133
- },
48
+
134
49
  };
135
50
  const material = {
136
51
  ...materialBody,
@@ -183,7 +98,6 @@ export async function finalizeRuntimeResumeEvidence({
183
98
  const readback = await readPublicResumeState({
184
99
  repoInfo,
185
100
  targetRef,
186
- runtimeSha: resolveRuntimeResumePublicRuntimeSha(material),
187
101
  version,
188
102
  transaction,
189
103
  token,
@@ -191,8 +105,7 @@ export async function finalizeRuntimeResumeEvidence({
191
105
  fetchImpl,
192
106
  });
193
107
  const resumed = createRuntimeResumeLineage({
194
- authorization: material.authorization,
195
- authorizationRoot: material.authorizationRoot,
108
+ repository: material.repository,
196
109
  buildAttempt: material.buildAttempt,
197
110
  resumeAttempt: material.resumeAttempt,
198
111
  source: material.source,
@@ -201,12 +114,8 @@ export async function finalizeRuntimeResumeEvidence({
201
114
  stageCapsules: material.stageCapsules,
202
115
  resumePlanRoot: material.resumePlanRoot,
203
116
  finalPublicReadbackRoot: readback.root,
204
- floatingRefBefore: material.floatingRefBefore,
205
- floatingRefAfter: { ref: "v4-alpha", sha: readback.refs.floating.sha },
206
117
  });
207
118
  const evidence = {
208
- authorization: material.authorization,
209
- authorizationRoot: material.authorizationRoot,
210
119
  lineage: resumed.lineage,
211
120
  lineageRoot: resumed.lineageRoot,
212
121
  };
@@ -282,7 +282,7 @@ function validatePlatformPayloads(passport, artifacts, platformManifests, platfo
282
282
  }
283
283
  }
284
284
 
285
- function validateProductPayloads({ passport, artifacts, productPayloadManifests, candidateRoot, buildSummaryRoot, runtimeSha }) {
285
+ function validateProductPayloads({ passport, artifacts, productPayloadManifests, candidateRoot, buildSummaryRoot }) {
286
286
  const byName = new Map(artifacts.map((artifact) => [artifact.name, artifact]));
287
287
  for (const [index, manifest] of (productPayloadManifests || []).entries()) {
288
288
  if (manifest?.contract !== "kungfu-buildchain-product-payload-manifest/v1") {
@@ -293,7 +293,6 @@ function validateProductPayloads({ passport, artifacts, productPayloadManifests,
293
293
  assertEqual(manifest.candidateRoot, candidateRoot, "candidate-root-mismatch", "product payload candidate root", "Use the product payload sealed for this exact candidate.");
294
294
  assertEqual(manifest.buildSummaryRoot, buildSummaryRoot, "build-summary-root-mismatch", "product payload build summary root", "Use the payload produced from the exact candidate summary.");
295
295
  assertEqual(manifest.source?.tree, passport.source?.treeHash, "source-tree-mismatch", "product payload source tree", "Use payload bytes produced from the exact candidate tree.");
296
- assertEqual(manifest.runtimeSha, runtimeSha, "runtime-mismatch", "product payload candidate runtime", "Use payload evidence created by the candidate runtime.");
297
296
  const artifact = byName.get(manifest.artifactName);
298
297
  if (!artifact) fail("artifact-missing", `product payload artifact is missing: ${manifest.artifactName}`, "Restore the exact product payload artifact.");
299
298
  const manifestName = String(manifest.manifestPath || "product-payload-manifest.json");
@@ -394,7 +393,6 @@ function validateCandidateIdentity({
394
393
  targetSha,
395
394
  targetTree,
396
395
  expectedSourceTree,
397
- expectedRuntimeSha,
398
396
  currentToolingSha,
399
397
  passport,
400
398
  buildSummary,
@@ -402,8 +400,8 @@ function validateCandidateIdentity({
402
400
  }) {
403
401
  const sha = exactSha(targetSha, "targetSha");
404
402
  const tree = exactSha(targetTree, "targetTree");
405
- const runtimeSha = exactSha(expectedRuntimeSha, "expectedRuntimeSha");
406
- const toolingSha = exactSha(currentToolingSha, "currentToolingSha");
403
+ const runtimeSha = passport.buildchain?.sha;
404
+ const toolingSha = currentToolingSha;
407
405
  const validation = validateReleaseCandidatePassport({ passport, repository, targetChannel: anchorProvenance ? "" : channel, buildSummary });
408
406
  if (!validation.ok) fail("passport-invalid", `Release Candidate Passport validation failed: ${validation.errors.join("; ")}`, "Preserve the candidate evidence and explicitly create a new candidate after fixing the producer.");
409
407
  const expectedPassportHash = sha256Json({
@@ -420,7 +418,6 @@ function validateCandidateIdentity({
420
418
  if (passport.candidateHash !== expectedPassportHash) fail("candidate-root-mismatch", "Release Candidate Passport candidate hash does not match its content", "Preserve the run evidence and explicitly create a new candidate after fixing the producer.");
421
419
  assertEqual(passport.source?.treeHash, tree, "source-tree-mismatch", "promotion Git tree", "Select a promotion SHA with the exact candidate Git tree or create a new candidate explicitly.");
422
420
  if (expectedSourceTree) assertEqual(passport.source?.treeHash, exactSha(expectedSourceTree, "expectedSourceTree"), "source-tree-mismatch", "expected source tree", "Correct the expected tree or create a new candidate.");
423
- assertEqual(passport.buildchain?.sha, runtimeSha, "runtime-mismatch", "candidate Buildchain runtime SHA", "Run recovery with the exact trusted Buildchain runtime recorded by the candidate.");
424
421
  return { sha, tree, runtimeSha, toolingSha };
425
422
  }
426
423
 
@@ -454,7 +451,6 @@ export function verifyReleaseCandidateRecovery({
454
451
  targetTree,
455
452
  expectedSourceTree = "",
456
453
  expectedCandidateRoot = "",
457
- expectedRuntimeSha,
458
454
  expectedTransactionId = "",
459
455
  existingTransaction = undefined,
460
456
  run,
@@ -481,7 +477,7 @@ export function verifyReleaseCandidateRecovery({
481
477
  });
482
478
  const { sha, tree, runtimeSha, toolingSha } = validateCandidateIdentity({
483
479
  repository, channel, targetSha, targetTree, expectedSourceTree,
484
- expectedRuntimeSha, currentToolingSha, passport, buildSummary, anchorProvenance,
480
+ currentToolingSha, passport, buildSummary, anchorProvenance,
485
481
  });
486
482
 
487
483
  const recoveredArtifacts = artifacts.map(normalizeArtifact).sort((left, right) => left.name.localeCompare(right.name));
@@ -495,7 +491,6 @@ export function verifyReleaseCandidateRecovery({
495
491
  for (const receipt of controllerReceipts) {
496
492
  const receiptValidation = validateControllerReceipt(receipt, {
497
493
  expectedSourceSha: passport.source?.headSha,
498
- expectedRuntimeSha: runtimeSha,
499
494
  });
500
495
  if (!receiptValidation.ok || !receiptValidation.qualifying) {
501
496
  fail("controller-receipt-invalid", `controller receipt is not qualifying: ${receiptValidation.issues.join("; ")}`, "Use a successful candidate with complete controller evidence.");
@@ -189,7 +189,6 @@ function normalizeConsumerPolicyEvidence(value, expected = {}) {
189
189
  receiptRoot: value.receiptRoot || "",
190
190
  repository: expected.repository,
191
191
  sourceSha: expected.sourceSha,
192
- resolvedRuntimeSha: expected.runtimeSha,
193
192
  });
194
193
  if (!verification.ok) {
195
194
  throw new Error(`consumer policy receipt invalid: ${verification.failures.map((failure) => failure.code).join(", ")}`);
@@ -215,7 +214,6 @@ function validateConsumerPolicyEvidence(passport, check) {
215
214
  }
216
215
 
217
216
  function validateEvidenceBoundCandidateHash(passport, check) {
218
- if (!passport.familyEvidence && !passport.consumerPolicy) return;
219
217
  const expectedCandidateHash = sha256Json({
220
218
  repository: passport.repository,
221
219
  target: passport.target,
@@ -404,7 +402,6 @@ export function createReleaseCandidatePassport({
404
402
  const normalizedConsumerPolicy = normalizeConsumerPolicyEvidence(consumerPolicyReceipt, {
405
403
  repository: repository || normalizedSummary.git?.repository || "",
406
404
  sourceSha: normalizedSummary.publishSource?.ref === "publish-gate/anchor" ? (consumerPolicyReceipt?.receipt || consumerPolicyReceipt)?.caller?.sourceSha : sourceSha,
407
- runtimeSha: resolvedBuildchain.sha,
408
405
  });
409
406
  if (isBuildchainRuntime(resolvedBuildchain) && !normalizedConsumerPolicy) {
410
407
  throw new Error("Buildchain v4 release candidate passport requires a valid floating consumer policy receipt");
@@ -413,7 +410,7 @@ export function createReleaseCandidatePassport({
413
410
  receipts: controllerReceipts,
414
411
  references: controllerReceiptReferences,
415
412
  expectedSourceSha: sourceSha,
416
- expectedRuntimeSha: optionalString(buildchain.sha || normalizedSummary.runtime?.sha),
413
+
417
414
  requirePassed: true,
418
415
  });
419
416
  const candidate = {
@@ -578,7 +575,7 @@ export function validateReleaseCandidatePassport({
578
575
  for (const [index, reference] of (passport.controllerReceipts || []).entries()) {
579
576
  const validation = validateControllerReceiptReference(reference, {
580
577
  expectedSourceSha: passport.source?.headSha || "",
581
- expectedRuntimeSha: passport.buildchain?.sha || "",
578
+
582
579
  requirePassed: true,
583
580
  });
584
581
  for (const issue of validation.issues) check(false, `controllerReceipts[${index}]: ${issue}`);
@@ -1,28 +1,9 @@
1
1
  import path from "node:path";
2
2
  import { getOctokit } from "@actions/github";
3
- import { command } from "../../runtime/action-process.mjs";
4
- import { installationRoot } from "../../runtime/installation-root.js";
5
- import { exactWorkflowRuntime } from "../../runtime/workflow-runtime.js";
6
3
  import { admitTailResealPlan } from "./plan.js";
7
4
  import { finalizeResealPlatform } from "./finalize-platform.js";
8
5
  import { sealTailReseal } from "./seal.js";
9
6
  import { tailPlanOutputs } from "./outputs.js";
10
- function runtime(core) {
11
- const sha = exactWorkflowRuntime(
12
- core.getInput("runtime-sha", { required: true }),
13
- );
14
- if (
15
- command(
16
- "git",
17
- ["-C", installationRoot(import.meta.url), "rev-parse", "HEAD"],
18
- { stdio: "pipe" },
19
- ).trim() !== sha
20
- )
21
- throw new Error(
22
- "Tail action runtime differs from admitted immutable commit",
23
- );
24
- return sha;
25
- }
26
7
  export async function admitTailResealPlanAction(core, env) {
27
8
  const request = JSON.parse(core.getInput("request-json", { required: true }));
28
9
  const result = await admitTailResealPlan(
@@ -30,7 +11,7 @@ export async function admitTailResealPlanAction(core, env) {
30
11
  request: JSON.parse(request["request-json"]),
31
12
  receipt: JSON.parse(request["consumer-policy-receipt-json"]),
32
13
  workspace: path.resolve(env.GITHUB_WORKSPACE),
33
- runtimeSha: runtime(core),
14
+ runtimeSha: env.BUILDCHAIN_RUNTIME_SHA,
34
15
  sourceSha: env.GITHUB_SHA,
35
16
  repository: env.GITHUB_REPOSITORY,
36
17
  },
@@ -49,7 +30,7 @@ export async function admitTailResealPlanAction(core, env) {
49
30
  export function finalizeResealPlatformAction(core, env) {
50
31
  return finalizeResealPlatform({
51
32
  workspace: path.resolve(env.GITHUB_WORKSPACE),
52
- runtimeSha: runtime(core),
33
+ runtimeSha: env.BUILDCHAIN_RUNTIME_SHA,
53
34
  platformId: core.getInput("platform", { required: true }),
54
35
  finalizationCommand: core.getInput("finalization-command"),
55
36
  signingToken: core.getInput("signing-token"),
@@ -61,7 +42,7 @@ export function finalizeResealPlatformAction(core, env) {
61
42
  export function sealTailResealAction(core, env) {
62
43
  const { passport, receipt } = sealTailReseal({
63
44
  workspace: path.resolve(env.GITHUB_WORKSPACE),
64
- runtimeSha: runtime(core),
45
+ runtimeSha: env.BUILDCHAIN_RUNTIME_SHA,
65
46
  sourceSha: env.GITHUB_SHA,
66
47
  sourceRef: env.GITHUB_REF,
67
48
  repository: env.GITHUB_REPOSITORY,
@@ -6,8 +6,6 @@ export function verifyTailPolicyBindings({
6
6
  runtimeSha,
7
7
  sourceSha,
8
8
  }) {
9
- if (request.runtime.sha !== runtimeSha)
10
- throw new Error("Tail runtime differs from job.workflow_sha");
11
9
  if (request.source.sha !== sourceSha)
12
10
  throw new Error("Tail source differs from the fresh workflow source");
13
11
  const result = verifyFloatingConsumerPolicyReceipt({
@@ -17,8 +17,6 @@ export async function finalizeResealPlatform({
17
17
  const request = normalizeTailResealRequest(
18
18
  readJson(path.join(directory, "request.json")),
19
19
  );
20
- if (request.runtime.sha !== runtimeSha)
21
- throw new Error("Reseal platform runtime differs from admitted request");
22
20
  let readback = verifyTailResealPlatform({
23
21
  request,
24
22
  platformId,
@@ -122,8 +122,7 @@ function validateSigningAuthority(normalized, signingRun, signingArtifacts) {
122
122
  if (
123
123
  Number(signingRun?.id) !== normalized.signing.authorityRunId ||
124
124
  signingRun?.status !== "completed" ||
125
- signingRun?.conclusion !== "success" ||
126
- signingRun?.head_sha !== normalized.signing.runtimeSha
125
+ signingRun?.conclusion !== "success"
127
126
  )
128
127
  fault(
129
128
  "tail-reseal-signer-authority-mismatch",
@@ -157,7 +157,6 @@ export function createTailResealReceipt({
157
157
  );
158
158
  if (
159
159
  passport.contract !== "kungfu-buildchain-release-candidate-passport" ||
160
- passport.buildchain?.sha !== normalized.runtime.sha ||
161
160
  passport.consumerPolicy?.receiptRoot !==
162
161
  normalized.runtime.consumerPolicyReceiptRoot
163
162
  )
@@ -177,19 +177,7 @@ function validateRuntime(value) {
177
177
  ["repository", "ref", "sha", "contractRoot", "consumerPolicyReceiptRoot"],
178
178
  "$/runtime",
179
179
  );
180
- if (value.repository !== "kungfu-systems/buildchain")
181
- fault(
182
- "tail-reseal-runtime-mismatch",
183
- "$/runtime/repository",
184
- "official Buildchain runtime required",
185
- );
186
- if (!DOMAIN_RUNTIME_REF.test(value.ref))
187
- fault(
188
- "tail-reseal-runtime-mismatch",
189
- "$/runtime/ref",
190
- "v4-alpha or a transient v4 train is required",
191
- );
192
- sha(value.sha, "$/runtime/sha");
180
+
193
181
  root(value.contractRoot, "$/runtime/contractRoot");
194
182
  root(value.consumerPolicyReceiptRoot, "$/runtime/consumerPolicyReceiptRoot");
195
183
  }
@@ -342,7 +330,6 @@ function validateSigning(value, evaluatedAt) {
342
330
  );
343
331
  text(value.authorityRepository, "$/signing/authorityRepository");
344
332
  positiveInteger(value.authorityRunId, "$/signing/authorityRunId");
345
- sha(value.runtimeSha, "$/signing/runtimeSha");
346
333
  for (const field of [
347
334
  "requestRoot",
348
335
  "delegationRoot",
@@ -495,12 +482,7 @@ export function normalizeTailResealRequest(request) {
495
482
  validateSigning(request.signing, request.evaluatedAt);
496
483
  validateReleaseTail(request.releaseTail);
497
484
  validatePlatforms(request.platforms);
498
- if (request.signing.runtimeSha !== request.runtime.sha)
499
- fault(
500
- "tail-reseal-signing-runtime-mismatch",
501
- "$/signing/runtimeSha",
502
- "signing authority runtime differs from candidate runtime",
503
- );
485
+
504
486
  const capsuleRoots = new Map(
505
487
  request.platforms.map((platform) => [platform.id, platform.capsuleRoot]),
506
488
  );
@@ -236,6 +236,10 @@ function createTreeEquivalentReleaseImpact({
236
236
  }
237
237
 
238
238
  function assertAllowedLocalChanges(cwd, allowedPaths) {
239
+ const dependencies = fs.lstatSync(path.join(cwd, "node_modules"), { throwIfNoEntry: false });
240
+ if (dependencies?.isSymbolicLink()) {
241
+ throw new Error("Unexpected local changes: ?? node_modules (dependency bridge)");
242
+ }
239
243
  const allowed = new Set(allowedPaths);
240
244
  const output = execSync("git status --porcelain --untracked-files=all", {
241
245
  cwd,
@@ -266,14 +270,6 @@ function assertAllowedLocalChanges(cwd, allowedPaths) {
266
270
  ? filePath.startsWith(allowedPath)
267
271
  : filePath === allowedPath,
268
272
  );
269
- const runtimeBridgePath = path.join(cwd, "node_modules");
270
- let runtimeBridgePresent = false;
271
- let isExactRuntimeBridge = false;
272
- try {
273
- runtimeBridgePresent = Boolean(fs.lstatSync(runtimeBridgePath));
274
- isExactRuntimeBridge = fs.realpathSync(runtimeBridgePath) ===
275
- fs.realpathSync(path.resolve(cwd, ".buildchain/runtime/node_modules"));
276
- } catch { /* Missing paths are not the exact runtime bridge. */ }
277
273
  const unexpected = output
278
274
  .split(/\r?\n/)
279
275
  .filter(Boolean)
@@ -281,13 +277,8 @@ function assertAllowedLocalChanges(cwd, allowedPaths) {
281
277
  const status = line.slice(0, 2);
282
278
  const filePath = line.slice(3).trim();
283
279
  if (isEphemeralBuildchainEvidence(status, filePath)) return false;
284
- if (status === "??" && filePath === "node_modules" && isExactRuntimeBridge) return false;
285
280
  return !(allowed.has(filePath) && status !== "??" && !status.includes("D"));
286
281
  });
287
- if (runtimeBridgePresent && !isExactRuntimeBridge &&
288
- !unexpected.includes("?? node_modules")) {
289
- unexpected.push("?? node_modules");
290
- }
291
282
  if (unexpected.length) throw new Error(`Unexpected version changes: ${unexpected.join(", ")}`);
292
283
  }
293
284
 
@@ -338,6 +329,18 @@ function runVersionVerification({
338
329
  if (!command && (!runLifecycleVerify || !lifecycleVerify) && !lifecycleVersionState) {
339
330
  return changedFiles;
340
331
  }
332
+ const lifecycleInstall = getLifecycleStage(loadedConfig, "install");
333
+ if (lifecycleVersionState && lifecycleInstall) {
334
+ // Source generators own their dependencies. Install against the original
335
+ // manifests before materializing the next version, independently of runtime X.
336
+ runLifecycleStage({
337
+ cwd,
338
+ loadedConfig,
339
+ name: "install",
340
+ stage: lifecycleInstall,
341
+ env: extraEnv,
342
+ });
343
+ }
341
344
  applyLocalVersionState(cwd, changedFiles);
342
345
  const lifecycleEnv = { BUILDCHAIN_VERSION: version, ...(extraEnv || {}) };
343
346
  if (lifecycleVersionState) {
@@ -12,16 +12,3 @@ export function verifyCheckoutIdentity(
12
12
  throw new Error(`${label} does not match the checked-out commit`);
13
13
  return actual;
14
14
  }
15
- export function verifySourceRuntimeCheckouts(
16
- { sourceDirectory, sourceSha, runtimeDirectory, runtimeSha },
17
- execute = command,
18
- ) {
19
- verifyCheckoutIdentity(
20
- { directory: runtimeDirectory, sha: runtimeSha, label: "Runtime" },
21
- execute,
22
- );
23
- verifyCheckoutIdentity(
24
- { directory: sourceDirectory, sha: sourceSha, label: "Source" },
25
- execute,
26
- );
27
- }
@@ -2,6 +2,6 @@
2
2
  export const DOMAIN_WASM_ABI_VERSION = 1;
3
3
  export const DOMAIN_WASM_RUSTC = "rustc 1.96.0 (ac68faa20 2026-05-25)";
4
4
  export const DOMAIN_WASM_SOURCE_SHA256 =
5
- "4434517a11caafc878c3829922144f68923d661f9f2f13d4b6e4734d9e62775c";
5
+ "83550684878224e6820594a44fc48f805c5ed1b3182ac32ebeb51b74cfd20a7f";
6
6
  export const DOMAIN_WASM_SHA256 =
7
- "d1b4a91dfb0bee972b0460fc22d784840226b9bc116de44c823f6d504465aebb";
7
+ "504e23c9241f43611813f0fbd213b7a694946328b00e23d22f6ba678e7b0c841";
@@ -0,0 +1,121 @@
1
+ import { resolveRecoverySource } from "./recovery.js";
2
+ import { getOctokit } from "@actions/github";
3
+ import { runtimeEntryProvider } from "./github.js";
4
+ import {
5
+ preparedRuntimeSelection,
6
+ selectExecutionRuntime,
7
+ } from "./selection.js";
8
+
9
+ export async function selectExecutionRuntimeAction(
10
+ core,
11
+ env,
12
+ { providerFactory = runtimeEntryProvider, githubFactory = getOctokit } = {},
13
+ ) {
14
+ const retained = core.getInput("selection");
15
+ const transport = retained
16
+ ? preparedRuntimeSelection(JSON.parse(retained))
17
+ : undefined;
18
+ const github = githubFactory(core.getInput("token", { required: true }));
19
+ let source = {
20
+ repository: core.getInput("source-repository") || env.GITHUB_REPOSITORY,
21
+ sha: core.getInput("source-sha") || env.GITHUB_SHA,
22
+ ref: env.GITHUB_REF,
23
+ };
24
+ const resumeRunId = core.getInput("resume-run-id");
25
+ if (resumeRunId) {
26
+ const reader = providerFactory(github, {
27
+ sourceRepository: source.repository,
28
+ sourceSha: source.sha,
29
+ actor: env.GITHUB_ACTOR,
30
+ eventName: env.GITHUB_EVENT_NAME,
31
+ });
32
+ await reader.authorize({ origin: "runtime-parameter" });
33
+ source = await resolveRecoverySource(
34
+ {
35
+ repository: source.repository,
36
+ runId: resumeRunId,
37
+ currentRunId: env.GITHUB_RUN_ID,
38
+ workflow: env.GITHUB_WORKFLOW_REF?.slice(source.repository.length + 1),
39
+ },
40
+ reader.readRun,
41
+ );
42
+ }
43
+ const provider = providerFactory(github, {
44
+ sourceRepository: source.repository,
45
+ sourceSha: source.sha,
46
+ actor: env.GITHUB_ACTOR,
47
+ eventName: env.GITHUB_EVENT_NAME,
48
+ });
49
+ const workflowSha = core.getInput("workflow-sha", { required: true });
50
+ const workflowRef = core.getInput("workflow-ref", { required: true });
51
+ const lockPath =
52
+ core.getInput("contract-lock") ||
53
+ transport?.contract?.path ||
54
+ (/@(?:refs\/tags\/)?v4-alpha$/u.test(workflowRef)
55
+ ? ".buildchain/alpha-contract-lock.json"
56
+ : ".buildchain/contract-lock.json");
57
+ if (
58
+ lockPath.startsWith("/") ||
59
+ lockPath.includes("\\") ||
60
+ lockPath.split("/").some((part) => !part || part === "." || part === "..")
61
+ )
62
+ throw new Error(
63
+ "Contract lock path must be relative to the consumer repository",
64
+ );
65
+ const runtimeRef = core.getInput("runtime-ref");
66
+ let selection;
67
+ if (retained) {
68
+ if (runtimeRef || resumeRunId)
69
+ throw new Error(
70
+ "Retained selection cannot be combined with a new runtime or recovery request",
71
+ );
72
+ selection = transport;
73
+ if (selection.origin === "runtime-parameter")
74
+ await provider.authorize({ origin: "runtime-parameter" });
75
+ if (selection.source?.runId) {
76
+ await provider.authorize({ origin: "runtime-parameter" });
77
+ source = await resolveRecoverySource(
78
+ {
79
+ repository: source.repository,
80
+ runId: selection.source.runId,
81
+ currentRunId: env.GITHUB_RUN_ID,
82
+ workflow: env.GITHUB_WORKFLOW_REF?.slice(
83
+ source.repository.length + 1,
84
+ ),
85
+ },
86
+ provider.readRun,
87
+ );
88
+ }
89
+ if (
90
+ selection.source?.repository !== source.repository ||
91
+ selection.source?.sha !== source.sha
92
+ )
93
+ throw new Error("Runtime transport changed the admitted consumer source");
94
+ } else {
95
+ selection = await selectExecutionRuntime(
96
+ {
97
+ workflowSha: core.getInput("workflow-sha", { required: true }),
98
+ runtimeRef,
99
+ lock: runtimeRef ? undefined : await provider.readLock(lockPath),
100
+ },
101
+ provider,
102
+ );
103
+ }
104
+ selection = {
105
+ ...selection,
106
+ source,
107
+ contract: {
108
+ ...selection.contract,
109
+ path: selection.contract?.path || lockPath,
110
+ },
111
+ };
112
+ core.setOutput("selection", selection);
113
+ core.setOutput("source-sha", selection.source.sha);
114
+ core.setOutput("source-ref", selection.source.ref);
115
+ core.setOutput("repository", selection.repository);
116
+ core.setOutput("sha", selection.sha);
117
+ core.setOutput("ref", selection.ref);
118
+ core.setOutput("class", selection.class);
119
+ core.setOutput("origin", selection.origin);
120
+ core.setOutput("override", String(selection.origin === "runtime-parameter"));
121
+ }