@kungfu-tech/buildchain 2.14.16-alpha.0 → 2.14.17-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.
@@ -4,7 +4,7 @@
4
4
  "product": {
5
5
  "name": "Buildchain",
6
6
  "package": "@kungfu-tech/buildchain",
7
- "version": "2.14.16-alpha.0",
7
+ "version": "2.14.17-alpha.0",
8
8
  "repository": "https://github.com/kungfu-systems/buildchain"
9
9
  },
10
10
  "majorLine": "v2",
@@ -604,7 +604,7 @@
604
604
  "agents can discover supported Node APIs without importing internal file paths"
605
605
  ],
606
606
  "breakingDigest": "sha256:48f925608d3e2131d90936b07dc2a30341204cae3e6e785c0f77d61ad755c945",
607
- "auditDigest": "sha256:c026509d1fde0a1828ea7d8691f4dfc1d14686ae92a140f3d2350252699d70b3"
607
+ "auditDigest": "sha256:8005d01fa6c771f466c77629f0589b361fc43a3a4f04b7d88bc1645d33895a51"
608
608
  },
609
609
  {
610
610
  "contractVersion": 1,
@@ -2913,5 +2913,5 @@
2913
2913
  }
2914
2914
  ],
2915
2915
  "compatibilityDigest": "sha256:cdf588422ec6b460bd6f631400efa6e361a045e052c8967d6c50fadd7aa4dd90",
2916
- "contractDigest": "sha256:1eb4a09877bfb2efea892d7125f0e3327f67e578f11fb6b10d044f4b6d34f987"
2916
+ "contractDigest": "sha256:fe7adf9ed1c1a0b14b29fef1eb72205ae29c9558806c9b35bfcc258f07d422a8"
2917
2917
  }
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "contract": "kungfu-buildchain-site-bundle",
4
- "generatedAt": "2026-07-22T10:03:39.987Z",
5
- "publishedAt": "2026-07-22T10:03:39.987Z",
4
+ "generatedAt": "2026-07-22T15:29:55.552Z",
5
+ "publishedAt": "2026-07-22T15:29:55.552Z",
6
6
  "reproducible": true,
7
7
  "timestampPolicy": "ci-injected",
8
8
  "deterministicInputs": [
@@ -19,7 +19,7 @@
19
19
  "declared Buildchain surface manifest contract"
20
20
  ],
21
21
  "sourceDateEpoch": "0",
22
- "sourceRevision": "473c1be9602573a533aac703e8f0802eda27e430",
22
+ "sourceRevision": "a013078fdf88b5b850e48e93faf58de582130440",
23
23
  "timestampPolicyDetails": {
24
24
  "contract": "kungfu-buildchain-surface-timestamp-policy",
25
25
  "timestampFields": [
@@ -37,7 +37,7 @@
37
37
  },
38
38
  "package": {
39
39
  "name": "@kungfu-tech/buildchain",
40
- "version": "2.14.16-alpha.0",
40
+ "version": "2.14.17-alpha.0",
41
41
  "versionSource": "package.json#version"
42
42
  },
43
43
  "source": {
@@ -4,7 +4,7 @@
4
4
  "product": {
5
5
  "id": "kungfu-tech-buildchain",
6
6
  "name": "@kungfu-tech/buildchain",
7
- "version": "2.14.16-alpha.0",
7
+ "version": "2.14.17-alpha.0",
8
8
  "repository": "https://github.com/kungfu-systems/buildchain"
9
9
  },
10
10
  "source": {
@@ -307,7 +307,7 @@
307
307
  "specifier": "@kungfu-tech/buildchain/publication-control-plane-audit",
308
308
  "export": "./publication-control-plane-audit",
309
309
  "target": "./packages/core/publication-control-plane-audit.js",
310
- "digest": "sha256:f9cab9f0aabee62ed5a054062beb56b2ec7c4251002cf7416fd561322a405bd8",
310
+ "digest": "sha256:8220ad9cdf7fb9d2f361cf7b066aad039412a378350676edfdb4c1f7019cda20",
311
311
  "summary": "Read-only publication control-plane snapshot evaluation APIs.",
312
312
  "capabilityGroup": "release-passport-trust",
313
313
  "audience": [
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "contract": "kungfu-buildchain-publication-release-registry",
4
- "generatedAt": "2026-07-22T10:03:39.987Z",
5
- "publishedAt": "2026-07-22T10:03:39.987Z",
4
+ "generatedAt": "2026-07-22T15:29:55.552Z",
5
+ "publishedAt": "2026-07-22T15:29:55.552Z",
6
6
  "reproducible": true,
7
7
  "timestampPolicy": "ci-injected",
8
8
  "deterministicInputs": [
@@ -19,7 +19,7 @@
19
19
  "declared Buildchain surface manifest contract"
20
20
  ],
21
21
  "sourceDateEpoch": "0",
22
- "sourceRevision": "473c1be9602573a533aac703e8f0802eda27e430",
22
+ "sourceRevision": "a013078fdf88b5b850e48e93faf58de582130440",
23
23
  "timestampPolicyDetails": {
24
24
  "contract": "kungfu-buildchain-surface-timestamp-policy",
25
25
  "timestampFields": [
@@ -32,7 +32,7 @@
32
32
  },
33
33
  "package": {
34
34
  "name": "@kungfu-tech/buildchain",
35
- "version": "2.14.16-alpha.0",
35
+ "version": "2.14.17-alpha.0",
36
36
  "versionSource": "package.json#version"
37
37
  },
38
38
  "sourceKind": "package-site-bundle",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "contract": "kungfu-buildchain-site-manifest",
4
- "generatedAt": "2026-07-22T10:03:39.987Z",
5
- "publishedAt": "2026-07-22T10:03:39.987Z",
4
+ "generatedAt": "2026-07-22T15:29:55.552Z",
5
+ "publishedAt": "2026-07-22T15:29:55.552Z",
6
6
  "reproducible": true,
7
7
  "timestampPolicy": "ci-injected",
8
8
  "deterministicInputs": [
@@ -19,7 +19,7 @@
19
19
  "declared Buildchain surface manifest contract"
20
20
  ],
21
21
  "sourceDateEpoch": "0",
22
- "sourceRevision": "473c1be9602573a533aac703e8f0802eda27e430",
22
+ "sourceRevision": "a013078fdf88b5b850e48e93faf58de582130440",
23
23
  "timestampPolicyDetails": {
24
24
  "contract": "kungfu-buildchain-surface-timestamp-policy",
25
25
  "timestampFields": [
@@ -37,7 +37,7 @@
37
37
  },
38
38
  "package": {
39
39
  "name": "@kungfu-tech/buildchain",
40
- "version": "2.14.16-alpha.0",
40
+ "version": "2.14.17-alpha.0",
41
41
  "versionSource": "package.json#version"
42
42
  },
43
43
  "entrypoint": "buildchain-site.json",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kungfu-tech/buildchain",
3
- "version": "2.14.16-alpha.0",
3
+ "version": "2.14.17-alpha.0",
4
4
  "private": false,
5
5
  "description": "Buildchain Release Passport, release governance, CLI toolkit, and site facts.",
6
6
  "repository": "https://github.com/kungfu-systems/buildchain",
@@ -1,5 +1,41 @@
1
1
  import { createPublicationControlPlaneAudit, publicationAuthorityDigest } from "./publication-authority.js";
2
2
 
3
+ export const BUILDCHAIN_RELEASE_RECONCILIATION_PATHS = Object.freeze([
4
+ ".buildchain/release-impact.json",
5
+ "dist/site/buildchain-contract.json",
6
+ "dist/site/buildchain-site.json",
7
+ "dist/site/kfd-upstream-aggregate.json",
8
+ "dist/site/publication-registry.json",
9
+ "dist/site/site-manifest.json",
10
+ "package.json",
11
+ ]);
12
+
13
+ export function evaluateBuildchainReleaseReconciliation({
14
+ repository,
15
+ publicationVersion,
16
+ packageVersion,
17
+ message,
18
+ parentSha,
19
+ changedPaths,
20
+ } = {}) {
21
+ const normalizedPaths = Array.isArray(changedPaths) ? changedPaths.map(String) : [];
22
+ const allowedPaths = new Set(BUILDCHAIN_RELEASE_RECONCILIATION_PATHS);
23
+ return {
24
+ qualifying: repository === "kungfu-systems/buildchain" &&
25
+ /^\d+\.\d+\.\d+$/.test(String(publicationVersion || "")) &&
26
+ message === `chore(release): release v${publicationVersion}` &&
27
+ packageVersion === publicationVersion &&
28
+ normalizedPaths.length > 0 &&
29
+ normalizedPaths.every((entry) => allowedPaths.has(entry)) &&
30
+ /^[0-9a-f]{40}$/.test(String(parentSha || "")),
31
+ parentSha: String(parentSha || ""),
32
+ version: String(publicationVersion || ""),
33
+ packageVersion: String(packageVersion || ""),
34
+ message: String(message || ""),
35
+ changedPaths: normalizedPaths,
36
+ };
37
+ }
38
+
3
39
  function fact(id, pass, observed) {
4
40
  return {
5
41
  id,
@@ -77,6 +113,15 @@ export function evaluatePublicationControlPlaneSnapshot({
77
113
  branchPolicy.requiredStatusCheckMatchCount === 1
78
114
  )
79
115
  );
116
+ const authorizationSha = branchPolicy.authorizationSha || branchPolicy.sourceSha;
117
+ const sourceAuthorizationPass = branchPolicy.sourceSha === authorizationSha || (
118
+ branchPolicy.releaseReconciliation?.qualifying === true &&
119
+ branchPolicy.releaseReconciliation.parentSha === authorizationSha &&
120
+ /^\d+\.\d+\.\d+$/.test(String(branchPolicy.releaseReconciliation.version || "")) &&
121
+ branchPolicy.releaseReconciliation.packageVersion === branchPolicy.releaseReconciliation.version &&
122
+ Array.isArray(branchPolicy.releaseReconciliation.changedPaths) &&
123
+ branchPolicy.releaseReconciliation.changedPaths.length > 0
124
+ );
80
125
  const providerTransactionBranchPass = branchPolicy.ref === branch &&
81
126
  branchPolicy.policyMode === "provider-enforced-transaction" &&
82
127
  branchPolicy.protected === true &&
@@ -88,6 +133,7 @@ export function evaluatePublicationControlPlaneSnapshot({
88
133
  /^[0-9a-f]{40}$/i.test(String(branchPolicy.requiredCheckSha || "")) &&
89
134
  branchPolicy.requiredCheckSha === branchPolicy.pullRequestHeadSha &&
90
135
  branchPolicy.sourceSha === branchPolicy.headSha &&
136
+ sourceAuthorizationPass &&
91
137
  branchPolicy.mergedPullRequest === true &&
92
138
  branchPolicy.baseRef === branch &&
93
139
  branchPolicy.headRepository === repository &&
@@ -4,7 +4,10 @@ import fs from "node:fs";
4
4
  import path from "node:path";
5
5
  import { execFileSync } from "node:child_process";
6
6
 
7
- import { validateControllerReceipt } from "../packages/core/controller-evidence.js";
7
+ import {
8
+ validateControllerPlan,
9
+ validateControllerReceipt,
10
+ } from "../packages/core/controller-evidence.js";
8
11
  import {
9
12
  createPublicationAdmission,
10
13
  createPublicationGateDecision,
@@ -102,15 +105,23 @@ function main() {
102
105
  const controllerRoot = path.join(evidenceRoot, "binary-controller");
103
106
  const manifest = readJson(oneFile(passportRoot, "buildchain-release-bundle.json"));
104
107
  const archivePath = oneFile(passportRoot, "buildchain-release-bundle.tar.gz");
108
+ const controllerPlan = readJson(oneFile(controllerRoot, "plan.json"));
105
109
  const controllerReceipt = readJson(oneFile(controllerRoot, "receipt.json"));
106
110
  validateBundle(manifest, archivePath, { sourceSha, releaseTag });
107
111
 
108
- const runtimeSha = execFileSync("git", ["-C", runtimeRoot, "rev-parse", "HEAD"], { encoding: "utf8" })
112
+ const authorityRuntimeSha = execFileSync("git", ["-C", runtimeRoot, "rev-parse", "HEAD"], { encoding: "utf8" })
109
113
  .trim()
110
114
  .toLowerCase();
115
+ if (!/^[0-9a-f]{40}$/.test(authorityRuntimeSha)) {
116
+ throw new Error("publication authority runtime SHA is invalid");
117
+ }
118
+ const controllerPlanValidation = validateControllerPlan(controllerPlan);
119
+ if (!controllerPlanValidation.ok || !controllerPlanValidation.qualifying) {
120
+ throw new Error(`binary distribution controller plan did not qualify: ${controllerPlanValidation.issues.join("; ")}`);
121
+ }
111
122
  const controllerValidation = validateControllerReceipt(controllerReceipt, {
123
+ plan: controllerPlan,
112
124
  expectedSourceSha: sourceSha,
113
- expectedRuntimeSha: runtimeSha,
114
125
  });
115
126
  if (!controllerValidation.ok || !controllerValidation.qualifying) {
116
127
  throw new Error(`binary distribution controller receipt did not qualify: ${controllerValidation.issues.join("; ")}`);
@@ -118,6 +129,7 @@ function main() {
118
129
  if (controllerReceipt.controller?.id !== "binary-distribution") {
119
130
  throw new Error("binary distribution controller receipt has the wrong controller id");
120
131
  }
132
+ const runtimeSha = controllerReceipt.runtime.sha;
121
133
 
122
134
  const controlPlaneAudit = readJson(required("BUILDCHAIN_CONTROL_PLANE_AUDIT_PATH"));
123
135
  const registry = readJson(path.join(runtimeRoot, "dist/site/publication-authority-registry.json"));
@@ -3,7 +3,10 @@ import { spawnSync } from "node:child_process";
3
3
  import fs from "node:fs";
4
4
  import path from "node:path";
5
5
 
6
- import { evaluatePublicationControlPlaneSnapshot } from "../packages/core/publication-control-plane-audit.js";
6
+ import {
7
+ evaluateBuildchainReleaseReconciliation,
8
+ evaluatePublicationControlPlaneSnapshot,
9
+ } from "../packages/core/publication-control-plane-audit.js";
7
10
 
8
11
  function flag(name, fallback = "") {
9
12
  const index = process.argv.indexOf(`--${name}`);
@@ -199,6 +202,8 @@ function main() {
199
202
  const sourceSha = flag("source-sha").toLowerCase();
200
203
  const packageName = flag("package", "@kungfu-tech/buildchain");
201
204
  const publisherMode = flag("publisher-mode", "npm-trusted-publisher");
205
+ const publicationVersion = flag("publication-version");
206
+ const allowReleaseReconciliation = process.argv.includes("--allow-release-reconciliation");
202
207
  if (!repository || !branch) throw new Error("--repository and --branch are required");
203
208
 
204
209
  const encodedWorkflow = workflowPath.split("/").map(encodeURIComponent).join("/");
@@ -260,13 +265,51 @@ function main() {
260
265
  if (!/^[0-9a-f]{40}$/.test(sourceSha)) {
261
266
  throw new Error("--source-sha is required when detailed branch policy is not readable");
262
267
  }
263
- const pullRequests = githubJson(`repos/${repository}/commits/${sourceSha}/pulls`, "source pull-request lineage");
264
- const mergedPullRequest = (Array.isArray(pullRequests) ? pullRequests : []).find((entry) =>
268
+ const sourceCommit = githubJson(`repos/${repository}/commits/${sourceSha}`, "source commit");
269
+ const sourceParents = Array.isArray(sourceCommit.parents) ? sourceCommit.parents.map((entry) => String(entry?.sha || "").toLowerCase()) : [];
270
+ const sourceChangedPaths = Array.isArray(sourceCommit.files) ? sourceCommit.files.map((entry) => String(entry?.filename || "")) : [];
271
+ const sourceMessage = String(sourceCommit.commit?.message || "").split("\n", 1)[0];
272
+ let authorizationSha = sourceSha;
273
+ let releaseReconciliation = {
274
+ qualifying: false,
275
+ parentSha: "",
276
+ version: publicationVersion,
277
+ message: sourceMessage,
278
+ changedPaths: sourceChangedPaths,
279
+ };
280
+ let pullRequests = githubJson(`repos/${repository}/commits/${authorizationSha}/pulls`, "source pull-request lineage");
281
+ let mergedPullRequest = (Array.isArray(pullRequests) ? pullRequests : []).find((entry) =>
265
282
  entry?.merged_at &&
266
- entry.merge_commit_sha === sourceSha &&
283
+ entry.merge_commit_sha === authorizationSha &&
267
284
  entry.base?.ref === branch &&
268
285
  entry.head?.repo?.full_name === repository
269
286
  );
287
+ if (!mergedPullRequest && allowReleaseReconciliation) {
288
+ const packageFile = githubJson(
289
+ `repos/${repository}/contents/package.json?ref=${encodeURIComponent(sourceSha)}`,
290
+ "release reconciliation package metadata",
291
+ );
292
+ const packageJson = JSON.parse(Buffer.from(String(packageFile.content || ""), "base64").toString("utf8"));
293
+ const parentSha = sourceParents.length === 1 ? sourceParents[0] : "";
294
+ releaseReconciliation = evaluateBuildchainReleaseReconciliation({
295
+ repository,
296
+ publicationVersion,
297
+ packageVersion: packageJson.version,
298
+ message: sourceMessage,
299
+ parentSha,
300
+ changedPaths: sourceChangedPaths,
301
+ });
302
+ if (releaseReconciliation.qualifying) {
303
+ authorizationSha = parentSha;
304
+ pullRequests = githubJson(`repos/${repository}/commits/${authorizationSha}/pulls`, "release parent pull-request lineage");
305
+ mergedPullRequest = (Array.isArray(pullRequests) ? pullRequests : []).find((entry) =>
306
+ entry?.merged_at &&
307
+ entry.merge_commit_sha === authorizationSha &&
308
+ entry.base?.ref === branch &&
309
+ entry.head?.repo?.full_name === repository
310
+ );
311
+ }
312
+ }
270
313
  const reviews = mergedPullRequest
271
314
  ? githubJson(`repos/${repository}/pulls/${mergedPullRequest.number}/reviews?per_page=100`, "source pull-request reviews")
272
315
  : [];
@@ -316,7 +359,9 @@ function main() {
316
359
  requiredCheckAppId: requiredCheckSource?.app_id || 0,
317
360
  requiredCheckSha: pullRequestHeadSha,
318
361
  sourceSha,
362
+ authorizationSha,
319
363
  headSha: String(branchState.commit?.sha || "").toLowerCase(),
364
+ releaseReconciliation,
320
365
  mergedPullRequest: Boolean(mergedPullRequest),
321
366
  pullRequestNumber: mergedPullRequest?.number || 0,
322
367
  pullRequestHeadSha,
@@ -354,7 +354,7 @@ function publicationImmutablePolicy({ artifactRoot, binding }) {
354
354
  throw new Error(`declared immutable publication prefix does not exist in artifact: ${prefix}`);
355
355
  }
356
356
  }
357
- const preservedRoots = [...new Set(declaredPrefixes.map((prefix) => prefix.split("/")[0]))].sort();
357
+ const preservedRoots = declaredPrefixes;
358
358
  const files = preservedRoots
359
359
  .flatMap((root) => listFiles(surfaceRoot, root))
360
360
  .map((filePath) => ({