@kungfu-tech/buildchain 4.0.0 → 4.0.1-alpha.10

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 (228) hide show
  1. package/AGENTS.md +13 -5
  2. package/actions/promote-buildchain-ref/README.md +11 -6
  3. package/actions/release-tail/README.md +8 -0
  4. package/architecture/ci-lane-change-budget.json +187 -0
  5. package/architecture/decisions/0002-next-development-transition.md +101 -0
  6. package/architecture/decisions/0003-two-phase-delivery-warrant.md +152 -0
  7. package/architecture/internal-capabilities.json +219 -7
  8. package/architecture/maintainability-policy.json +246 -29
  9. package/architecture/release-tail-contract-inventory.json +5 -2
  10. package/architecture/v3-core-mechanism-inventory.json +91 -0
  11. package/architecture/v4-adopter-delivery-parity.json +32 -5
  12. package/architecture/v4-capability-state-machine-manifest.json +73 -0
  13. package/architecture/v4-compatibility-facts-parity.json +77 -0
  14. package/architecture/v4-delivery-authority-parity.json +250 -0
  15. package/architecture/v4-delivery-warrant-shadow-fixtures.json +41 -9
  16. package/architecture/v4-floating-consumer-policy.json +81 -0
  17. package/architecture/v4-floating-consumer-policy.md +32 -0
  18. package/architecture/v4-next-development-parity.json +192 -0
  19. package/architecture/v4-publication-rehearsal-parity.json +84 -0
  20. package/architecture/v4-release-train-parity.json +1 -0
  21. package/architecture/v4-runtime-ref-resume-authority.json +64 -0
  22. package/architecture/v4-stage-capsule-qualification.json +2 -2
  23. package/architecture/v4-tail-reseal-parity.json +150 -0
  24. package/bin/buildchain.mjs +32 -3
  25. package/bin/internal/adopter-delivery-cli.mjs +70 -0
  26. package/bin/internal/command-registry.mjs +3 -0
  27. package/bin/internal/compatibility-facts-cli.mjs +101 -0
  28. package/bin/internal/trust-release-release-handlers.mjs +5 -0
  29. package/contracts/dev-delivery-authority-v2.schema.json +662 -0
  30. package/contracts/fixtures/next-development-transition-v1/anchored-manual-waiting.json +47 -0
  31. package/contracts/fixtures/next-development-transition-v1/semver-auto-planned.json +47 -0
  32. package/contracts/fixtures/next-development-transition-v1/version-model-cases.json +40 -0
  33. package/contracts/fixtures/v4-adopter-delivery-v1/archive-template.json +19 -0
  34. package/contracts/fixtures/v4-adopter-delivery-v1/bootstrap-positive.json +93 -0
  35. package/contracts/fixtures/v4-adopter-delivery-v1/gate-positive.json +29 -0
  36. package/contracts/fixtures/v4-adopter-delivery-v1/gate-unknown-selector.json +26 -0
  37. package/contracts/fixtures/v4-adopter-delivery-v1/offline-vectors.json +50 -0
  38. package/contracts/fixtures/v4-compatibility-facts-v1/shared.json +1129 -0
  39. package/contracts/fixtures/v4-floating-consumer-policy-v1/cases.json +59 -0
  40. package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/artifacts/product.bin +1 -0
  41. package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/config/buildchain.toml +5 -0
  42. package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/documents/release-activation.json +1 -0
  43. package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/documents/signed-channel.json +1 -0
  44. package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/evidence/qualification.json +1 -0
  45. package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/manifests/candidate.json +5 -0
  46. package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/manifests/release-passport.json +1 -0
  47. package/contracts/fixtures/v4-publication-rehearsal-v1/capsule.json +707 -0
  48. package/contracts/fixtures/v4-publication-rehearsal-v1/offline-vectors.json +27 -0
  49. package/contracts/fixtures/v4-runtime-ref-resume-authority-v1/scenario.json +15 -0
  50. package/contracts/fixtures/v4-tail-reseal-v1/valid.json +229 -0
  51. package/contracts/next-development-request-v1.schema.json +66 -0
  52. package/contracts/next-development-transition-v1.schema.json +292 -0
  53. package/contracts/v4-adopter-delivery-v1.schema.json +81 -0
  54. package/contracts/v4-compatibility-facts-v1.schema.json +230 -0
  55. package/contracts/v4-floating-consumer-policy-receipt-v1.schema.json +107 -0
  56. package/contracts/v4-publication-rehearsal-capsule-v1.schema.json +233 -0
  57. package/contracts/v4-runtime-ref-resume-authority-v1.schema.json +235 -0
  58. package/contracts/v4-tail-reseal-v1.schema.json +276 -0
  59. package/dist/site/agent-index.json +5 -0
  60. package/dist/site/artifact-schemas.json +10 -0
  61. package/dist/site/buildchain-contract.json +1562 -44
  62. package/dist/site/buildchain-site.json +684 -42
  63. package/dist/site/capability-registry.json +17 -14
  64. package/dist/site/cli-registry.json +205 -3
  65. package/dist/site/controller-registry.json +62 -6
  66. package/dist/site/kfd-claims.json +551 -22
  67. package/dist/site/kfd-upstream-aggregate.json +1 -1
  68. package/dist/site/manual-registry.json +55 -9
  69. package/dist/site/node-api-registry.json +15247 -8690
  70. package/dist/site/page-registry.json +647 -29
  71. package/dist/site/public-surface-audit.json +876 -55
  72. package/dist/site/publication-authority-registry.json +44 -8
  73. package/dist/site/publication-registry.json +4 -4
  74. package/dist/site/release-provenance.json +26 -0
  75. package/dist/site/schemas/dev-delivery-authority-v2.schema.json +662 -0
  76. package/dist/site/schemas/release-tail-capabilities-v1.schema.json +199 -0
  77. package/dist/site/schemas/v4-adopter-delivery-v1.schema.json +81 -0
  78. package/dist/site/schemas/v4-compatibility-facts-v1.schema.json +230 -0
  79. package/dist/site/schemas/v4-publication-rehearsal-capsule-v1.schema.json +233 -0
  80. package/dist/site/site-manifest.json +37 -13
  81. package/dist/site/workflow-registry.json +200 -22
  82. package/docs/MAP.md +10 -2
  83. package/docs/cli-reference.md +404 -13
  84. package/docs/cli.md +8 -0
  85. package/docs/dev-alpha-candidate-patrol.md +8 -0
  86. package/docs/dev-delivery-qualification-landing-adr.md +251 -0
  87. package/docs/dev-delivery-warrant.md +361 -30
  88. package/docs/lifecycle-protocol.md +41 -0
  89. package/docs/next-development-transition.md +118 -0
  90. package/docs/node-api-reference.md +748 -322
  91. package/docs/release-tail-provider-plane.md +30 -0
  92. package/docs/reusable-build-surface.md +41 -0
  93. package/docs/runtime-train-validation.md +10 -0
  94. package/docs/v4-adopter-delivery.md +133 -0
  95. package/docs/v4-compatibility-facts.md +91 -0
  96. package/docs/v4-publication-rehearsal.md +130 -0
  97. package/docs/v4-runtime-ref-resume-authority.md +69 -0
  98. package/docs/v4-tail-reseal.md +73 -0
  99. package/docs/versioning.md +4 -2
  100. package/package.json +36 -6
  101. package/packages/core/adopter-delivery-passport.js +259 -0
  102. package/packages/core/adopter-delivery-vectors.js +158 -0
  103. package/packages/core/adopter-delivery-vectors.json +77 -0
  104. package/packages/core/artifact-signing.js +61 -0
  105. package/packages/core/buildchain-agent-manuals.js +3 -0
  106. package/packages/core/buildchain-compatibility-authority.js +336 -0
  107. package/packages/core/buildchain-compatibility-fact.js +394 -0
  108. package/packages/core/buildchain-compatibility-facts.json +217 -0
  109. package/packages/core/buildchain-compatibility-proof.js +566 -0
  110. package/packages/core/buildchain-config.js +150 -1
  111. package/packages/core/buildchain-contract.js +96 -143
  112. package/packages/core/buildchain-delivery-bootstrap.js +240 -0
  113. package/packages/core/buildchain-delivery-infrastructure.js +164 -0
  114. package/packages/core/buildchain-delivery-self-dogfood.js +395 -0
  115. package/packages/core/buildchain-publication-authority.js +1 -0
  116. package/packages/core/channel-candidate.js +8 -0
  117. package/packages/core/channel-promotion-baseline.js +55 -0
  118. package/packages/core/ci-lane-change-budget.js +247 -0
  119. package/packages/core/dev-alpha-candidate-selection.js +10 -2
  120. package/packages/core/dev-delivery-authority-candidate.js +270 -0
  121. package/packages/core/dev-delivery-authority-evidence.js +146 -0
  122. package/packages/core/dev-delivery-authority-landing.js +461 -0
  123. package/packages/core/dev-delivery-authority-observation.js +48 -0
  124. package/packages/core/dev-delivery-authority-qualification.js +591 -0
  125. package/packages/core/dev-delivery-authority-settlement.js +213 -0
  126. package/packages/core/dev-delivery-authority-state.js +583 -0
  127. package/packages/core/dev-delivery-candidate-identity.js +13 -0
  128. package/packages/core/dev-delivery-contract-surface.js +76 -0
  129. package/packages/core/dev-delivery-execution-failure.js +133 -0
  130. package/packages/core/dev-delivery-execution-transfer.js +592 -0
  131. package/packages/core/dev-delivery-landing-admission-core.js +119 -0
  132. package/packages/core/dev-delivery-landing-readback.js +598 -0
  133. package/packages/core/dev-delivery-landing-terminal-evidence.js +271 -0
  134. package/packages/core/dev-delivery-landing-testing-port.js +6 -0
  135. package/packages/core/dev-delivery-native-execution.js +110 -0
  136. package/packages/core/dev-delivery-native-proof.js +562 -0
  137. package/packages/core/dev-delivery-process-boundary.js +563 -0
  138. package/packages/core/dev-delivery-proof.js +37 -3
  139. package/packages/core/dev-delivery-provider-attempt.js +127 -0
  140. package/packages/core/dev-delivery-provider-heartbeat.js +382 -0
  141. package/packages/core/dev-delivery-warrant-cancellation.js +1 -0
  142. package/packages/core/dev-delivery-warrant-qualification.js +145 -0
  143. package/packages/core/dev-delivery-warrant-settlement.js +237 -36
  144. package/packages/core/dev-delivery-warrant-state.js +587 -0
  145. package/packages/core/dev-delivery-warrant.js +328 -370
  146. package/packages/core/github-governance-authority.js +1 -0
  147. package/packages/core/index.js +7 -0
  148. package/packages/core/kungfu-temporal-fact.js +557 -0
  149. package/packages/core/legacy-kfd-adopter-driver.js +167 -0
  150. package/packages/core/next-development-candidate-reservation.js +186 -0
  151. package/packages/core/next-development-controller.js +728 -0
  152. package/packages/core/next-development-projection.js +287 -0
  153. package/packages/core/next-development-transition.js +738 -0
  154. package/packages/core/paper-agent-entry.js +11 -5
  155. package/packages/core/paper.js +16 -5
  156. package/packages/core/publication-authority.js +5 -5
  157. package/packages/core/published-delivery-authority.js +266 -0
  158. package/packages/core/release-candidate-recovery.js +66 -11
  159. package/packages/core/release-candidate.js +79 -19
  160. package/packages/core/release-passport.js +271 -38
  161. package/packages/core/v4-adopter-delivery-parity.js +3 -3
  162. package/packages/core/v4-adopter-delivery.js +359 -0
  163. package/packages/core/v4-canonical-contracts.js +5 -0
  164. package/packages/core/v4-delivery-warrant-read-candidate.js +10 -3
  165. package/packages/core/v4-floating-consumer-evidence.js +338 -0
  166. package/packages/core/v4-floating-consumer-policy.js +569 -0
  167. package/packages/core/v4-floating-consumer-release-passport.js +153 -0
  168. package/packages/core/v4-publication-rehearsal-capsule.js +468 -0
  169. package/packages/core/v4-publication-rehearsal-provider-bindings.js +212 -0
  170. package/packages/core/v4-publication-rehearsal.js +481 -0
  171. package/packages/core/v4-runtime-ref-resume-authority.js +625 -0
  172. package/packages/core/v4-runtime-selector-persistence.js +228 -0
  173. package/packages/core/v4-tail-reseal-contract.js +26 -0
  174. package/packages/core/v4-tail-reseal-github.js +178 -0
  175. package/packages/core/v4-tail-reseal-receipt.js +225 -0
  176. package/packages/core/v4-tail-reseal.js +594 -0
  177. package/packages/core/workflow-yaml-contract.js +72 -2
  178. package/scripts/audit-publication-control-plane.mjs +31 -31
  179. package/scripts/buildchain-cli-help.mjs +41 -2
  180. package/scripts/check-ci-lane-change-budget.mjs +100 -0
  181. package/scripts/check-inventory.mjs +14 -3
  182. package/scripts/check-v4-floating-consumer-policy-contract.mjs +217 -0
  183. package/scripts/check-v4-public-dogfood-contract.mjs +6 -11
  184. package/scripts/dev-alpha-candidate-patrol.mjs +22 -1
  185. package/scripts/dev-delivery-authority-command-adapters.mjs +206 -0
  186. package/scripts/dev-delivery-authority-provider.mjs +28 -0
  187. package/scripts/dev-delivery-authority.mjs +490 -0
  188. package/scripts/dev-delivery-native-run.mjs +177 -0
  189. package/scripts/dev-delivery-process-boundary.mjs +260 -0
  190. package/scripts/dev-delivery-proof.mjs +67 -2
  191. package/scripts/dev-delivery-provider-heartbeat.mjs +215 -0
  192. package/scripts/dev-delivery-source-proof-replay.mjs +153 -0
  193. package/scripts/dev-delivery-source-proof-reuse.mjs +547 -0
  194. package/scripts/dev-delivery-two-phase-resume.mjs +345 -0
  195. package/scripts/dev-delivery-two-phase.mjs +573 -0
  196. package/scripts/dev-delivery-warrant-options.mjs +266 -0
  197. package/scripts/dev-delivery-warrant-store.mjs +231 -0
  198. package/scripts/dev-delivery-warrant.mjs +232 -194
  199. package/scripts/dev-pr-auto-merge.mjs +37 -48
  200. package/scripts/dev-pr-delivery-warrant.mjs +216 -2
  201. package/scripts/dev-pr-prequeue-guard.mjs +399 -0
  202. package/scripts/dev-qualification-patrol.mjs +9 -9
  203. package/scripts/dispatch-artifact-signing-authority.mjs +1 -1
  204. package/scripts/ensure-github-release.mjs +3 -3
  205. package/scripts/generate-channel-build-workflow.mjs +3 -0
  206. package/scripts/generate-channel-promotion-workflow.mjs +114 -14
  207. package/scripts/generate-next-development-guidance.mjs +49 -0
  208. package/scripts/generate-release-candidate-passport.mjs +192 -32
  209. package/scripts/generate-site-bundle.mjs +69 -4
  210. package/scripts/init-repo.mjs +26 -4
  211. package/scripts/inspect-artifact-signing-requests.mjs +6 -0
  212. package/scripts/next-development-self-dogfood-harness.mjs +460 -0
  213. package/scripts/next-development-self-dogfood.mjs +597 -0
  214. package/scripts/next-development-transition.mjs +47 -0
  215. package/scripts/npm-publish-transaction.mjs +103 -91
  216. package/scripts/promotion-channel-router.mjs +4 -4
  217. package/scripts/release-candidate-anchor-provenance.mjs +99 -0
  218. package/scripts/release-tail.mjs +51 -3
  219. package/scripts/release-train-self-dogfood.mjs +94 -92
  220. package/scripts/resume-from-candidate-run.mjs +565 -41
  221. package/scripts/seal-artifact-signing-requests.mjs +6 -0
  222. package/scripts/site-capability-metadata.mjs +43 -0
  223. package/scripts/stable-candidate-qualification.mjs +9 -10
  224. package/scripts/v4-consumer-policy.mjs +231 -0
  225. package/scripts/v4-publication-rehearsal-fixture.mjs +144 -0
  226. package/scripts/v4-tail-reseal-macos-rehearsal.mjs +134 -0
  227. package/scripts/v4-tail-reseal.mjs +416 -0
  228. package/templates/native-dev-delivery.yml +143 -0
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env node
2
+
3
+ import fs from "node:fs";
4
+ import path from "node:path";
5
+ import { pathToFileURL } from "node:url";
6
+
7
+ import { nextDevelopmentManual } from "../packages/core/next-development-projection.js";
8
+
9
+ export const NEXT_DEVELOPMENT_MANUAL_PATH =
10
+ "docs/next-development-transition.md";
11
+
12
+ export function generateNextDevelopmentGuidance({
13
+ cwd = process.cwd(),
14
+ check = false,
15
+ } = {}) {
16
+ const target = path.resolve(cwd, NEXT_DEVELOPMENT_MANUAL_PATH);
17
+ const expected = nextDevelopmentManual();
18
+ const current = fs.existsSync(target) ? fs.readFileSync(target, "utf8") : "";
19
+ if (check) {
20
+ if (current !== expected) {
21
+ throw new Error(
22
+ `${NEXT_DEVELOPMENT_MANUAL_PATH} drifted from its contract source`,
23
+ );
24
+ }
25
+ return { ok: true, changed: false, path: NEXT_DEVELOPMENT_MANUAL_PATH };
26
+ }
27
+ fs.mkdirSync(path.dirname(target), { recursive: true });
28
+ if (current !== expected) fs.writeFileSync(target, expected);
29
+ return {
30
+ ok: true,
31
+ changed: current !== expected,
32
+ path: NEXT_DEVELOPMENT_MANUAL_PATH,
33
+ };
34
+ }
35
+
36
+ if (
37
+ process.argv[1] &&
38
+ import.meta.url === pathToFileURL(process.argv[1]).href
39
+ ) {
40
+ try {
41
+ const result = generateNextDevelopmentGuidance({
42
+ check: process.argv.includes("--check"),
43
+ });
44
+ process.stdout.write(`${JSON.stringify(result)}\n`);
45
+ } catch (error) {
46
+ process.stderr.write(`next-development guidance: ${error.message}\n`);
47
+ process.exitCode = 1;
48
+ }
49
+ }
@@ -1,19 +1,179 @@
1
1
  #!/usr/bin/env node
2
2
  import fs from "node:fs";
3
3
  import path from "node:path";
4
+ import { execFileSync } from "node:child_process";
4
5
  import { pathToFileURL } from "node:url";
5
- import {
6
- createReleaseCandidatePassport,
7
- validateReleaseCandidatePassport,
8
- } from "../packages/core/release-candidate.js";
6
+ import { createReleaseCandidatePassport, validateReleaseCandidatePassport } from "../packages/core/release-candidate.js";
7
+ import { scanV4FloatingConsumerPolicy, v4ConsumerPolicyScannerRoot } from "../packages/core/v4-floating-consumer-policy.js";
8
+ import { v4ContentRoot } from "../packages/core/v4-canonical-contracts.js";
9
+ import { V4_STAGE_CAPSULE_CONTRACT, V4_STAGE_CAPSULE_IDENTITY_CONTRACT, v4StageCapsuleIdentityRoot, v4StageCapsuleRoot, validateV4StageCapsule } from "../packages/core/v4-stage-capsule.js";
10
+ import { v4RuntimeResumeDocumentRoot } from "../packages/core/v4-runtime-ref-resume-authority.js";
9
11
  import { writeGitHubOutputs } from "./build-contract-core.mjs";
10
12
 
11
- function env(name, fallback = "") {
12
- return process.env[name] || fallback;
13
+ const env = (name, fallback = "") => process.env[name] || fallback;
14
+ const readJsonFile = (filePath) => JSON.parse(fs.readFileSync(filePath, "utf8"));
15
+
16
+ export function createReleaseCandidateStageCapsules({
17
+ passport,
18
+ buildSummary,
19
+ coordinates,
20
+ }) {
21
+ if (!passport.consumerPolicy?.receiptRoot) return undefined;
22
+ if (
23
+ coordinates.repository !== passport.repository ||
24
+ String(coordinates.runId) !== String(passport.workflow.runId) ||
25
+ String(coordinates.runAttempt) !== String(passport.workflow.runAttempt) ||
26
+ coordinates.sourceSha !== passport.source.headSha
27
+ ) {
28
+ throw new Error(
29
+ "Stage Capsule coordinate set does not bind the candidate run",
30
+ );
31
+ }
32
+ const coordinateByPlatform = new Map(
33
+ coordinates.artifacts.map((entry) => [entry.platformId, entry]),
34
+ );
35
+ const qualificationRoot = passport.controllerReceipts?.[0]?.receiptDigest;
36
+ const entries = passport.platformMatrix
37
+ .map((platform) => {
38
+ const coordinate = coordinateByPlatform.get(platform.platformId);
39
+ if (!coordinate || coordinate.name !== platform.artifactName) {
40
+ throw new Error(
41
+ `Stage Capsule coordinate missing for ${platform.platformId}`,
42
+ );
43
+ }
44
+ const manifest = readJsonFile(platform.manifestPath);
45
+ const identity = {
46
+ schema: V4_STAGE_CAPSULE_IDENTITY_CONTRACT,
47
+ sourceRoot: v4ContentRoot("candidate-identity", passport.source),
48
+ platform: platform.platformId,
49
+ platformRoot: v4ContentRoot("candidate-identity", manifest.platform),
50
+ stage: "verify",
51
+ toolchainRoots: [],
52
+ runtimeRoot: v4ContentRoot("candidate-identity", {
53
+ sha: passport.buildchain.sha,
54
+ }),
55
+ policyRoot: passport.consumerPolicy.receiptRoot,
56
+ declaredInputs: [
57
+ {
58
+ name: "release-candidate",
59
+ root: `sha256:${passport.candidateHash}`,
60
+ },
61
+ ],
62
+ transformationRoot: v4ContentRoot("candidate-identity", {
63
+ lifecycle: manifest.lifecycle,
64
+ summary: platform.summary,
65
+ }),
66
+ outputManifestRoot: v4ContentRoot(
67
+ "stage-capsule-artifact-manifest",
68
+ { artifact: coordinate, manifest },
69
+ ),
70
+ qualificationRoot,
71
+ observationRoots: [
72
+ {
73
+ name: "provider-coordinate",
74
+ root: v4ContentRoot("provider-readback-sample", coordinate),
75
+ },
76
+ ],
77
+ };
78
+ const capsule = {
79
+ schema: V4_STAGE_CAPSULE_CONTRACT,
80
+ writerAuthority: "typescript-v3",
81
+ rustAuthority: "validation-only",
82
+ identity,
83
+ identityRoot: v4StageCapsuleIdentityRoot(identity),
84
+ retentionPromise: {
85
+ class: "github-artifact",
86
+ retainUntil: coordinate.expiresAt,
87
+ },
88
+ capsuleRoot: `sha256:${"0".repeat(64)}`,
89
+ };
90
+ capsule.capsuleRoot = v4StageCapsuleRoot(capsule);
91
+ validateV4StageCapsule(capsule);
92
+ return {
93
+ platform: platform.platformId,
94
+ artifactName: coordinate.name,
95
+ artifactDigest: coordinate.digest,
96
+ artifact: coordinate,
97
+ capsule,
98
+ };
99
+ })
100
+ .sort((left, right) => left.platform.localeCompare(right.platform));
101
+ const body = {
102
+ schemaVersion: 1,
103
+ contract: "kungfu-buildchain-v4-release-candidate-stage-capsules/v1",
104
+ status: "sealed",
105
+ repository: passport.repository,
106
+ buildAttempt: {
107
+ id: `github-run:${passport.workflow.runId}:attempt:${passport.workflow.runAttempt}`,
108
+ runtimeSha: passport.buildchain.sha,
109
+ },
110
+ source: {
111
+ sha: passport.source.headSha,
112
+ treeSha: passport.source.treeHash,
113
+ },
114
+ consumerPolicyReceiptRoot: passport.consumerPolicy.receiptRoot,
115
+ capsules: entries,
116
+ };
117
+ return { ...body, root: v4RuntimeResumeDocumentRoot(body) };
118
+ }
119
+
120
+ function writeReleaseCandidateStageCapsules({
121
+ passport,
122
+ buildSummary,
123
+ outputPath,
124
+ }) {
125
+ const coordinatesPath = path.resolve(
126
+ env(
127
+ "BUILDCHAIN_ARTIFACT_COORDINATES_PATH",
128
+ ".buildchain/artifacts/artifact-coordinates.json",
129
+ ),
130
+ );
131
+ if (!fs.existsSync(coordinatesPath)) {
132
+ if (passport.consumerPolicy?.receiptRoot) {
133
+ throw new Error(
134
+ "v4 release candidate Stage Capsules require exact artifact coordinates",
135
+ );
136
+ }
137
+ return { path: "", root: "" };
138
+ }
139
+ const stageCapsules = createReleaseCandidateStageCapsules({
140
+ passport,
141
+ buildSummary,
142
+ coordinates: readJsonFile(coordinatesPath),
143
+ });
144
+ if (!stageCapsules) return { path: "", root: "" };
145
+ const stageCapsulesPath = path.join(
146
+ path.dirname(outputPath),
147
+ "release-candidate-stage-capsules.json",
148
+ );
149
+ fs.writeFileSync(
150
+ stageCapsulesPath,
151
+ `${JSON.stringify(stageCapsules, null, 2)}\n`,
152
+ );
153
+ return {
154
+ path: path
155
+ .relative(process.cwd(), stageCapsulesPath)
156
+ .split(path.sep)
157
+ .join("/"),
158
+ root: stageCapsules.root,
159
+ };
13
160
  }
14
161
 
15
- function readJsonFile(filePath) {
16
- return JSON.parse(fs.readFileSync(filePath, "utf8"));
162
+ export function resolveLegacyConsumerPolicyReceipt(options = {}) {
163
+ if (options.json) return { receipt: JSON.parse(options.json), receiptRoot: options.receiptRoot };
164
+ if (options.repository !== "kungfu-systems/buildchain" || options.targetChannel !== "alpha" || options.workflowShellRef !== "v4-alpha" || options.runtimeOverride !== true) return undefined;
165
+ if (!/^[0-9a-f]{40}$/u.test(options.runtimeRef || "") || options.runtimeRef !== options.runtimeSha || options.sourceTreeHash !== options.runtimeTreeHash()) return undefined;
166
+ const root = path.resolve(options.root || ".buildchain/runtime");
167
+ const alphaLock = readJsonFile(path.join(root, ".buildchain/alpha-contract-lock.json"));
168
+ const result = scanV4FloatingConsumerPolicy({
169
+ root, repository: options.repository, sourceSha: options.sourceSha,
170
+ invokedWorkflow: options.invokedWorkflow || ".github/workflows/build.yml", invocationSourcePath: options.invocationSourcePath,
171
+ expectedInvocationChannel: "alpha", resolvedWorkflowSha: alphaLock.buildchain?.resolvedSha,
172
+ resolvedRuntimeSha: options.runtimeSha, scannerRoot: v4ConsumerPolicyScannerRoot(),
173
+ policy: readJsonFile(path.resolve(import.meta.dirname, "../architecture/v4-floating-consumer-policy.json")),
174
+ });
175
+ if (!result.ok) throw new Error(`legacy floating-shell policy receipt invalid: ${result.failures.map(({ code }) => code).join(", ")}`);
176
+ return { receipt: result.receipt, receiptRoot: result.receiptRoot };
17
177
  }
18
178
 
19
179
  export function generateReleaseCandidatePassportCli() {
@@ -21,23 +181,28 @@ export function generateReleaseCandidatePassportCli() {
21
181
  const outputPath = path.resolve(env("BUILDCHAIN_RC_PASSPORT_PATH", ".buildchain/artifacts/release-candidate-passport.json"));
22
182
  const buildSummary = readJsonFile(buildSummaryPath);
23
183
  const sourceSha = env("BUILDCHAIN_RC_SOURCE_HEAD_SHA", buildSummary.publishSource?.sha || buildSummary.git?.sha || "");
24
- const version = env(
25
- "BUILDCHAIN_RC_VERSION",
26
- buildSummary.publishSource?.consumerVersion || "",
27
- );
184
+ const version = env("BUILDCHAIN_RC_VERSION", buildSummary.publishSource?.consumerVersion || "");
28
185
  const gateAggregateJson = env("BUILDCHAIN_GATE_PROFILE_AGGREGATE_JSON");
29
186
  const gateAggregate = gateAggregateJson ? JSON.parse(gateAggregateJson) : undefined;
30
187
  const controllerReceiptJson = env("BUILDCHAIN_CONTROLLER_RECEIPT_JSON");
31
188
  const controllerReceipts = controllerReceiptJson ? [JSON.parse(controllerReceiptJson)] : [];
32
189
  const familyEvidenceJson = env("BUILDCHAIN_RC_FAMILY_EVIDENCE_JSON");
33
190
  const familyEvidence = familyEvidenceJson ? JSON.parse(familyEvidenceJson) : undefined;
191
+ const consumerPolicyJson = env("BUILDCHAIN_V4_POLICY_RECEIPT_JSON");
192
+ const consumerPolicyReceipt = resolveLegacyConsumerPolicyReceipt({
193
+ json: consumerPolicyJson, receiptRoot: env("BUILDCHAIN_V4_POLICY_RECEIPT_ROOT"),
194
+ repository: env("GITHUB_REPOSITORY", buildSummary.git?.repository || ""), sourceSha,
195
+ targetChannel: env("BUILDCHAIN_RC_TARGET_CHANNEL", buildSummary.publishSource?.channel || buildSummary.publishGate?.channel || ""),
196
+ runtimeRef: env("BUILDCHAIN_RUNTIME_REF", buildSummary.runtime?.ref || ""), runtimeSha: env("BUILDCHAIN_RUNTIME_SHA", buildSummary.runtime?.sha || ""),
197
+ workflowShellRef: env("BUILDCHAIN_WORKFLOW_SHELL_REF", buildSummary.runtime?.workflowShellRef || ""), runtimeOverride: buildSummary.runtime?.override === true,
198
+ root: ".buildchain/runtime", invocationSourcePath: env("GITHUB_WORKFLOW_REF"), sourceTreeHash: env("BUILDCHAIN_RC_SOURCE_TREE_HASH"),
199
+ runtimeTreeHash: () => execFileSync("git", ["-C", ".buildchain/runtime", "rev-parse", "HEAD^{tree}"], { encoding: "utf8" }).trim(),
200
+ });
34
201
  const passport = createReleaseCandidatePassport({
35
202
  repository: env("GITHUB_REPOSITORY", buildSummary.git?.repository || ""),
36
203
  pullRequest: {
37
- number: env("BUILDCHAIN_PULL_REQUEST_NUMBER"),
38
- url: env("BUILDCHAIN_PULL_REQUEST_URL"),
39
- headRef: env("BUILDCHAIN_PULL_REQUEST_HEAD_REF"),
40
- baseRef: env("BUILDCHAIN_PULL_REQUEST_BASE_REF"),
204
+ number: env("BUILDCHAIN_PULL_REQUEST_NUMBER"), url: env("BUILDCHAIN_PULL_REQUEST_URL"),
205
+ headRef: env("BUILDCHAIN_PULL_REQUEST_HEAD_REF"), baseRef: env("BUILDCHAIN_PULL_REQUEST_BASE_REF"),
41
206
  },
42
207
  targetChannel: env("BUILDCHAIN_RC_TARGET_CHANNEL", buildSummary.publishSource?.channel || buildSummary.publishGate?.channel || ""),
43
208
  version,
@@ -47,32 +212,24 @@ export function generateReleaseCandidatePassportCli() {
47
212
  sourceTreeHash: env("BUILDCHAIN_RC_SOURCE_TREE_HASH"),
48
213
  buildSummary,
49
214
  buildchain: {
50
- ref: env("BUILDCHAIN_RUNTIME_REF", buildSummary.runtime?.ref || ""),
51
- sha: env("BUILDCHAIN_RUNTIME_SHA", buildSummary.runtime?.sha || ""),
52
- version: env("BUILDCHAIN_RUNTIME_VERSION"),
53
- workflowShellRef: env("BUILDCHAIN_WORKFLOW_SHELL_REF", buildSummary.runtime?.workflowShellRef || ""),
215
+ ref: env("BUILDCHAIN_RUNTIME_REF", buildSummary.runtime?.ref || ""), sha: env("BUILDCHAIN_RUNTIME_SHA", buildSummary.runtime?.sha || ""),
216
+ version: env("BUILDCHAIN_RUNTIME_VERSION"), workflowShellRef: env("BUILDCHAIN_WORKFLOW_SHELL_REF", buildSummary.runtime?.workflowShellRef || ""),
54
217
  },
55
218
  gateAggregate,
56
219
  familyEvidence,
220
+ consumerPolicyReceipt,
57
221
  controllerReceipts,
58
222
  workflow: {
59
- name: env("GITHUB_WORKFLOW"),
60
- runId: env("GITHUB_RUN_ID", buildSummary.git?.runId || ""),
61
- runAttempt: env("GITHUB_RUN_ATTEMPT", buildSummary.git?.runAttempt || ""),
62
- url: env("BUILDCHAIN_WORKFLOW_RUN_URL"),
223
+ name: env("GITHUB_WORKFLOW"), runId: env("GITHUB_RUN_ID", buildSummary.git?.runId || ""),
224
+ runAttempt: env("GITHUB_RUN_ATTEMPT", buildSummary.git?.runAttempt || ""), url: env("BUILDCHAIN_WORKFLOW_RUN_URL"),
63
225
  },
64
226
  });
65
227
  const validation = validateReleaseCandidatePassport({
66
- passport,
67
- repository: env("GITHUB_REPOSITORY", buildSummary.git?.repository || ""),
68
- sourceHeadSha: sourceSha,
69
- buildSummary,
70
- });
71
- if (!validation.ok) {
72
- throw new Error(`release candidate passport invalid: ${validation.errors.join("; ")}`);
73
- }
228
+ passport, repository: env("GITHUB_REPOSITORY", buildSummary.git?.repository || ""), sourceHeadSha: sourceSha, buildSummary });
229
+ if (!validation.ok) throw new Error(`release candidate passport invalid: ${validation.errors.join("; ")}`);
74
230
  fs.mkdirSync(path.dirname(outputPath), { recursive: true });
75
231
  fs.writeFileSync(outputPath, `${JSON.stringify(passport, null, 2)}\n`);
232
+ const stageCapsules = writeReleaseCandidateStageCapsules({ passport, buildSummary, outputPath });
76
233
  writeGitHubOutputs({
77
234
  "release-candidate-passport-path": path.relative(process.cwd(), outputPath).split(path.sep).join("/"),
78
235
  "release-candidate-passport-json": JSON.stringify({
@@ -84,8 +241,11 @@ export function generateReleaseCandidatePassportCli() {
84
241
  platformCount: passport.platformMatrix.length,
85
242
  gateProfileEvidence: passport.gateProfileEvidence,
86
243
  familyEvidence: passport.familyEvidence,
244
+ consumerPolicy: passport.consumerPolicy,
87
245
  controllerReceipts: passport.controllerReceipts || [],
88
246
  }),
247
+ "release-candidate-stage-capsules-path": stageCapsules.path,
248
+ "release-candidate-stage-capsules-root": stageCapsules.root,
89
249
  });
90
250
  return passport;
91
251
  }
@@ -46,6 +46,31 @@ import {
46
46
  const SITE_BUNDLE_CONTRACT = "kungfu-buildchain-site-bundle";
47
47
  const PUBLICATION_RELEASE_REGISTRY_CONTRACT = "kungfu-buildchain-publication-release-registry";
48
48
  const README_PATH = "README.md";
49
+ const DEV_DELIVERY_AUTHORITY_SCHEMA =
50
+ "schemas/dev-delivery-authority-v2.schema.json";
51
+ const DEV_DELIVERY_AUTHORITY_SCHEMA_SOURCE =
52
+ "contracts/dev-delivery-authority-v2.schema.json";
53
+ const V4_COMPATIBILITY_FACTS_SCHEMA =
54
+ "schemas/v4-compatibility-facts-v1.schema.json";
55
+ const V4_COMPATIBILITY_FACTS_SCHEMA_SOURCE =
56
+ "contracts/v4-compatibility-facts-v1.schema.json";
57
+ const V4_PUBLICATION_REHEARSAL_SCHEMA =
58
+ "schemas/v4-publication-rehearsal-capsule-v1.schema.json";
59
+ const V4_PUBLICATION_REHEARSAL_SCHEMA_SOURCE =
60
+ "contracts/v4-publication-rehearsal-capsule-v1.schema.json";
61
+ const V4_ADOPTER_DELIVERY_SCHEMA =
62
+ "schemas/v4-adopter-delivery-v1.schema.json";
63
+ const V4_ADOPTER_DELIVERY_SCHEMA_SOURCE =
64
+ "contracts/v4-adopter-delivery-v1.schema.json";
65
+ const RELEASE_TAIL_CAPABILITIES_SCHEMA =
66
+ "schemas/release-tail-capabilities-v1.schema.json";
67
+ const RELEASE_TAIL_CAPABILITIES_SCHEMA_SOURCE =
68
+ "contracts/release-tail-capabilities-v1.schema.json";
69
+ const PUBLICATION_REHEARSAL_SITE_SCHEMAS = [
70
+ V4_PUBLICATION_REHEARSAL_SCHEMA,
71
+ V4_ADOPTER_DELIVERY_SCHEMA,
72
+ RELEASE_TAIL_CAPABILITIES_SCHEMA,
73
+ ];
49
74
  const root = path.resolve(import.meta.dirname, "..");
50
75
  const outputDir = path.join(root, "dist", "site");
51
76
  const requireFromHere = createRequire(import.meta.url);
@@ -73,6 +98,21 @@ function stableJson(value) {
73
98
  return `${JSON.stringify(value, null, 2)}\n`;
74
99
  }
75
100
 
101
+ function siteFileBytes(name, value) {
102
+ if (name === DEV_DELIVERY_AUTHORITY_SCHEMA) return readText(DEV_DELIVERY_AUTHORITY_SCHEMA_SOURCE);
103
+ if (name === V4_COMPATIBILITY_FACTS_SCHEMA) return readText(V4_COMPATIBILITY_FACTS_SCHEMA_SOURCE);
104
+ if (name === V4_PUBLICATION_REHEARSAL_SCHEMA) return readText(V4_PUBLICATION_REHEARSAL_SCHEMA_SOURCE);
105
+ if (name === V4_ADOPTER_DELIVERY_SCHEMA) return readText(V4_ADOPTER_DELIVERY_SCHEMA_SOURCE);
106
+ if (name === RELEASE_TAIL_CAPABILITIES_SCHEMA) return readText(RELEASE_TAIL_CAPABILITIES_SCHEMA_SOURCE);
107
+ return stableJson(value);
108
+ }
109
+
110
+ function writeSiteFile(name, value) {
111
+ const filePath = path.join(outputDir, name);
112
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
113
+ fs.writeFileSync(filePath, siteFileBytes(name, value));
114
+ }
115
+
76
116
  function env(name) {
77
117
  return String(process.env[name] || "").trim();
78
118
  }
@@ -367,13 +407,16 @@ const manualMetaById = new Map(Object.entries({
367
407
  "release-activation-transaction": { capabilityGroup: "release-passport-trust", audience: ["release-operator", "agent"], maturity: "preview", order: 125 },
368
408
  "release-candidate": { capabilityGroup: "reusable-build", audience: ["release-operator", "consumer"], maturity: "stable", order: 130 },
369
409
  "release-train": { capabilityGroup: "governance-versioning", audience: ["release-operator", "consumer", "agent"], maturity: "preview", order: 132 },
410
+ "next-development-transition": { capabilityGroup: "governance-versioning", audience: ["release-operator", "consumer", "agent"], maturity: "preview", order: 133 },
370
411
  "stable-candidate-patrol": { capabilityGroup: "governance-versioning", audience: ["release-operator", "consumer"], maturity: "preview", order: 135 },
371
412
  "dev-qualification-patrol": { capabilityGroup: "governance-versioning", audience: ["release-operator", "consumer", "agent"], maturity: "preview", order: 136 },
372
413
  "dev-alpha-candidate-patrol": { capabilityGroup: "governance-versioning", audience: ["release-operator", "consumer", "agent"], maturity: "preview", order: 137 },
373
414
  "v4-canonical-contracts": { capabilityGroup: "governance-versioning", audience: ["developer", "maintainer", "agent"], maturity: "preview", order: 138 },
415
+ "v4-compatibility-facts": { capabilityGroup: "governance-versioning", audience: ["developer", "maintainer", "agent"], maturity: "preview", order: 139 },
374
416
  "observed-evidence-patrol": { capabilityGroup: "governance-versioning", audience: ["release-operator", "consumer", "agent"], maturity: "preview", order: 140 },
375
417
  "engineering-housekeeper": { capabilityGroup: "governance-versioning", audience: ["maintainer", "consumer", "agent"], maturity: "preview", order: 145 },
376
418
  "reusable-build-surface": { capabilityGroup: "reusable-build", audience: ["consumer", "release-operator"], maturity: "stable", order: 200 },
419
+ "v4-adopter-delivery": { capabilityGroup: "reusable-build", audience: ["consumer", "developer", "agent"], maturity: "preview", order: 205 },
377
420
  "lifecycle-protocol": { capabilityGroup: "reusable-build", audience: ["consumer", "developer"], maturity: "stable", order: 210 },
378
421
  "runtime-train-validation": { capabilityGroup: "governance-versioning", audience: ["maintainer", "consumer"], maturity: "stable", order: 220 },
379
422
  "kfd-support": { capabilityGroup: "kfd-trust", audience: ["agent", "maintainer"], maturity: "stable", order: 300 },
@@ -737,6 +780,7 @@ function buildSiteBundle() {
737
780
  "docs/reusable-build-surface.md",
738
781
  "docs/release-candidate.md",
739
782
  "docs/release-train.md",
783
+ "docs/next-development-transition.md",
740
784
  "docs/stable-candidate-patrol.md",
741
785
  "docs/dev-qualification-patrol.md",
742
786
  "docs/dev-alpha-candidate-patrol.md",
@@ -931,6 +975,9 @@ function buildSiteBundle() {
931
975
  "schemas/release-passport-v1.schema.json",
932
976
  "schemas/kfd-agent-hub-adoption.schema.json",
933
977
  "schemas/kfd-product-gate-input-v1.schema.json",
978
+ "schemas/dev-delivery-authority-v2.schema.json",
979
+ "schemas/v4-compatibility-facts-v1.schema.json",
980
+ ...PUBLICATION_REHEARSAL_SITE_SCHEMAS,
934
981
  "kfd-support.json",
935
982
  "artifact-evidence.json",
936
983
  "product-mechanism.json",
@@ -965,6 +1012,9 @@ function buildSiteBundle() {
965
1012
  "schemas/release-passport-v1.schema.json",
966
1013
  "schemas/kfd-agent-hub-adoption.schema.json",
967
1014
  "schemas/kfd-product-gate-input-v1.schema.json",
1015
+ "schemas/dev-delivery-authority-v2.schema.json",
1016
+ "schemas/v4-compatibility-facts-v1.schema.json",
1017
+ ...PUBLICATION_REHEARSAL_SITE_SCHEMAS,
968
1018
  "buildchain-contract.json",
969
1019
  "kfd-claims.json",
970
1020
  "product-mechanism.json",
@@ -1095,6 +1145,9 @@ function buildSiteBundle() {
1095
1145
  "schemas/release-passport-v1.schema.json",
1096
1146
  "schemas/kfd-agent-hub-adoption.schema.json",
1097
1147
  "schemas/kfd-product-gate-input-v1.schema.json",
1148
+ "schemas/dev-delivery-authority-v2.schema.json",
1149
+ "schemas/v4-compatibility-facts-v1.schema.json",
1150
+ ...PUBLICATION_REHEARSAL_SITE_SCHEMAS,
1098
1151
  "buildchain-contract.json",
1099
1152
  "kfd-upstream-aggregate.json",
1100
1153
  "kfd-claims.json",
@@ -1269,6 +1322,18 @@ function buildSiteBundle() {
1269
1322
  "schemas/release-passport-v1.schema.json": RELEASE_PASSPORT_SCHEMA,
1270
1323
  "schemas/kfd-agent-hub-adoption.schema.json": KFD_AGENT_HUB_ADOPTION_SCHEMA,
1271
1324
  "schemas/kfd-product-gate-input-v1.schema.json": KFD_PRODUCT_GATE_INPUT_SCHEMA,
1325
+ [DEV_DELIVERY_AUTHORITY_SCHEMA]: readJson(
1326
+ DEV_DELIVERY_AUTHORITY_SCHEMA_SOURCE,
1327
+ ),
1328
+ [V4_COMPATIBILITY_FACTS_SCHEMA]: readJson(
1329
+ V4_COMPATIBILITY_FACTS_SCHEMA_SOURCE,
1330
+ ),
1331
+ ...Object.fromEntries(
1332
+ PUBLICATION_REHEARSAL_SITE_SCHEMAS.map((name) => [
1333
+ name,
1334
+ JSON.parse(siteFileBytes(name)),
1335
+ ]),
1336
+ ),
1272
1337
  "badge-endpoint-registry.json": badgeEndpointRegistry,
1273
1338
  "publication-registry.json": publicationRegistry,
1274
1339
  "buildchain-contract.json": createBuildchainContractWorld({ root, controllerRegistry }),
@@ -1288,7 +1353,7 @@ export function writeSiteBundle({ check = false } = {}) {
1288
1353
  const mismatches = [];
1289
1354
  for (const [name, value] of Object.entries(files)) {
1290
1355
  const filePath = path.join(outputDir, name);
1291
- const next = stableJson(value);
1356
+ const next = siteFileBytes(name, value);
1292
1357
  if (check) {
1293
1358
  if (existingJson(filePath) !== next) {
1294
1359
  mismatches.push(path.relative(root, filePath));
@@ -1301,11 +1366,11 @@ export function writeSiteBundle({ check = false } = {}) {
1301
1366
  if (!check) {
1302
1367
  for (let iteration = 0; iteration < 5; iteration += 1) {
1303
1368
  for (const [name, value] of Object.entries(files)) {
1304
- writeJson(path.join(outputDir, name), value);
1369
+ writeSiteFile(name, value);
1305
1370
  }
1306
1371
  const nextFiles = buildSiteBundle();
1307
1372
  const stable = Object.entries(nextFiles).every(([name, value]) => (
1308
- existingJson(path.join(outputDir, name)) === stableJson(value)
1373
+ existingJson(path.join(outputDir, name)) === siteFileBytes(name, value)
1309
1374
  ));
1310
1375
  files = nextFiles;
1311
1376
  if (stable) {
@@ -1316,7 +1381,7 @@ export function writeSiteBundle({ check = false } = {}) {
1316
1381
  }
1317
1382
  }
1318
1383
  for (const [name, value] of Object.entries(files)) {
1319
- writeJson(path.join(outputDir, name), value);
1384
+ writeSiteFile(name, value);
1320
1385
  }
1321
1386
  }
1322
1387
  return {
@@ -4,6 +4,11 @@ import path from "node:path";
4
4
  import { pathToFileURL } from "node:url";
5
5
  import { BUILDCHAIN_CONFIG_PATH } from "../packages/core/buildchain-layout.js";
6
6
  import { detectPackageManager, assertPackageManager } from "../packages/core/package-manager.js";
7
+ import {
8
+ appendNextDevelopmentToml,
9
+ mergeNextDevelopmentAgentInstructions,
10
+ nextDevelopmentWorkflowHeader,
11
+ } from "../packages/core/next-development-projection.js";
7
12
 
8
13
  const BUILDCHAIN_WORKFLOW_REF = "kungfu-systems/buildchain/.github/workflows/.build.yml@v4";
9
14
  const DEFAULT_PUBLICATION_LATEX_IMAGE = "ghcr.io/kungfu-systems/build-images/latex-pdf-builder";
@@ -327,7 +332,9 @@ function workflowArtifactPaths(type) {
327
332
  }
328
333
 
329
334
  function publicationWorkflowYaml() {
330
- return `name: Build
335
+ return `${nextDevelopmentWorkflowHeader()}# Commit both .buildchain/contract-lock.json and .buildchain/alpha-contract-lock.json.
336
+ # Persist only @v4 or @v4-alpha; pass temporary train/SHA runtimes through workflow_dispatch.
337
+ name: Build
331
338
 
332
339
  on:
333
340
  workflow_dispatch:
@@ -359,8 +366,10 @@ jobs:
359
366
  }
360
367
 
361
368
  function workflowYaml({ type, runnerPreset, artifactName }) {
362
- return `# Buildchain v4 lifecycle checkpoints are governed by architecture/v4-platform-stage-checkpoints.json.
369
+ return `${nextDevelopmentWorkflowHeader()}# Buildchain v4 lifecycle checkpoints are governed by architecture/v4-platform-stage-checkpoints.json.
363
370
  # Do not add undeclared runner-only inputs, outputs, environment, or provider effects.
371
+ # Commit both .buildchain/contract-lock.json and .buildchain/alpha-contract-lock.json.
372
+ # Persist only @v4 or @v4-alpha; pass temporary train/SHA runtimes through workflow_dispatch.
364
373
  name: Build
365
374
 
366
375
  on:
@@ -403,6 +412,13 @@ function writeIfAllowed(filePath, content, { force }) {
403
412
  return filePath;
404
413
  }
405
414
 
415
+ function writeManagedAgentEntry(filePath, current) {
416
+ const content = mergeNextDevelopmentAgentInstructions(current);
417
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
418
+ fs.writeFileSync(filePath, content);
419
+ return filePath;
420
+ }
421
+
406
422
  export function initBuildchainRepo({
407
423
  cwd = process.cwd(),
408
424
  type = "package",
@@ -413,7 +429,7 @@ export function initBuildchainRepo({
413
429
  } = {}) {
414
430
  const resolvedCwd = path.resolve(cwd);
415
431
  const manager = detectOrDefaultPackageManager(resolvedCwd, packageManager);
416
- const toml = (() => {
432
+ const toml = appendNextDevelopmentToml((() => {
417
433
  if (type === "package") {
418
434
  return packageToml(resolvedCwd, manager);
419
435
  }
@@ -433,7 +449,12 @@ export function initBuildchainRepo({
433
449
  return anchoredPackageToml(resolvedCwd, manager);
434
450
  }
435
451
  throw new Error("init --type must be one of package, native, web-surface, infra-contract, publication-artifact, or anchored-package");
436
- })();
452
+ })());
453
+
454
+ const agentsPath = path.join(resolvedCwd, "AGENTS.md");
455
+ const currentAgents = fs.existsSync(agentsPath)
456
+ ? fs.readFileSync(agentsPath, "utf8")
457
+ : "";
437
458
 
438
459
  const written = [
439
460
  writeIfAllowed(path.join(resolvedCwd, BUILDCHAIN_CONFIG_PATH), toml, { force }),
@@ -448,6 +469,7 @@ export function initBuildchainRepo({
448
469
  }),
449
470
  { force },
450
471
  ),
472
+ writeManagedAgentEntry(agentsPath, currentAgents),
451
473
  ];
452
474
 
453
475
  if (type === "anchored-package" && !fs.existsSync(path.join(resolvedCwd, "release.json"))) {
@@ -82,6 +82,10 @@ export function inspectArtifactSigningRequests({
82
82
  if (seen.has(key))
83
83
  throw new Error(`duplicate artifact signing request: ${key}`);
84
84
  seen.add(key);
85
+ const {
86
+ entitlementsProfile = "none",
87
+ entitlementsPaths = [],
88
+ } = request.signature;
85
89
  const item = {
86
90
  id: request.artifact.id,
87
91
  slug: safeId(request.artifact.id),
@@ -104,6 +108,8 @@ export function inspectArtifactSigningRequests({
104
108
  sourceSha: request.source.sha,
105
109
  sourceTreeSha: request.source.treeSha,
106
110
  transportFormat: request.artifact.transport?.format || "",
111
+ entitlementsProfile,
112
+ entitlementsPaths: entitlementsPaths.join(","),
107
113
  };
108
114
  if (request.signature.profile === "detached-signature-v1")
109
115
  matrices.detached.push(item);