@kungfu-tech/buildchain 4.0.2-alpha.9 → 4.0.3-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (281) hide show
  1. package/AGENTS.md +14 -5
  2. package/CONTRIBUTING.md +58 -0
  3. package/README.md +3 -3
  4. package/actions/promote-buildchain-ref/README.md +1 -1
  5. package/actions/release-candidate-promote/README.md +31 -0
  6. package/architecture/agent-change-map.md +190 -126
  7. package/architecture/{v4-architecture-constitution.md → architecture-constitution.md} +33 -30
  8. package/architecture/{v3-core-mechanism-inventory.md → baseline-core-mechanism-inventory.md} +1 -1
  9. package/architecture/{v4-bootstrap-authority.json → bootstrap-authority.json} +3 -3
  10. package/architecture/{v3-v4-capability-closure.md → capability-parity-closure.md} +3 -3
  11. package/architecture/{v3-v4-live-capability-inventory.json → capability-parity-live-capability-inventory.json} +4 -4
  12. package/architecture/{v4-capability-state-machine-manifest.json → capability-state-machine-manifest.json} +2 -2
  13. package/architecture/{v4-capability-state-machine-manifest.schema.json → capability-state-machine-manifest.schema.json} +2 -2
  14. package/architecture/ci-lane-change-budget.json +384 -0
  15. package/architecture/{v4-cross-platform-adopter-qualification.json → cross-platform-adopter-qualification.json} +4 -4
  16. package/architecture/{v4-delivery-authority-parity.json → delivery-authority-parity.json} +17 -17
  17. package/architecture/{v4-delivery-warrant-shadow-bootstrap-plan.json → delivery-warrant-shadow-bootstrap-plan.json} +4 -4
  18. package/architecture/{v4-delivery-warrant-shadow-bootstrap-plan.md → delivery-warrant-shadow-bootstrap-plan.md} +7 -7
  19. package/architecture/{v4-floating-consumer-policy.json → floating-consumer-policy.json} +2 -2
  20. package/architecture/{v4-floating-consumer-policy.md → floating-consumer-policy.md} +1 -1
  21. package/architecture/implementation-naming.json +1273 -0
  22. package/architecture/internal-capabilities.json +201 -154
  23. package/architecture/maintainability-debt.json +205 -146
  24. package/architecture/maintainability-policy.json +37 -33
  25. package/architecture/{v4-next-development-parity.json → next-development-parity.json} +12 -12
  26. package/architecture/{v4-partial-mutation-recovery-qualification.json → partial-mutation-recovery-qualification.json} +8 -5
  27. package/architecture/{v4-platform-stage-checkpoints.json → platform-stage-checkpoints.json} +3 -3
  28. package/architecture/{v4-provider-operation-journal-contract.json → provider-operation-journal-contract.json} +10 -7
  29. package/architecture/publication-facade-patches.json +64 -0
  30. package/architecture/{v4-publication-rehearsal-parity.json → publication-rehearsal-parity.json} +4 -4
  31. package/architecture/{v4-release-activation-shadow-domain.json → release-activation-shadow-domain.json} +9 -6
  32. package/architecture/release-tail-contract-inventory.json +6 -6
  33. package/architecture/{v4-release-topology.json → release-topology.json} +163 -72
  34. package/architecture/{v4-release-train-parity.json → release-train-parity.json} +2 -2
  35. package/architecture/{v4-runtime-ref-resume-authority.json → runtime-ref-resume-authority.json} +1 -1
  36. package/architecture/{v4-runtime-semantic-closure.json → runtime-semantic-closure.json} +2 -2
  37. package/architecture/{v4-rust-libnode-bridge-evaluation.json → rust-libnode-bridge-evaluation.json} +3 -3
  38. package/architecture/{v4-rust-libnode-bridge-spike.md → rust-libnode-bridge-spike.md} +6 -6
  39. package/architecture/rust-wasm-production-authority.json +58 -0
  40. package/architecture/{v4-stable-publication-fence.json → stable-publication-fence.json} +7 -4
  41. package/architecture/{v4-stage-capsule-contract.json → stage-capsule-contract.json} +1 -1
  42. package/architecture/{v4-stage-capsule-qualification.json → stage-capsule-qualification.json} +8 -8
  43. package/architecture/{v4-stage-capsule-resume-planner.json → stage-capsule-resume-planner.json} +2 -2
  44. package/architecture/{v4-stage-capsule-store-contract.json → stage-capsule-store-contract.json} +4 -4
  45. package/architecture/{v4-tail-reseal-parity.json → tail-reseal-parity.json} +35 -33
  46. package/architecture/universal-workflow-bootstrap.json +176 -0
  47. package/architecture/universal-workflow-fault-campaign.json +72 -0
  48. package/architecture/universal-workflow-train-admission.json +40 -0
  49. package/architecture/workflow-taxonomy.json +1462 -0
  50. package/bin/buildchain.mjs +10 -10
  51. package/bin/internal/adopter-delivery-cli.mjs +9 -9
  52. package/contracts/buildchain-v2-residuals-v1.json +57 -48
  53. package/contracts/dev-delivery-authority-v2.schema.json +16 -2
  54. package/contracts/fixtures/v4-tail-reseal-v1/valid.json +1 -1
  55. package/contracts/v4-canonical-contracts-v1.schema.json +1 -0
  56. package/crates/{buildchain-v4-bridge → buildchain-host-bridge}/Cargo.lock +1 -1
  57. package/crates/{buildchain-v4-bridge → buildchain-host-bridge}/Cargo.toml +1 -1
  58. package/crates/{buildchain-v4-bridge → buildchain-host-bridge}/src/main.rs +3 -3
  59. package/dist/site/buildchain-contract.json +98 -53
  60. package/dist/site/buildchain-site.json +351 -102
  61. package/dist/site/capability-registry.json +7 -7
  62. package/dist/site/controller-registry.json +50 -13
  63. package/dist/site/kfd-claims.json +2773 -1052
  64. package/dist/site/kfd-upstream-aggregate.json +1 -1
  65. package/dist/site/manual-registry.json +14 -14
  66. package/dist/site/node-api-registry.json +13176 -10733
  67. package/dist/site/page-registry.json +332 -83
  68. package/dist/site/public-surface-audit.json +3227 -1222
  69. package/dist/site/publication-authority-registry.json +1135 -363
  70. package/dist/site/publication-registry.json +4 -4
  71. package/dist/site/release-provenance.json +18 -9
  72. package/dist/site/schemas/dev-delivery-authority-v2.schema.json +16 -2
  73. package/dist/site/site-manifest.json +18 -18
  74. package/dist/site/workflow-registry.json +5367 -1931
  75. package/docs/MAP.md +5 -3
  76. package/docs/auditable-demo.md +1 -1
  77. package/docs/cli.md +21 -8
  78. package/docs/dev-delivery-warrant.md +1 -1
  79. package/docs/engineering-housekeeper.md +3 -3
  80. package/docs/kfd-support.md +26 -2
  81. package/docs/next-development-transition.md +26 -3
  82. package/docs/node-api-reference.md +618 -358
  83. package/docs/oci-publication.md +173 -0
  84. package/docs/publication-authority.md +2 -2
  85. package/docs/publish-transaction.md +36 -3
  86. package/docs/release-candidate.md +3 -3
  87. package/docs/release-flow.md +67 -19
  88. package/docs/release-governance.md +8 -8
  89. package/docs/release-passport.md +27 -2
  90. package/docs/reusable-build-surface.md +17 -1
  91. package/docs/v4-adopter-delivery.md +4 -4
  92. package/docs/v4-canonical-contracts.md +7 -7
  93. package/docs/v4-delivery-warrant-read-candidate.md +3 -3
  94. package/docs/v4-delivery-warrant-semantic-diff.md +3 -3
  95. package/docs/v4-production-release.md +77 -8
  96. package/docs/v4-publication-rehearsal.md +3 -3
  97. package/docs/v4-runtime-ref-resume-authority.md +2 -2
  98. package/docs/v4-rust-wasm-production-authority.md +58 -0
  99. package/docs/v4-stage-capsule.md +9 -9
  100. package/docs/v4-tail-reseal.md +2 -2
  101. package/docs/workflow-catalog.md +155 -0
  102. package/docs/workflow-path-migration.md +109 -0
  103. package/package.json +39 -24
  104. package/packages/compatibility/adopter-delivery.js +16 -0
  105. package/packages/compatibility/cross-platform-adopter-qualification.js +12 -0
  106. package/packages/compatibility/floating-consumer-policy.js +14 -0
  107. package/packages/compatibility/publication-qualification.js +11 -0
  108. package/packages/compatibility/publication-rehearsal.js +18 -0
  109. package/packages/compatibility/runtime-ref-resume-authority.js +13 -0
  110. package/packages/compatibility/tail-reseal-receipt.js +7 -0
  111. package/packages/compatibility/tail-reseal.js +11 -0
  112. package/packages/core/{v4-adopter-delivery-parity.js → adopter-delivery-parity.js} +12 -12
  113. package/packages/core/{v4-adopter-delivery.js → adopter-delivery.js} +24 -24
  114. package/packages/core/artifact-verification-envelope.js +5 -5
  115. package/packages/core/buildchain-contract.js +6 -6
  116. package/packages/core/buildchain-domain.wasm +0 -0
  117. package/packages/core/buildchain-kfd-claims.js +2 -2
  118. package/packages/core/buildchain-publication-authority.js +43 -26
  119. package/packages/core/{v4-canonical-contracts.js → canonical-contracts.js} +39 -103
  120. package/packages/core/ci-lane-change-budget.js +14 -1
  121. package/packages/core/controller-evidence.js +4 -1
  122. package/packages/core/{v4-cross-platform-adopter-qualification.js → cross-platform-adopter-qualification.js} +19 -19
  123. package/packages/core/{v4-delivery-warrant-fixture-runner.js → delivery-warrant-fixture-runner.js} +36 -32
  124. package/packages/core/{v4-delivery-warrant-read-candidate.js → delivery-warrant-read-candidate.js} +40 -40
  125. package/packages/core/{v4-delivery-warrant-semantic-diff-gate.js → delivery-warrant-semantic-diff-gate.js} +58 -59
  126. package/packages/core/{v4-delivery-warrant-shadow-adapter.js → delivery-warrant-shadow-adapter.js} +15 -15
  127. package/packages/core/dev-delivery-candidate-identity.js +40 -6
  128. package/packages/core/dev-delivery-execution-transfer.js +6 -6
  129. package/packages/core/dev-delivery-native-proof.js +12 -8
  130. package/packages/core/dev-delivery-warrant-legacy-recovery.js +1 -1
  131. package/packages/core/dev-delivery-warrant-native-compatibility.js +4 -4
  132. package/packages/core/dev-delivery-warrant-state.js +14 -15
  133. package/packages/core/dev-delivery-warrant.js +15 -5
  134. package/packages/core/domain-wasm-artifact.js +7 -0
  135. package/packages/core/domain-wasm.js +216 -0
  136. package/packages/core/{v4-floating-consumer-evidence.js → floating-consumer-evidence.js} +14 -14
  137. package/packages/core/{v4-floating-consumer-policy.js → floating-consumer-policy.js} +28 -30
  138. package/packages/core/{v4-floating-consumer-release-passport.js → floating-consumer-release-passport.js} +25 -25
  139. package/packages/core/github-governance-authority.js +4 -4
  140. package/packages/core/index.js +4 -8
  141. package/packages/core/kfd-adopter-manifest.js +46 -47
  142. package/packages/core/next-development-projection.js +26 -3
  143. package/packages/core/next-development-transition.js +5 -6
  144. package/packages/core/oci-compose-qualification.js +143 -0
  145. package/packages/core/oci-publication-bundle.js +281 -0
  146. package/packages/core/oci-publication-graph.js +206 -0
  147. package/packages/core/paper-agent-entry.js +30 -4
  148. package/packages/core/paper-fleet.js +1 -1
  149. package/packages/core/paper-runtime-channels.js +348 -0
  150. package/packages/core/paper-scaffold-content.js +10 -0
  151. package/packages/core/paper.js +37 -71
  152. package/packages/core/partial-mutation-recovery-qualification.js +18 -0
  153. package/packages/core/{v4-platform-stage-checkpoints.js → platform-stage-checkpoints.js} +37 -37
  154. package/packages/core/product-publication.js +59 -0
  155. package/packages/core/{v4-protected-publication-source.js → protected-publication-source.js} +22 -24
  156. package/packages/core/provider-operation-journal.js +62 -0
  157. package/packages/core/{v4-provider-readback-idempotency.js → provider-readback-idempotency.js} +40 -125
  158. package/packages/core/public-export-compatibility.js +33 -0
  159. package/packages/core/publication-development.js +72 -0
  160. package/packages/core/{v4-publication-qualification.js → publication-qualification.js} +17 -17
  161. package/packages/core/{v4-publication-rehearsal-capsule.js → publication-rehearsal-capsule.js} +23 -23
  162. package/packages/core/publication-rehearsal-projection.js +2 -2
  163. package/packages/core/{v4-publication-rehearsal-provider-bindings.js → publication-rehearsal-provider-bindings.js} +4 -4
  164. package/packages/core/publication-rehearsal-runtime.js +21 -21
  165. package/packages/core/{v4-publication-rehearsal.js → publication-rehearsal.js} +33 -33
  166. package/packages/core/publication-sealed-bundle.js +78 -13
  167. package/packages/core/release-activation-shadow.js +32 -0
  168. package/packages/core/release-candidate.js +6 -6
  169. package/packages/core/release-invocation.js +64 -0
  170. package/packages/core/release-line-dry-run.js +1 -1
  171. package/packages/core/release-passport-contract.js +5 -5
  172. package/packages/core/release-passport.js +41 -40
  173. package/packages/core/release-tail-product-capabilities.js +9 -0
  174. package/packages/core/release-tail-provider-plane.js +68 -1048
  175. package/packages/core/{v4-runtime-ref-resume-authority.js → runtime-ref-resume-authority.js} +36 -40
  176. package/packages/core/{v4-runtime-selector-persistence.js → runtime-selector-persistence.js} +7 -7
  177. package/packages/core/stable-publication-fence.js +28 -0
  178. package/packages/core/{v4-stage-capsule-local-store.js → stage-capsule-local-store.js} +56 -54
  179. package/packages/core/{v4-stage-capsule-qualification-campaign.js → stage-capsule-qualification-campaign.js} +37 -38
  180. package/packages/core/{v4-stage-capsule-qualification.js → stage-capsule-qualification.js} +28 -29
  181. package/packages/core/{v4-stage-capsule-resume-planner.js → stage-capsule-resume-planner.js} +29 -29
  182. package/packages/core/{v4-stage-capsule-store.js → stage-capsule-store.js} +59 -56
  183. package/packages/core/{v4-stage-capsule.js → stage-capsule.js} +45 -45
  184. package/packages/core/{v4-tail-reseal-contract.js → tail-reseal-contract.js} +6 -6
  185. package/packages/core/{v4-tail-reseal-github.js → tail-reseal-github.js} +12 -12
  186. package/packages/core/{v4-tail-reseal-receipt.js → tail-reseal-receipt.js} +22 -22
  187. package/packages/core/{v4-tail-reseal.js → tail-reseal.js} +29 -29
  188. package/packages/core/universal-workflow-bootstrap.js +586 -0
  189. package/scripts/{v4-architecture.mjs → architecture.mjs} +6 -6
  190. package/scripts/binary-publication-evidence.mjs +135 -0
  191. package/scripts/{v4-bridge-bootstrap.mjs → bridge-bootstrap.mjs} +14 -18
  192. package/scripts/{v4-bridge-evidence.mjs → bridge-evidence.mjs} +8 -8
  193. package/scripts/build-contract-core.mjs +1 -14
  194. package/scripts/build-domain-wasm.mjs +177 -0
  195. package/scripts/{v3-v4-capability-catalog.mjs → capability-parity-catalog.mjs} +19 -19
  196. package/scripts/check-action-bundles.mjs +12 -2
  197. package/scripts/{check-v3-v4-capability-inventory.mjs → check-capability-parity-inventory.mjs} +42 -42
  198. package/scripts/check-ci-lane-change-budget.mjs +4 -1
  199. package/scripts/check-core-mechanism-inventory.mjs +8 -4
  200. package/scripts/{check-v4-floating-consumer-policy-contract.mjs → check-floating-consumer-policy-contract.mjs} +10 -10
  201. package/scripts/check-implementation-naming.mjs +135 -0
  202. package/scripts/check-inventory.mjs +39 -47
  203. package/scripts/check-maintainability.mjs +25 -115
  204. package/scripts/{check-v4-public-dogfood-contract.mjs → check-public-dogfood-contract.mjs} +37 -24
  205. package/scripts/{check-v4-release-topology.mjs → check-release-topology.mjs} +131 -52
  206. package/scripts/{check-v4-runtime-semantic-closure.mjs → check-runtime-semantic-closure.mjs} +23 -17
  207. package/scripts/check-universal-workflow-bootstrap.mjs +266 -0
  208. package/scripts/check-workflow-taxonomy.mjs +6 -0
  209. package/scripts/{v4-consumer-policy.mjs → consumer-policy.mjs} +15 -15
  210. package/scripts/copy-domain-wasm.mjs +14 -0
  211. package/scripts/{v4-cross-platform-adopter-qualification.mjs → cross-platform-adopter-qualification.mjs} +9 -9
  212. package/scripts/{v4-declarative-promotion-admission.mjs → declarative-promotion-admission.mjs} +4 -4
  213. package/scripts/dev-delivery-authority-command-adapters.mjs +1 -1
  214. package/scripts/dev-delivery-authority.mjs +8 -8
  215. package/scripts/dev-delivery-source-proof-reuse.mjs +2 -1
  216. package/scripts/dev-delivery-warrant-options.mjs +15 -10
  217. package/scripts/dev-delivery-warrant-store.mjs +98 -13
  218. package/scripts/dev-delivery-warrant-transition.mjs +109 -0
  219. package/scripts/dev-delivery-warrant.mjs +80 -103
  220. package/scripts/dev-pr-auto-merge.mjs +15 -15
  221. package/scripts/dev-pr-delivery-warrant.mjs +1 -1
  222. package/scripts/generate-channel-build-workflow.mjs +7 -2
  223. package/scripts/generate-channel-promotion-workflow.mjs +19 -34
  224. package/scripts/generate-release-candidate-passport.mjs +23 -23
  225. package/scripts/generate-site-bundle.mjs +28 -28
  226. package/scripts/generate-universal-workflow-facades.mjs +498 -0
  227. package/scripts/generate-workflow-taxonomy.mjs +25 -0
  228. package/scripts/github-output.mjs +31 -0
  229. package/scripts/{v4-host-adapter.mjs → host-adapter.mjs} +1 -1
  230. package/scripts/implementation-references.mjs +25 -0
  231. package/scripts/init-repo.mjs +1 -1
  232. package/scripts/maintainability-metrics.mjs +16 -5
  233. package/scripts/maintainability-public-surface.mjs +115 -0
  234. package/scripts/next-development-review.mjs +313 -0
  235. package/scripts/oci-compose-preview.mjs +261 -0
  236. package/scripts/paper-work-fleet-cli.mjs +2 -0
  237. package/scripts/{v4-platform-stage-checkpoint-rehearsal.mjs → platform-stage-checkpoint-rehearsal.mjs} +17 -17
  238. package/scripts/{v4-product-publication-intent.mjs → product-publication-intent.mjs} +28 -13
  239. package/scripts/publication-candidate-kind.mjs +93 -0
  240. package/scripts/publication-candidate-sealer.mjs +16 -1
  241. package/scripts/{v4-publication-rehearsal-fixture.mjs → publication-rehearsal-fixture.mjs} +5 -5
  242. package/scripts/publication-settlement.mjs +211 -0
  243. package/scripts/release-asset-client.mjs +91 -0
  244. package/scripts/{v4-release-candidate-adapter.mjs → release-candidate-adapter.mjs} +4 -4
  245. package/scripts/release-candidate-resolver.mjs +24 -35
  246. package/scripts/release-tail.mjs +5 -5
  247. package/scripts/resume-from-candidate-run.mjs +35 -42
  248. package/scripts/site-capability-metadata.mjs +9 -0
  249. package/scripts/source-verification-evidence.mjs +344 -0
  250. package/scripts/stable-candidate-qualification.mjs +1 -1
  251. package/scripts/{v4-stage-capsule-qualification.mjs → stage-capsule-qualification.mjs} +62 -62
  252. package/scripts/{v4-stage-capsule-resume-rehearsal.mjs → stage-capsule-resume-rehearsal.mjs} +6 -6
  253. package/scripts/{v4-tail-reseal-macos-rehearsal.mjs → tail-reseal-macos-rehearsal.mjs} +9 -9
  254. package/scripts/{v4-tail-reseal.mjs → tail-reseal.mjs} +19 -19
  255. package/scripts/universal-facade-maintainability.mjs +91 -0
  256. package/scripts/universal-workflow-backflow.mjs +212 -0
  257. package/scripts/universal-workflow-engine.mjs +620 -0
  258. package/scripts/universal-workflow-self-dogfood.mjs +205 -0
  259. package/scripts/verify-version-state-delta.mjs +175 -0
  260. package/scripts/{v4-warrant-shadow-plan.mjs → warrant-shadow-plan.mjs} +6 -6
  261. package/scripts/workflow-taxonomy.mjs +507 -0
  262. package/templates/native-dev-delivery.yml +4 -7
  263. package/templates/universal-buildchain-bootstrap-recovery.yml +282 -0
  264. package/templates/universal-buildchain-bootstrap.yml +28 -0
  265. package/actions/v4-release-candidate-promote/README.md +0 -3
  266. package/packages/core/v4-partial-mutation-recovery-qualification.js +0 -395
  267. package/packages/core/v4-product-publication.js +0 -387
  268. package/packages/core/v4-provider-operation-journal.js +0 -531
  269. package/packages/core/v4-release-activation-shadow.js +0 -519
  270. package/packages/core/v4-release-invocation.js +0 -425
  271. package/packages/core/v4-stable-publication-fence.js +0 -357
  272. /package/architecture/{v4-adopter-delivery-parity.json → adopter-delivery-parity.json} +0 -0
  273. /package/architecture/{v3-core-mechanism-inventory.json → baseline-core-mechanism-inventory.json} +0 -0
  274. /package/architecture/{v4-canonical-contract-fixtures.json → canonical-contract-fixtures.json} +0 -0
  275. /package/architecture/{v4-compatibility-facts-parity.json → compatibility-facts-parity.json} +0 -0
  276. /package/architecture/{v4-delivery-warrant-shadow-bootstrap-plan.schema.json → delivery-warrant-shadow-bootstrap-plan.schema.json} +0 -0
  277. /package/architecture/{v4-delivery-warrant-shadow-fixtures.json → delivery-warrant-shadow-fixtures.json} +0 -0
  278. /package/architecture/{v4-delivery-warrant-shadow-fixtures.schema.json → delivery-warrant-shadow-fixtures.schema.json} +0 -0
  279. /package/architecture/{v4-exception-ledger.json → exception-ledger.json} +0 -0
  280. /package/architecture/{v4-exception-ledger.schema.json → exception-ledger.schema.json} +0 -0
  281. /package/architecture/{v4-release-invocation-fixtures.json → release-invocation-fixtures.json} +0 -0
@@ -4,8 +4,8 @@ import fs from "node:fs";
4
4
  import path from "node:path";
5
5
  import { fileURLToPath } from "node:url";
6
6
 
7
- import { v4CanonicalBytes } from "../packages/core/v4-canonical-contracts.js";
8
- import { planV4StageCapsuleResume } from "../packages/core/v4-stage-capsule-resume-planner.js";
7
+ import { domainCanonicalBytes } from "../packages/core/canonical-contracts.js";
8
+ import { planStageCapsuleResume } from "../packages/core/stage-capsule-resume-planner.js";
9
9
 
10
10
  const repoRoot = path.resolve(
11
11
  path.dirname(fileURLToPath(import.meta.url)),
@@ -22,7 +22,7 @@ if (!platform) throw new Error("--platform is required");
22
22
 
23
23
  const declaration = JSON.parse(
24
24
  fs.readFileSync(
25
- path.join(repoRoot, "architecture/v4-platform-stage-checkpoints.json"),
25
+ path.join(repoRoot, "architecture/platform-stage-checkpoints.json"),
26
26
  "utf8",
27
27
  ),
28
28
  );
@@ -38,13 +38,13 @@ const fixture = JSON.parse(
38
38
  "utf8",
39
39
  ),
40
40
  );
41
- const first = planV4StageCapsuleResume(fixture);
42
- const second = planV4StageCapsuleResume(structuredClone(fixture));
41
+ const first = planStageCapsuleResume(fixture);
42
+ const second = planStageCapsuleResume(structuredClone(fixture));
43
43
  if (first.planRoot !== second.planRoot)
44
44
  throw new Error("resume planner is not deterministic");
45
45
 
46
46
  process.stdout.write(
47
- v4CanonicalBytes({
47
+ domainCanonicalBytes({
48
48
  schema: "buildchain-v4-stage-capsule-resume-rehearsal/v1",
49
49
  mode: "shadow-only",
50
50
  platform,
@@ -6,8 +6,8 @@ import os from "node:os";
6
6
  import path from "node:path";
7
7
  import { pathToFileURL } from "node:url";
8
8
 
9
- import { v4ContentRoot } from "../packages/core/v4-canonical-contracts.js";
10
- import { verifyV4TailResealPlatform } from "./v4-tail-reseal.mjs";
9
+ import { domainContentRoot } from "../packages/core/canonical-contracts.js";
10
+ import { verifyTailResealPlatform } from "./tail-reseal.mjs";
11
11
 
12
12
  function flag(args, name, fallback = "") {
13
13
  const index = args.indexOf(`--${name}`);
@@ -56,12 +56,12 @@ function writeCandidate(root, request, content) {
56
56
  fs.mkdirSync(path.dirname(manifestPath), { recursive: true });
57
57
  fs.writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`);
58
58
  return {
59
- artifactRoot: v4ContentRoot("tail-reseal-artifact-files", [file]),
59
+ artifactRoot: domainContentRoot("tail-reseal-artifact-files", [file]),
60
60
  manifestRoot: fileRoot(manifestPath),
61
61
  };
62
62
  }
63
63
 
64
- export function rehearseV4TailResealMacos({
64
+ export function rehearseTailResealMacos({
65
65
  fixturePath = "contracts/fixtures/v4-tail-reseal-v1/valid.json",
66
66
  outputPath = "",
67
67
  } = {}) {
@@ -69,20 +69,20 @@ export function rehearseV4TailResealMacos({
69
69
  fs.readFileSync(path.resolve(fixturePath), "utf8"),
70
70
  );
71
71
  const workRoot = fs.mkdtempSync(
72
- path.join(os.tmpdir(), "buildchain-v4-tail-macos-"),
72
+ path.join(os.tmpdir(), "buildchain-tail-macos-"),
73
73
  );
74
74
  try {
75
75
  const retainedRoots = writeCandidate(workRoot, request, "unsigned");
76
76
  const platform = request.platforms.find(({ id }) => id === "macos-arm64");
77
77
  Object.assign(platform, retainedRoots);
78
- const retained = verifyV4TailResealPlatform({
78
+ const retained = verifyTailResealPlatform({
79
79
  request,
80
80
  platformId: "macos-arm64",
81
81
  artifactRoot: workRoot,
82
82
  mode: "retained",
83
83
  });
84
84
  writeCandidate(workRoot, request, "signed-and-notarized");
85
- const resealed = verifyV4TailResealPlatform({
85
+ const resealed = verifyTailResealPlatform({
86
86
  request,
87
87
  platformId: "macos-arm64",
88
88
  artifactRoot: workRoot,
@@ -100,7 +100,7 @@ export function rehearseV4TailResealMacos({
100
100
  };
101
101
  const evidence = {
102
102
  ...payload,
103
- evidenceRoot: v4ContentRoot("tail-reseal-admission", payload),
103
+ evidenceRoot: domainContentRoot("tail-reseal-admission", payload),
104
104
  };
105
105
  if (outputPath) {
106
106
  const output = path.resolve(outputPath);
@@ -118,7 +118,7 @@ if (
118
118
  import.meta.url === pathToFileURL(process.argv[1]).href
119
119
  ) {
120
120
  try {
121
- const evidence = rehearseV4TailResealMacos({
121
+ const evidence = rehearseTailResealMacos({
122
122
  fixturePath: flag(
123
123
  process.argv.slice(2),
124
124
  "fixture",
@@ -6,13 +6,13 @@ import path from "node:path";
6
6
  import { pathToFileURL } from "node:url";
7
7
 
8
8
  import {
9
- V4_TAIL_RESEAL_PLATFORMS,
10
- normalizeV4TailResealRequest,
11
- planV4TailReseal,
12
- } from "../packages/core/v4-tail-reseal.js";
13
- import { createV4TailResealReceipt } from "../packages/core/v4-tail-reseal-receipt.js";
14
- import { validateV4TailResealGitHubEvidence } from "../packages/core/v4-tail-reseal-github.js";
15
- import { v4ContentRoot } from "../packages/core/v4-canonical-contracts.js";
9
+ TAIL_RESEAL_PLATFORMS,
10
+ normalizeTailResealRequest,
11
+ planTailReseal,
12
+ } from "../packages/core/tail-reseal.js";
13
+ import { createTailResealReceipt } from "../packages/core/tail-reseal-receipt.js";
14
+ import { validateTailResealGitHubEvidence } from "../packages/core/tail-reseal-github.js";
15
+ import { domainContentRoot } from "../packages/core/canonical-contracts.js";
16
16
 
17
17
  function flag(args, name, fallback = "") {
18
18
  const index = args.indexOf(`--${name}`);
@@ -137,7 +137,7 @@ async function admitFromGitHub(request) {
137
137
  token,
138
138
  ),
139
139
  ]);
140
- return validateV4TailResealGitHubEvidence({
140
+ return validateTailResealGitHubEvidence({
141
141
  request,
142
142
  sourceCommit,
143
143
  sourceRun,
@@ -183,14 +183,14 @@ function resolvePayload(root, relative, platformId) {
183
183
  return absolute;
184
184
  }
185
185
 
186
- export function verifyV4TailResealPlatform({
186
+ export function verifyTailResealPlatform({
187
187
  request,
188
188
  platformId,
189
189
  artifactRoot,
190
190
  mode = "retained",
191
191
  providerReadbackRoot = null,
192
192
  } = {}) {
193
- const normalized = normalizeV4TailResealRequest(request);
193
+ const normalized = normalizeTailResealRequest(request);
194
194
  const platform = normalized.platforms.find(({ id }) => id === platformId);
195
195
  if (!platform)
196
196
  throw new Error(`tail reseal request does not bind platform ${platformId}`);
@@ -243,7 +243,7 @@ export function verifyV4TailResealPlatform({
243
243
  );
244
244
  if (files.length === 0)
245
245
  throw new Error(`${platformId} manifest has no retained files`);
246
- const observedArtifactRoot = v4ContentRoot(
246
+ const observedArtifactRoot = domainContentRoot(
247
247
  "tail-reseal-artifact-files",
248
248
  files,
249
249
  );
@@ -290,21 +290,21 @@ function collectReadbacks(directory) {
290
290
  throw new Error(`duplicate tail reseal readback for ${value.platformId}`);
291
291
  byPlatform.set(value.platformId, value);
292
292
  }
293
- return V4_TAIL_RESEAL_PLATFORMS.map((platformId) => {
293
+ return TAIL_RESEAL_PLATFORMS.map((platformId) => {
294
294
  if (!byPlatform.has(platformId))
295
295
  throw new Error(`missing tail reseal readback for ${platformId}`);
296
296
  return byPlatform.get(platformId);
297
297
  });
298
298
  }
299
299
 
300
- export function runV4TailResealCli(args = process.argv.slice(2)) {
300
+ export function runTailResealCli(args = process.argv.slice(2)) {
301
301
  const [command, ...options] = args;
302
302
  const requestPath = flag(options, "request");
303
303
  if (command === "plan") {
304
- const request = normalizeV4TailResealRequest(
304
+ const request = normalizeTailResealRequest(
305
305
  readJson(required(requestPath, "--request"), "tail reseal request"),
306
306
  );
307
- const plan = planV4TailReseal(request);
307
+ const plan = planTailReseal(request);
308
308
  const output = writeJson(
309
309
  flag(options, "output", ".buildchain/tail-reseal/plan.json"),
310
310
  plan,
@@ -331,7 +331,7 @@ export function runV4TailResealCli(args = process.argv.slice(2)) {
331
331
  return plan;
332
332
  }
333
333
  if (command === "admit") {
334
- const request = normalizeV4TailResealRequest(
334
+ const request = normalizeTailResealRequest(
335
335
  readJson(required(requestPath, "--request"), "tail reseal request"),
336
336
  );
337
337
  return admitFromGitHub(request).then((admission) => {
@@ -347,7 +347,7 @@ export function runV4TailResealCli(args = process.argv.slice(2)) {
347
347
  });
348
348
  }
349
349
  if (command === "verify-platform") {
350
- const readback = verifyV4TailResealPlatform({
350
+ const readback = verifyTailResealPlatform({
351
351
  request: readJson(required(requestPath, "--request")),
352
352
  platformId: required(flag(options, "platform"), "--platform"),
353
353
  artifactRoot: flag(options, "artifact-root", process.cwd()),
@@ -371,7 +371,7 @@ export function runV4TailResealCli(args = process.argv.slice(2)) {
371
371
  }
372
372
  if (command === "seal") {
373
373
  const request = readJson(required(requestPath, "--request"));
374
- const receipt = createV4TailResealReceipt({
374
+ const receipt = createTailResealReceipt({
375
375
  request,
376
376
  plan: readJson(required(flag(options, "plan"), "--plan")),
377
377
  readbacks: collectReadbacks(
@@ -409,7 +409,7 @@ if (
409
409
  process.argv[1] &&
410
410
  import.meta.url === pathToFileURL(process.argv[1]).href
411
411
  ) {
412
- runV4TailResealCli().catch((error) => {
412
+ runTailResealCli().catch((error) => {
413
413
  console.error(`tail-reseal: ${error.message}`);
414
414
  process.exitCode = 1;
415
415
  });
@@ -0,0 +1,91 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { execFileSync } from "node:child_process";
4
+
5
+ function loadUniversalFacadeMigration(root) {
6
+ const contract = JSON.parse(
7
+ fs.readFileSync(
8
+ path.join(root, "architecture/universal-workflow-bootstrap.json"),
9
+ "utf8",
10
+ ),
11
+ );
12
+ const retired = new Set(contract.retiredWorkflowSurfaces || []);
13
+ const paths = (contract.bootstrapGovernedWorkflows || []).filter(
14
+ (entry) =>
15
+ entry !== contract.bootstrap?.publicWorkflow && !retired.has(entry),
16
+ );
17
+ const sourceRevision = contract.migration?.facadeSourceRevision || "";
18
+ if (!/^[0-9a-f]{40}$/u.test(sourceRevision)) {
19
+ throw new Error(
20
+ "universal facade migration requires an exact facadeSourceRevision",
21
+ );
22
+ }
23
+ return {
24
+ paths: new Set(paths),
25
+ sourceRevision,
26
+ postMigration: new Set(contract.migration?.postMigrationWorkflows || []),
27
+ };
28
+ }
29
+
30
+ function verifyUniversalFacadeMigration(root) {
31
+ execFileSync(
32
+ process.execPath,
33
+ ["scripts/generate-universal-workflow-facades.mjs", "--check"],
34
+ { cwd: root, stdio: "pipe" },
35
+ );
36
+ }
37
+
38
+ function governUniversalFacadeWorkflowMetrics({
39
+ root,
40
+ current,
41
+ workflowMetricsAtRevision,
42
+ }) {
43
+ const migration = loadUniversalFacadeMigration(root);
44
+ verifyUniversalFacadeMigration(root);
45
+ const frozen = workflowMetricsAtRevision(root, migration.sourceRevision);
46
+ const governed = { ...current, workflows: { ...current.workflows } };
47
+ for (const file of migration.postMigration) {
48
+ if (frozen[file] || !migration.paths.has(file))
49
+ throw new Error(`invalid post-migration workflow declaration ${file}`);
50
+ migration.paths.delete(file);
51
+ }
52
+ for (const file of migration.paths) {
53
+ if (!frozen[file])
54
+ throw new Error(`frozen universal facade source is missing ${file}`);
55
+ governed.workflows[file] = frozen[file];
56
+ }
57
+ return { governed, migration };
58
+ }
59
+
60
+ function isGeneratedFacadePublicTransition({
61
+ entry,
62
+ kind,
63
+ migration,
64
+ baseContract,
65
+ currentContract,
66
+ }) {
67
+ if (kind !== "workflow" || !migration?.paths.has(entry.path) || !baseContract)
68
+ return false;
69
+ const { inputs: currentInputs, ...currentRest } = currentContract;
70
+ const { inputs: previousInputs, ...previousRest } = baseContract;
71
+ if (JSON.stringify(currentRest) !== JSON.stringify(previousRest))
72
+ return false;
73
+ const added = currentInputs.filter(
74
+ (input) => !previousInputs.includes(input),
75
+ );
76
+ const removed = previousInputs.filter(
77
+ (input) => !currentInputs.includes(input),
78
+ );
79
+ return (
80
+ removed.length === 0 &&
81
+ added.length === 1 &&
82
+ added[0] === "universal-request-json"
83
+ );
84
+ }
85
+
86
+ export {
87
+ governUniversalFacadeWorkflowMetrics,
88
+ isGeneratedFacadePublicTransition,
89
+ loadUniversalFacadeMigration,
90
+ verifyUniversalFacadeMigration,
91
+ };
@@ -0,0 +1,212 @@
1
+ #!/usr/bin/env node
2
+ import crypto from "node:crypto";
3
+ import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import {
6
+ validateUniversalWorkflowRequest,
7
+ universalWorkflowRequestRoot,
8
+ } from "../packages/core/universal-workflow-bootstrap.js";
9
+ const SHA = /^[0-9a-f]{40}$/u;
10
+ const ROOT = /^sha256:[0-9a-f]{64}$/u;
11
+
12
+ function fail(message) {
13
+ throw new Error(message);
14
+ }
15
+
16
+ function canonical(value) {
17
+ if (Array.isArray(value)) return value.map(canonical);
18
+ if (value && typeof value === "object")
19
+ return Object.fromEntries(
20
+ Object.keys(value)
21
+ .sort((left, right) => Buffer.from(left).compare(Buffer.from(right)))
22
+ .map((key) => [key, canonical(value[key])]),
23
+ );
24
+ return value;
25
+ }
26
+
27
+ function contentRoot(domain, value) {
28
+ const hash = crypto.createHash("sha256");
29
+ hash.update(domain, "utf8");
30
+ hash.update(Buffer.from([0]));
31
+ hash.update(`${JSON.stringify(canonical(value))}\n`, "utf8");
32
+ return `sha256:${hash.digest("hex")}`;
33
+ }
34
+
35
+ function validateTerminalReceipt(value, request) {
36
+ if (
37
+ value?.schema !==
38
+ "kungfu-buildchain-v4-universal-workflow-terminal-receipt/v1" ||
39
+ value.status !== "succeeded" ||
40
+ value.runtime?.repository !== request.candidate.repository ||
41
+ value.runtime?.sha !== request.candidate.expectedSha ||
42
+ value.requestRoot !== universalWorkflowRequestRoot(request) ||
43
+ !SHA.test(value.runtime?.sha || "") ||
44
+ !ROOT.test(value.receiptRoot || "")
45
+ )
46
+ fail(
47
+ "successful exact-candidate terminal receipt is required for backflow",
48
+ );
49
+ return value;
50
+ }
51
+
52
+ export function createUniversalBackflowPlan({
53
+ request: requestValue,
54
+ receipt,
55
+ }) {
56
+ const request = validateUniversalWorkflowRequest(requestValue);
57
+ if (request.mode !== "train") fail("only Train delivery can create backflow");
58
+ if (request.capability.id !== "release-candidate-promote")
59
+ fail("only a release-candidate-promote delivery can create backflow");
60
+ if (request.payload?.inputs?.["dry-run"] !== false)
61
+ fail("only a non-dry-run release delivery can create backflow");
62
+ const terminal = validateTerminalReceipt(receipt, request);
63
+ const marker = `<!-- buildchain-universal-backflow:${request.candidate.expectedSha} -->`;
64
+ const binding = {
65
+ schema: "kungfu-buildchain-v4-universal-workflow-backflow/v1",
66
+ repository: request.candidate.repository,
67
+ pullRequest: request.candidate.reviewPullRequest,
68
+ baseRef: "dev/v4/v4.0",
69
+ trainSha: request.candidate.expectedSha,
70
+ consumerRepository: request.consumer.repository,
71
+ consumerSha: request.consumer.sourceSha,
72
+ requestRoot: terminal.requestRoot,
73
+ terminalReceiptRoot: terminal.receiptRoot,
74
+ };
75
+ const backflowRoot = contentRoot("universal-workflow-backflow", binding);
76
+ return {
77
+ ...binding,
78
+ marker,
79
+ backflowRoot,
80
+ body: [
81
+ marker,
82
+ "## Universal Train backflow",
83
+ "",
84
+ `- Train SHA: \`${binding.trainSha}\``,
85
+ `- Consumer: \`${binding.consumerRepository}@${binding.consumerSha}\``,
86
+ `- Request root: \`${binding.requestRoot}\``,
87
+ `- Terminal receipt root: \`${binding.terminalReceiptRoot}\``,
88
+ `- Backflow root: \`${backflowRoot}\``,
89
+ "",
90
+ "This receipt binds a successful consumer delivery to the protected Train-to-dev backflow PR; it does not designate the Train candidate as a Buildchain release.",
91
+ ].join("\n"),
92
+ };
93
+ }
94
+
95
+ function githubHeaders(token) {
96
+ return {
97
+ accept: "application/vnd.github+json",
98
+ authorization: `Bearer ${token}`,
99
+ "content-type": "application/json",
100
+ "user-agent": "buildchain-universal-backflow",
101
+ "x-github-api-version": "2022-11-28",
102
+ };
103
+ }
104
+
105
+ async function githubJson({ path, method = "GET", token, body, fetchImpl }) {
106
+ const api = String(
107
+ process.env.GITHUB_API_URL || "https://api.github.com",
108
+ ).replace(/\/+$/u, "");
109
+ const response = await fetchImpl(`${api}${path}`, {
110
+ method,
111
+ headers: githubHeaders(token),
112
+ body: body === undefined ? undefined : JSON.stringify(body),
113
+ });
114
+ const text = await response.text();
115
+ const value = text ? JSON.parse(text) : {};
116
+ if (!response.ok)
117
+ fail(
118
+ `GitHub API ${method} ${path} failed with ${response.status}: ${value.message || text}`,
119
+ );
120
+ return value;
121
+ }
122
+
123
+ export async function upsertUniversalBackflow({
124
+ request,
125
+ receipt,
126
+ token,
127
+ fetchImpl = globalThis.fetch,
128
+ }) {
129
+ const admitted = validateUniversalWorkflowRequest(request);
130
+ if (
131
+ admitted.mode !== "train" ||
132
+ admitted.capability.id !== "release-candidate-promote" ||
133
+ admitted.payload?.inputs?.["dry-run"] !== false
134
+ ) {
135
+ return {
136
+ schema: "kungfu-buildchain-v4-universal-workflow-backflow-result/v1",
137
+ action: "skipped",
138
+ reason: "not-a-successful-non-dry-run-release-delivery",
139
+ backflowRoot: "",
140
+ };
141
+ }
142
+ if (!token) fail("GH_TOKEN is required for protected backflow");
143
+ if (typeof fetchImpl !== "function") fail("fetch is required for backflow");
144
+ const plan = createUniversalBackflowPlan({ request: admitted, receipt });
145
+ const encodedRepository = plan.repository;
146
+ const pull = await githubJson({
147
+ path: `/repos/${encodedRepository}/pulls/${plan.pullRequest}`,
148
+ token,
149
+ fetchImpl,
150
+ });
151
+ if (
152
+ pull.state !== "open" ||
153
+ pull.base?.ref !== plan.baseRef ||
154
+ pull.head?.repo?.full_name !== plan.repository ||
155
+ pull.head?.sha !== plan.trainSha
156
+ )
157
+ fail("backflow PR no longer binds the exact admitted Train candidate");
158
+ const comments = await githubJson({
159
+ path: `/repos/${encodedRepository}/issues/${plan.pullRequest}/comments?per_page=100`,
160
+ token,
161
+ fetchImpl,
162
+ });
163
+ const existing = comments.find((comment) =>
164
+ String(comment.body || "").includes(plan.marker),
165
+ );
166
+ const comment = existing
167
+ ? await githubJson({
168
+ path: `/repos/${encodedRepository}/issues/comments/${existing.id}`,
169
+ method: "PATCH",
170
+ token,
171
+ body: { body: plan.body },
172
+ fetchImpl,
173
+ })
174
+ : await githubJson({
175
+ path: `/repos/${encodedRepository}/issues/${plan.pullRequest}/comments`,
176
+ method: "POST",
177
+ token,
178
+ body: { body: plan.body },
179
+ fetchImpl,
180
+ });
181
+ return {
182
+ schema: "kungfu-buildchain-v4-universal-workflow-backflow-result/v1",
183
+ action: existing ? "updated" : "created",
184
+ pullRequest: plan.pullRequest,
185
+ trainSha: plan.trainSha,
186
+ terminalReceiptRoot: plan.terminalReceiptRoot,
187
+ backflowRoot: plan.backflowRoot,
188
+ commentUrl: comment.html_url,
189
+ };
190
+ }
191
+
192
+ async function main() {
193
+ const request = JSON.parse(
194
+ process.env.BUILDCHAIN_UNIVERSAL_REQUEST_JSON ||
195
+ fail("request is required"),
196
+ );
197
+ const receipt = JSON.parse(
198
+ process.env.BUILDCHAIN_UNIVERSAL_TERMINAL_RECEIPT_JSON ||
199
+ fail("terminal receipt is required"),
200
+ );
201
+ const result = await upsertUniversalBackflow({
202
+ request,
203
+ receipt,
204
+ token: process.env.GH_TOKEN || process.env.GITHUB_TOKEN,
205
+ });
206
+ process.stdout.write(`${JSON.stringify(result)}\n`);
207
+ }
208
+
209
+ const isMain =
210
+ process.argv[1] &&
211
+ fileURLToPath(import.meta.url) === path.resolve(process.argv[1]);
212
+ if (isMain) await main();