@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
@@ -0,0 +1,86 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { execFileSync } from "node:child_process";
4
+ import { installLockedDependencies } from "../locked-dependencies.js";
5
+ import { preparedRuntimeSelection } from "./selection.js";
6
+
7
+ export function activateExecutionRuntime(
8
+ { selection, workspace },
9
+ {
10
+ readCommit = (directory) =>
11
+ execFileSync("git", ["-C", directory, "rev-parse", "HEAD"], {
12
+ encoding: "utf8",
13
+ }).trim(),
14
+ install = installLockedDependencies,
15
+ } = {},
16
+ ) {
17
+ const selected = preparedRuntimeSelection(selection);
18
+ const directory = path.resolve(workspace, ".buildchain/runtime");
19
+ if (readCommit(directory).toLowerCase() !== selected.sha)
20
+ throw new Error(
21
+ "Runtime preparation acquired different bytes than selected",
22
+ );
23
+ const protocol = JSON.parse(
24
+ fs.readFileSync(
25
+ path.join(directory, "architecture/runtime-entry.json"),
26
+ "utf8",
27
+ ),
28
+ );
29
+ if (
30
+ protocol.schema !== "buildchain.runtime-entry/v1" ||
31
+ protocol.protocol !== selected.protocol
32
+ )
33
+ throw new Error(
34
+ "Acquired runtime does not implement the admitted entry protocol",
35
+ );
36
+ const contractFile = path.join(
37
+ directory,
38
+ "dist/site/buildchain-contract.json",
39
+ );
40
+ const contract = JSON.parse(fs.readFileSync(contractFile, "utf8"));
41
+ if (!/^sha256:[0-9a-f]{64}$/u.test(contract.contractDigest || ""))
42
+ throw new Error("Prepared runtime distribution lacks a contract digest");
43
+ if (
44
+ selected.contract?.digest &&
45
+ selected.contract.digest !== contract?.contractDigest
46
+ )
47
+ throw new Error("Selected runtime contract differs from the consumer lock");
48
+ const { nodePath } = install({
49
+ directory,
50
+ production: true,
51
+ ignoreScripts: true,
52
+ });
53
+ return { directory, nodePath, selection: selected, contract };
54
+ }
55
+
56
+ export function activateExecutionRuntimeAction(core, env) {
57
+ const result = activateExecutionRuntime({
58
+ selection: JSON.parse(core.getInput("selection", { required: true })),
59
+ workspace: env.GITHUB_WORKSPACE || process.cwd(),
60
+ });
61
+ // Execution identity is provenance. Only this preparation boundary validates it.
62
+ core.exportVariable("BUILDCHAIN_RUNTIME_ROOT", result.directory);
63
+ core.exportVariable(
64
+ "BUILDCHAIN_CONTRACT_DIGEST",
65
+ result.contract?.contractDigest || "",
66
+ );
67
+ core.exportVariable(
68
+ "BUILDCHAIN_EXECUTION_SOURCE",
69
+ JSON.stringify(result.selection.source || {}),
70
+ );
71
+ core.exportVariable("BUILDCHAIN_RUNTIME_SHA", result.selection.sha);
72
+ core.exportVariable("BUILDCHAIN_RUNTIME_REF", result.selection.ref);
73
+ core.exportVariable("BUILDCHAIN_RUNTIME_CLASS", result.selection.class);
74
+ core.exportVariable("BUILDCHAIN_RUNTIME_ORIGIN", result.selection.origin);
75
+ core.exportVariable(
76
+ "BUILDCHAIN_RUNTIME_OVERRIDE",
77
+ String(result.selection.origin === "runtime-parameter"),
78
+ );
79
+ core.exportVariable(
80
+ "BUILDCHAIN_RUNTIME_SELECTION",
81
+ JSON.stringify(result.selection),
82
+ );
83
+ core.exportVariable("BUILDCHAIN_NODE_PATH", result.nodePath);
84
+ core.setOutput("directory", result.directory);
85
+ core.setOutput("node-path", result.nodePath);
86
+ }
@@ -0,0 +1,55 @@
1
+ export function runtimeEntryProvider(
2
+ github,
3
+ { sourceRepository, sourceSha, actor, eventName },
4
+ ) {
5
+ const parts = (repository) => {
6
+ const [owner, repo] = repository.split("/");
7
+ if (!owner || !repo)
8
+ throw new Error("Runtime entry requires an owner/repository");
9
+ return { owner, repo };
10
+ };
11
+ async function readJson(repository, ref, file, optional = false) {
12
+ try {
13
+ const { data } = await github.rest.repos.getContent({
14
+ ...parts(repository),
15
+ ref,
16
+ path: file,
17
+ });
18
+ if (data.type !== "file" || data.encoding !== "base64")
19
+ throw new Error(`Runtime entry expected a JSON file: ${file}`);
20
+ return JSON.parse(Buffer.from(data.content, "base64").toString("utf8"));
21
+ } catch (error) {
22
+ if (optional && error.status === 404) return undefined;
23
+ throw error;
24
+ }
25
+ }
26
+ return {
27
+ readLock: (file) => readJson(sourceRepository, sourceSha, file, true),
28
+ readRun: async ({ repository, runId }) =>
29
+ (
30
+ await github.rest.actions.getWorkflowRun({
31
+ ...parts(repository),
32
+ run_id: runId,
33
+ })
34
+ ).data,
35
+ resolveRef: async ({ repository, ref }) =>
36
+ (await github.rest.repos.getCommit({ ...parts(repository), ref })).data
37
+ .sha,
38
+ readProtocol: ({ repository, sha }) =>
39
+ readJson(repository, sha, "architecture/runtime-entry.json"),
40
+ authorize: async ({ origin }) => {
41
+ if (origin !== "runtime-parameter") return;
42
+ // GitHub already authorizes workflow_dispatch using repository Actions
43
+ // write permission, including installation tokens without a collaborator.
44
+ if (eventName === "workflow_dispatch") return;
45
+ const { data } = await github.rest.repos.getCollaboratorPermissionLevel({
46
+ ...parts(sourceRepository),
47
+ username: actor,
48
+ });
49
+ if (!["admin", "maintain", "write"].includes(data.permission))
50
+ throw new Error(
51
+ "Transient runtime selection requires repository write permission",
52
+ );
53
+ },
54
+ };
55
+ }
@@ -0,0 +1,37 @@
1
+ export async function resolveRecoverySource(
2
+ { repository, runId, currentRunId, workflow },
3
+ readRun,
4
+ ) {
5
+ if (
6
+ !/^[1-9]\d*$/u.test(String(runId)) ||
7
+ String(runId) === String(currentRunId)
8
+ )
9
+ throw new Error("Recovery requires a different positive workflow run ID");
10
+ const run = await readRun({ repository, runId: Number(runId) });
11
+ if (
12
+ run.repository?.full_name !== repository ||
13
+ run.head_repository?.full_name !== repository
14
+ )
15
+ throw new Error("Recovery cannot cross repository or fork boundaries");
16
+ if (workflow && run.path?.split("@")[0] !== workflow.split("@")[0])
17
+ throw new Error(
18
+ "Recovery must enter through the original consumer workflow",
19
+ );
20
+ if (
21
+ run.status !== "completed" ||
22
+ !["failure", "cancelled", "timed_out", "action_required"].includes(
23
+ run.conclusion,
24
+ )
25
+ )
26
+ throw new Error("Recovery requires a completed unsuccessful execution");
27
+ if (!/^[a-f0-9]{40}$/u.test(run.head_sha || ""))
28
+ throw new Error("Recovery source commit is unavailable");
29
+ return {
30
+ repository,
31
+ sha: run.head_sha,
32
+ ref: run.head_branch || run.head_sha,
33
+ runId: String(run.id),
34
+ attempt: String(run.run_attempt),
35
+ workflow: run.path,
36
+ };
37
+ }
@@ -0,0 +1,110 @@
1
+ const exactSha = /^[a-f0-9]{40}$/iu;
2
+ const repository = "kungfu-systems/buildchain";
3
+ const trainRef =
4
+ /^(?:refs\/(?:heads|tags)\/)?train\/v4\/v4\.\d+\/[a-zA-Z0-9._/-]+$/u;
5
+
6
+ function commit(value, label) {
7
+ if (!exactSha.test(value || ""))
8
+ throw new Error(`${label} must resolve to an exact commit`);
9
+ return value.toLowerCase();
10
+ }
11
+
12
+ export function runtimeSelector({ runtimeRef = "", lock, workflowSha }) {
13
+ if (runtimeRef) {
14
+ if (
15
+ runtimeRef
16
+ .split("/")
17
+ .some((part) => part === ".." || part === "." || part === "")
18
+ )
19
+ throw new Error("Runtime parameter contains an unsafe reference");
20
+ if (
21
+ !exactSha.test(runtimeRef) &&
22
+ !trainRef.test(runtimeRef) &&
23
+ !["v4", "v4-alpha"].includes(runtimeRef)
24
+ )
25
+ throw new Error(
26
+ "Runtime parameter must name an exact commit, channel or train",
27
+ );
28
+ return { ref: runtimeRef, origin: "runtime-parameter" };
29
+ }
30
+ if (lock) {
31
+ if (lock.contract !== "kungfu-buildchain-contract-lock")
32
+ throw new Error("Unsupported Buildchain contract lock");
33
+ const sha = commit(lock.buildchain?.resolvedSha, "Contract lock runtime");
34
+ if (
35
+ lock.schemaVersion !== 1 ||
36
+ !["v4", "v4-alpha"].includes(lock.buildchain.ref) ||
37
+ !/^sha256:[0-9a-f]{64}$/u.test(lock.buildchain.contractDigest || "")
38
+ )
39
+ throw new Error(
40
+ "Contract lock must declare its channel and contract digest",
41
+ );
42
+ return {
43
+ ref: sha,
44
+ origin: "contract-lock",
45
+ };
46
+ }
47
+ return {
48
+ ref: commit(workflowSha, "Workflow default"),
49
+ origin: "workflow-default",
50
+ };
51
+ }
52
+
53
+ export function preparedRuntimeSelection(value) {
54
+ if (
55
+ value?.schema !== "buildchain.runtime-selection/v1" ||
56
+ value.repository !== repository ||
57
+ value.protocol !== 1
58
+ )
59
+ throw new Error("Unsupported runtime selection");
60
+ return { ...value, sha: commit(value.sha, "Selected runtime") };
61
+ }
62
+
63
+ export async function selectExecutionRuntime(
64
+ request,
65
+ { resolveRef, authorize, readProtocol },
66
+ ) {
67
+ const selected = runtimeSelector(request);
68
+ // Authorization belongs to entry selection, never to subsequent business nodes.
69
+ await authorize({ ...selected, repository });
70
+ const sha = exactSha.test(selected.ref)
71
+ ? selected.ref.toLowerCase()
72
+ : commit(
73
+ await resolveRef({ repository, ref: selected.ref }),
74
+ "Runtime reference",
75
+ );
76
+ const protocol = await readProtocol({ repository, sha });
77
+ if (
78
+ protocol?.schema !== "buildchain.runtime-entry/v1" ||
79
+ protocol.protocol !== 1
80
+ )
81
+ throw new Error("Selected runtime does not implement the entry protocol");
82
+ return {
83
+ schema: "buildchain.runtime-selection/v1",
84
+ protocol: 1,
85
+ repository,
86
+ sha,
87
+ ref:
88
+ selected.origin === "contract-lock"
89
+ ? request.lock.buildchain.ref || selected.ref
90
+ : selected.ref,
91
+ origin: selected.origin,
92
+ ...(selected.origin === "contract-lock"
93
+ ? { contract: { digest: request.lock.buildchain.contractDigest } }
94
+ : {}),
95
+ class:
96
+ selected.origin === "contract-lock" &&
97
+ request.lock.buildchain.ref === "v4-alpha"
98
+ ? "alpha"
99
+ : selected.origin === "contract-lock" &&
100
+ request.lock.buildchain.ref === "v4"
101
+ ? "stable"
102
+ : trainRef.test(selected.ref)
103
+ ? "train"
104
+ : selected.ref === "v4-alpha"
105
+ ? "alpha"
106
+ : selected.ref === "v4"
107
+ ? "stable"
108
+ : "exact-sha",
109
+ };
110
+ }
@@ -58,7 +58,7 @@ export function webControllerStages(observations, prepublication = false) {
58
58
  "production-apply",
59
59
  ].map(result);
60
60
  return [
61
- { id: "resolve-runtime", status: result("runtime") },
61
+ { id: "resolve-runtime", status: result("execution-runtime") },
62
62
  { id: "plan", status: result("plan") },
63
63
  { id: "build", status: plan["build-outcome"] || result("plan") },
64
64
  { id: "verify", status: plan["verify-outcome"] || result("plan") },
@@ -2,7 +2,6 @@ import crypto from "node:crypto";
2
2
  import fs from "node:fs";
3
3
  import path from "node:path";
4
4
  import { getOctokit } from "@actions/github";
5
- import { command } from "../runtime/action-process.mjs";
6
5
  import { installationRoot } from "../runtime/installation-root.js";
7
6
  import { finalizeWebController } from "./controller.js";
8
7
  import { assembleWebPublicationAdmission } from "./publication-admission.js";
@@ -15,13 +14,7 @@ export async function sealWebPublicationAction(core, env) {
15
14
  const sourceSha =
16
15
  observations["release-intent"].outputs["production-source-sha"];
17
16
  const runtimeRoot = installationRoot(import.meta.url);
18
- const runtimeSha = command("git", ["-C", runtimeRoot, "rev-parse", "HEAD"], {
19
- stdio: "pipe",
20
- })
21
- .trim()
22
- .toLowerCase();
23
- if (runtimeSha !== observations.runtime.outputs["runtime-sha"])
24
- throw new Error("Web publication runtime changed after admission");
17
+ const runtimeSha = env.BUILDCHAIN_RUNTIME_SHA;
25
18
  const { receipt } = finalizeWebController({
26
19
  workspace: env.GITHUB_WORKSPACE,
27
20
  observations,
@@ -89,7 +89,7 @@ export function createWebSurfacePublicationCandidate({
89
89
  const normalizedRepository = requiredString(repository, "repository");
90
90
  const normalizedSourceSha = normalizeGitSha(sourceSha, "sourceSha");
91
91
  const normalizedSourceTreeSha = normalizeGitSha(sourceTreeSha, "sourceTreeSha");
92
- const normalizedRuntimeSha = normalizeGitSha(runtimeSha, "runtimeSha");
92
+ const normalizedRuntimeSha = runtimeSha;
93
93
  if (plan?.contract !== "kungfu-buildchain-web-surface-deploy-plan") {
94
94
  throw new Error("web-surface publication plan contract mismatch");
95
95
  }
@@ -103,9 +103,6 @@ export function createWebSurfacePublicationCandidate({
103
103
  if (normalizeDigest(plan.manifest?.artifactHash, "plan.manifest.artifactHash") !== artifactHash) {
104
104
  throw new Error("web-surface publication plan artifact hash mismatch");
105
105
  }
106
- if (plan.manifest?.runtimeId && String(plan.manifest.runtimeId).toLowerCase() !== normalizedRuntimeSha) {
107
- throw new Error("web-surface publication plan runtime SHA mismatch");
108
- }
109
106
  const canonicalPlanDigest = crypto
110
107
  .createHash("sha256")
111
108
  .update(`${JSON.stringify(plan, null, 2)}\n`)
@@ -115,7 +112,7 @@ export function createWebSurfacePublicationCandidate({
115
112
  }
116
113
  const controllerValidation = validateControllerReceipt(controllerReceipt, {
117
114
  expectedSourceSha: normalizedSourceSha,
118
- expectedRuntimeSha: normalizedRuntimeSha,
115
+
119
116
  });
120
117
  if (!controllerValidation.ok || !controllerValidation.qualifying) {
121
118
  throw new Error(`web-surface publication controller receipt did not qualify: ${controllerValidation.issues.join("; ")}`);
@@ -1,45 +1,25 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
- import { workflowInstallationRoot } from "../installation.js";
3
+ import { installationRoot } from "../../runtime/installation-root.js";
4
4
  import {
5
5
  inspectUniversalRequest,
6
- admitReviewedWorkflow,
6
+ admitConsumerCapability,
7
7
  } from "./transactions.js";
8
- import { readCandidateReview } from "./review.js";
9
8
  const request = (core) =>
10
9
  JSON.parse(core.getInput("request-json", { required: true }));
11
10
  export function inspectUniversalRequestAction(core) {
12
11
  const outputs = inspectUniversalRequest(
13
12
  request(core),
14
- core.getBooleanInput("recovery"),
15
13
  );
16
14
  for (const [key, value] of Object.entries(outputs))
17
15
  core.setOutput(key, value);
18
16
  }
19
- export function reviewUniversalCandidateAction(core, env) {
20
- const review = readCandidateReview({
17
+ export function admitConsumerCapabilityAction(core, env) {
18
+ const admitted = admitConsumerCapability({
21
19
  request: request(core),
20
+ runtime: JSON.parse(env.BUILDCHAIN_RUNTIME_SELECTION),
22
21
  workspace: env.GITHUB_WORKSPACE,
23
- runtimeRoot: workflowInstallationRoot(import.meta.url),
24
- candidateRoot: path.join(env.GITHUB_WORKSPACE, ".buildchain/candidate"),
25
- token: core.getInput("token", { required: true }),
26
- });
27
- const file = path.join(
28
- env.GITHUB_WORKSPACE,
29
- ".buildchain/review-evidence.json",
30
- );
31
- fs.mkdirSync(path.dirname(file), { recursive: true });
32
- fs.writeFileSync(file, JSON.stringify(review, null, 2) + "\n");
33
- core.setOutput("review-json", JSON.stringify(review));
34
- }
35
- export function admitUniversalCandidateAction(core, env) {
36
- const admitted = admitReviewedWorkflow({
37
- request: request(core),
38
- reviewEvidence: JSON.parse(
39
- core.getInput("review-json", { required: true }),
40
- ),
41
- workspace: env.GITHUB_WORKSPACE,
42
- candidateRoot: path.join(env.GITHUB_WORKSPACE, ".buildchain/candidate"),
22
+ runtimeRoot: installationRoot(import.meta.url),
43
23
  consumer: {
44
24
  repository: env.GITHUB_REPOSITORY,
45
25
  sha: env.GITHUB_SHA,
@@ -1,47 +1,7 @@
1
- import { requireValue } from "../../runtime/action-process.mjs";
1
+ import { assertResultLineage } from "../engine/execution.js";
2
2
  import { completeUniversalWorkflow } from "../universal-workflow-bootstrap.js";
3
3
 
4
- export function recoveryCoordinates(request) {
5
- const candidate = request.candidate;
6
- requireValue(
7
- request.schema === "kungfu-buildchain-v4-universal-workflow-request/v1" &&
8
- request.mode === "train",
9
- "Recovery requires the current Train request envelope",
10
- );
11
- requireValue(
12
- candidate?.repository === "kungfu-systems/buildchain" &&
13
- /^train\/v4\/v4\.\d+\/[A-Za-z0-9][A-Za-z0-9._/-]*$/u.test(
14
- candidate.discoveryRef || "",
15
- ) &&
16
- !candidate.discoveryRef.split("/").includes(".."),
17
- "Recovery requires a Buildchain capability Train",
18
- );
19
- requireValue(
20
- /^[0-9a-f]{40}$/u.test(candidate.expectedSha || "") &&
21
- Number.isSafeInteger(candidate.reviewPullRequest) &&
22
- candidate.reviewPullRequest > 0,
23
- "Recovery requires an exact candidate SHA and review PR",
24
- );
25
- return {
26
- repository: candidate.repository,
27
- ref: candidate.discoveryRef,
28
- sha: candidate.expectedSha,
29
- pr: candidate.reviewPullRequest,
30
- };
31
- }
32
4
  export function recoveryTerminalReceipt(admission, result) {
33
- requireValue(
34
- result.schema === "kungfu-buildchain-v4-universal-workflow-result/v1" &&
35
- ["succeeded", "failed"].includes(result.status) &&
36
- result.requestRoot === admission.requestRoot &&
37
- result.capabilityRoot === admission.capabilityRoot &&
38
- result.runtime?.repository === admission.runtime?.repository &&
39
- result.runtime?.sha === admission.runtime?.sha,
40
- "candidate result does not match the consumer-owned admission lineage",
41
- );
42
- return completeUniversalWorkflow({
43
- admission,
44
- resultRoot: result.resultRoot,
45
- status: result.status,
46
- });
5
+ assertResultLineage(admission, result);
6
+ return completeUniversalWorkflow({ admission, resultRoot: result.resultRoot, status: result.status });
47
7
  }
@@ -1,44 +1,29 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
- import { command } from "../../runtime/action-process.mjs";
4
3
  import {
5
4
  validateUniversalWorkflowRequest,
6
5
  universalWorkflowRequestRoot,
7
6
  admitUniversalWorkflow,
8
7
  } from "../universal-workflow-bootstrap.js";
9
- import { recoveryCoordinates } from "./recovery.js";
10
- export function inspectUniversalRequest(request, recovery = false) {
11
- if (recovery) recoveryCoordinates(request);
8
+ export function inspectUniversalRequest(request) {
12
9
  const value = validateUniversalWorkflowRequest(request);
13
10
  return {
14
- mode: value.mode,
15
- repository: value.candidate.repository,
16
- "discovery-ref": value.candidate.discoveryRef,
17
- "expected-sha": value.candidate.expectedSha,
18
- "review-pr": value.candidate.reviewPullRequest,
19
11
  "capability-id": value.capability.id,
20
12
  "request-root": universalWorkflowRequestRoot(value),
21
13
  };
22
14
  }
23
- export function admitReviewedWorkflow({
15
+ export function admitConsumerCapability({
24
16
  request,
25
- reviewEvidence,
26
17
  workspace,
27
- candidateRoot,
18
+ runtimeRoot,
28
19
  consumer,
20
+ runtime,
29
21
  }) {
30
- const observedSha = command(
31
- "git",
32
- ["-C", candidateRoot, "rev-parse", "HEAD"],
33
- { stdio: "pipe" },
34
- )
35
- .trim()
36
- .toLowerCase();
37
22
  const policy = JSON.parse(
38
23
  fs.readFileSync(
39
24
  path.join(
40
- candidateRoot,
41
- "architecture/universal-workflow-train-admission.json",
25
+ runtimeRoot,
26
+ "architecture/universal-workflow-capability-policy.json",
42
27
  ),
43
28
  "utf8",
44
29
  ),
@@ -46,12 +31,11 @@ export function admitReviewedWorkflow({
46
31
  const admitted = admitUniversalWorkflow({
47
32
  request,
48
33
  policy,
49
- observedRefSha: observedSha,
34
+ runtime,
50
35
  observedConsumerRepository: consumer.repository,
51
36
  observedConsumerSha: consumer.sha,
52
37
  observedConsumerWorkflowRef: consumer.workflowRef,
53
- reviewEvidence,
54
- now: new Date().toISOString(),
38
+ now: new Date().toISOString(),
55
39
  });
56
40
  const file = path.join(workspace, ".buildchain/admission.json");
57
41
  fs.mkdirSync(path.dirname(file), { recursive: true });
@@ -267,7 +267,7 @@ export const BUILDCHAIN_USAGE = `Usage:
267
267
  buildchain paper alpha [--cwd <dir>] [--source-ref <ref>] [--target-ref <ref>]
268
268
  [--execute] [--json]
269
269
  buildchain paper status [--cwd <dir>] [--json]
270
- buildchain paper resume [--cwd <dir>] [--buildchain-ref <ref>] [--execute] [--json]
270
+ buildchain paper resume [--cwd <dir>] [--runtime-ref <ref>] [--execute] [--json]
271
271
  buildchain release-propagation <plan|write-lock|work|entry|pickup> ...
272
272
  buildchain badges readme [--cwd <dir>] [--readme <path>] [--check] [--write] [--json]
273
273
  buildchain badges bundle [--cwd <dir>] [--readme <path>] [--claims <csv>] [--check] [--write] [--json]
@@ -26,8 +26,6 @@ if (command === "inspect") {
26
26
  emit({
27
27
  schema: "kungfu-buildchain-v4-universal-workflow-inspection/v1",
28
28
  requestRoot: universalWorkflowRequestRoot(request),
29
- mode: request.mode,
30
- candidate: request.candidate,
31
29
  consumer: request.consumer,
32
30
  capability: request.capability,
33
31
  });
@@ -36,15 +34,12 @@ if (command === "inspect") {
36
34
  admitUniversalWorkflow({
37
35
  request: readJsonEnvironment("BUILDCHAIN_UNIVERSAL_REQUEST_JSON"),
38
36
  policy: readJsonEnvironment("BUILDCHAIN_UNIVERSAL_ADMISSION_POLICY_JSON"),
39
- observedRefSha: process.env.BUILDCHAIN_UNIVERSAL_OBSERVED_SHA,
37
+ runtime: readJsonEnvironment("BUILDCHAIN_RUNTIME_SELECTION"),
40
38
  observedConsumerRepository:
41
39
  process.env.BUILDCHAIN_UNIVERSAL_CONSUMER_REPOSITORY,
42
40
  observedConsumerSha: process.env.BUILDCHAIN_UNIVERSAL_CONSUMER_SHA,
43
41
  observedConsumerWorkflowRef:
44
42
  process.env.BUILDCHAIN_UNIVERSAL_CONSUMER_WORKFLOW_REF,
45
- reviewEvidence: readJsonEnvironment(
46
- "BUILDCHAIN_UNIVERSAL_REVIEW_EVIDENCE_JSON",
47
- ),
48
43
  now: process.env.BUILDCHAIN_UNIVERSAL_OBSERVED_AT,
49
44
  }),
50
45
  );
@@ -54,7 +49,7 @@ if (command === "inspect") {
54
49
  );
55
50
  const admission = readJsonEnvironment("BUILDCHAIN_UNIVERSAL_ADMISSION_JSON");
56
51
  emit(await executeAdmittedWorkflow(request, admission, {
57
- engineSha: process.env.BUILDCHAIN_UNIVERSAL_ENGINE_SHA, runtimeRoot: installationRoot(import.meta.url),
52
+ runtimeRoot: installationRoot(import.meta.url),
58
53
  ...providerExecutionContext({ token: process.env.GH_TOKEN || process.env.GITHUB_TOKEN || "", mutationToken: process.env.BUILDCHAIN_PROMOTION_TOKEN || "", env: process.env }),
59
54
  }));
60
55
  } else if (command === "terminal") {
@@ -1,7 +1,5 @@
1
1
  import fs from "node:fs";
2
2
  import * as github from "@actions/github";
3
- import { installationRoot } from "../../runtime/installation-root.js";
4
- import { command } from "../../runtime/action-process.mjs";
5
3
  import { readSelfDogfoodReadiness } from "./readiness.js";
6
4
  import {
7
5
  selfDogfoodCoordinates,
@@ -26,24 +24,10 @@ export async function admitSelfDogfoodAction(core, env) {
26
24
  }))
27
25
  core.setOutput(key, value);
28
26
  }
29
- function exactCandidate(sha) {
30
- if (
31
- !/^[0-9a-f]{40}$/.test(sha || "") ||
32
- command(
33
- "git",
34
- ["-C", installationRoot(import.meta.url), "rev-parse", "HEAD"],
35
- { stdio: "pipe" },
36
- ).trim() !== sha
37
- )
38
- throw new Error(
39
- "Self-dogfood must execute the exact independently reviewed candidate",
40
- );
41
- }
42
27
  export function generateSelfDogfoodRequestsAction(core) {
43
28
  const coordinates = JSON.parse(
44
29
  core.getInput("coordinates-json", { required: true }),
45
30
  );
46
- exactCandidate(coordinates["candidate-sha"]);
47
31
  for (const [key, value] of Object.entries(
48
32
  createSelfDogfoodRequests(coordinates),
49
33
  ))
@@ -51,7 +35,6 @@ export function generateSelfDogfoodRequestsAction(core) {
51
35
  }
52
36
  export function reconcileSelfDogfoodAction(core, env) {
53
37
  const candidateSha = core.getInput("candidate-sha", { required: true });
54
- exactCandidate(candidateSha);
55
38
  return reconcileSelfDogfood({
56
39
  workspace: env.GITHUB_WORKSPACE,
57
40
  candidateSha,
@@ -1,6 +1,5 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
- import { command } from "../../runtime/action-process.mjs";
4
3
  import { installationRoot } from "../../runtime/installation-root.js";
5
4
  import { executeAdmittedWorkflow } from "./execution.js";
6
5
  import { providerExecutionContext } from "./provider-context.js";
@@ -18,15 +17,11 @@ export function candidateResultOutputs(value) {
18
17
  }
19
18
  export async function executeCandidateAction(core, env) {
20
19
  const runtimeRoot = installationRoot(import.meta.url);
21
- const engineSha = command("git", ["-C", runtimeRoot, "rev-parse", "HEAD"], {
22
- stdio: "pipe",
23
- }).trim();
24
20
  const result = await executeAdmittedWorkflow(
25
21
  JSON.parse(core.getInput("request-json", { required: true })),
26
22
  JSON.parse(core.getInput("admission-json", { required: true })),
27
23
  {
28
24
  runtimeRoot,
29
- engineSha,
30
25
  ...providerExecutionContext({
31
26
  token: core.getInput("token", { required: true }),
32
27
  mutationToken: core.getInput("mutation-token"),
@@ -37,7 +37,7 @@ export function executeBootstrapConformance(
37
37
  fs.readFileSync(
38
38
  path.join(
39
39
  runtimeRoot,
40
- "architecture/universal-workflow-train-admission.json",
40
+ "architecture/universal-workflow-capability-policy.json",
41
41
  ),
42
42
  ),
43
43
  );
@@ -24,11 +24,6 @@ async function executeCandidate(request, admission, context) {
24
24
  const runtime = exactRuntime(admission);
25
25
  if (universalWorkflowRequestRoot(request) !== admission.requestRoot)
26
26
  fail("candidate request does not match the admitted request root");
27
- const engineSha = String(context.engineSha || "")
28
- .trim()
29
- .toLowerCase();
30
- if (engineSha !== runtime.sha)
31
- fail("candidate engine checkout does not match the admitted runtime SHA");
32
27
  try {
33
28
  return {
34
29
  status: "succeeded",
@@ -65,12 +60,13 @@ export async function executeAdmittedWorkflow(request, admission, context) {
65
60
  }
66
61
 
67
62
  export function assertResultLineage(admission, result) {
63
+ const { resultRoot, ...body } = result || {};
64
+ if (resultRoot !== contentRoot("universal-workflow-result", body)) fail("candidate result root mismatch");
68
65
  if (
69
66
  result?.schema !== "kungfu-buildchain-v4-universal-workflow-result/v1" ||
70
67
  result.requestRoot !== admission.requestRoot ||
71
68
  result.capabilityRoot !== admission.capabilityRoot ||
72
69
  result.runtime?.repository !== admission.runtime?.repository ||
73
- result.runtime?.sha !== admission.runtime?.sha ||
74
70
  !["succeeded", "failed"].includes(result.status)
75
71
  )
76
72
  fail("candidate result does not match the admitted lineage");