@kungfu-tech/buildchain 2.14.16 → 2.14.17-alpha.1

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",
7
+ "version": "2.14.17-alpha.1",
8
8
  "repository": "https://github.com/kungfu-systems/buildchain"
9
9
  },
10
10
  "majorLine": "v2",
@@ -256,7 +256,7 @@
256
256
  "channel-aware artifact host facts are checked against the deploy plan before adapter side effects"
257
257
  ],
258
258
  "breakingDigest": "sha256:da569f90374e878948e3d5160ed9929338ce0572473ca8ee54867b0fe1aaeace",
259
- "auditDigest": "sha256:cd620b10103c27137ae17f23583753adfe2f3ef501e511f7380431aa95f08b18"
259
+ "auditDigest": "sha256:4a7c696ec399c14aa3170fdd24adac0d624bd33db6a2639c489e2b58726c190b"
260
260
  },
261
261
  {
262
262
  "contractVersion": 1,
@@ -323,6 +323,9 @@
323
323
  "publish transactions can require a resolved publish-gate source lock to prevent floating-ref drift",
324
324
  "semver GitHub Releases are created or updated only after transaction completion, with prerelease/latest metadata bound to the authoritative publication channel and tag syntax retained as the fallback for ordinary callers"
325
325
  ],
326
+ "compatibleBreakingDigests": [
327
+ "sha256:a59f0910e6df842e7699139472e5dd69ac2fdd7f7213bf2cb346d1d622556874"
328
+ ],
326
329
  "breakingDigest": "sha256:6147c0a8d5c36bfaa6021871574e1fc28192a3f1b8cfdae4d24ef3059ac1ebda",
327
330
  "auditDigest": "sha256:ff220542fd1cb21fc4780d0bb31eb9f78d44d70746b6c4364483e104b48ae083"
328
331
  },
@@ -604,7 +607,7 @@
604
607
  "agents can discover supported Node APIs without importing internal file paths"
605
608
  ],
606
609
  "breakingDigest": "sha256:48f925608d3e2131d90936b07dc2a30341204cae3e6e785c0f77d61ad755c945",
607
- "auditDigest": "sha256:c026509d1fde0a1828ea7d8691f4dfc1d14686ae92a140f3d2350252699d70b3"
610
+ "auditDigest": "sha256:915daa5d9dd8879a356865d2ab9336a8f2fb9806b43f5ba18eadfe448e6d8304"
608
611
  },
609
612
  {
610
613
  "contractVersion": 1,
@@ -1850,7 +1853,7 @@
1850
1853
  "missing receipts are non-qualifying and must not be represented as a successful controller run"
1851
1854
  ],
1852
1855
  "breakingDigest": "sha256:f14825324a16b51c2e9ed708ebe64e1932e05b6d5e0866f83aea8439decb4a27",
1853
- "auditDigest": "sha256:cd620b10103c27137ae17f23583753adfe2f3ef501e511f7380431aa95f08b18"
1856
+ "auditDigest": "sha256:4a7c696ec399c14aa3170fdd24adac0d624bd33db6a2639c489e2b58726c190b"
1854
1857
  },
1855
1858
  {
1856
1859
  "contractVersion": 1,
@@ -2913,5 +2916,5 @@
2913
2916
  }
2914
2917
  ],
2915
2918
  "compatibilityDigest": "sha256:cdf588422ec6b460bd6f631400efa6e361a045e052c8967d6c50fadd7aa4dd90",
2916
- "contractDigest": "sha256:81c0ed79269d4b0c2f94c11cc316069db7b4264814f3170b3877a9f960ac0320"
2919
+ "contractDigest": "sha256:9d5bef7245674767352cc2746d507d556a11d685502120c00176f1a15bade2ba"
2917
2920
  }
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "contract": "kungfu-buildchain-site-bundle",
4
- "generatedAt": "2026-07-22T14:12:30.154Z",
5
- "publishedAt": "2026-07-22T14:12:30.154Z",
4
+ "generatedAt": "2026-07-22T23:30:42.191Z",
5
+ "publishedAt": "2026-07-22T23:30:42.191Z",
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": "f75ebb90c708bfed893b89f59bbb5ea77e5e45cb",
22
+ "sourceRevision": "7c7ff64cd7cd3b34ad377999ed8aa22b1e1d8d93",
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",
40
+ "version": "2.14.17-alpha.1",
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",
7
+ "version": "2.14.17-alpha.1",
8
8
  "repository": "https://github.com/kungfu-systems/buildchain"
9
9
  },
10
10
  "source": {
@@ -99,7 +99,7 @@
99
99
  "specifier": "@kungfu-tech/buildchain/buildchain-contract",
100
100
  "export": "./buildchain-contract",
101
101
  "target": "./packages/core/buildchain-contract.js",
102
- "digest": "sha256:da92e920f6cc00dd5e21405f06580c2fa943eead3b755dc36b6c3a2381e68423",
102
+ "digest": "sha256:1e5f8a1741a0a98116e754ef0874337db4c1821bb7a153ab398009145509681c",
103
103
  "summary": "Runtime contract world and compatibility digest APIs for floating-ref drift checks.",
104
104
  "capabilityGroup": "governance-versioning",
105
105
  "audience": [
@@ -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-22T14:12:30.154Z",
5
- "publishedAt": "2026-07-22T14:12:30.154Z",
4
+ "generatedAt": "2026-07-22T23:30:42.191Z",
5
+ "publishedAt": "2026-07-22T23:30:42.191Z",
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": "f75ebb90c708bfed893b89f59bbb5ea77e5e45cb",
22
+ "sourceRevision": "7c7ff64cd7cd3b34ad377999ed8aa22b1e1d8d93",
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",
35
+ "version": "2.14.17-alpha.1",
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-22T14:12:30.154Z",
5
- "publishedAt": "2026-07-22T14:12:30.154Z",
4
+ "generatedAt": "2026-07-22T23:30:42.191Z",
5
+ "publishedAt": "2026-07-22T23:30:42.191Z",
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": "f75ebb90c708bfed893b89f59bbb5ea77e5e45cb",
22
+ "sourceRevision": "7c7ff64cd7cd3b34ad377999ed8aa22b1e1d8d93",
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",
40
+ "version": "2.14.17-alpha.1",
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",
3
+ "version": "2.14.17-alpha.1",
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",
@@ -351,6 +351,9 @@ export function createBuildchainContractWorld({
351
351
  "publish transactions can require a resolved publish-gate source lock to prevent floating-ref drift",
352
352
  "semver GitHub Releases are created or updated only after transaction completion, with prerelease/latest metadata bound to the authoritative publication channel and tag syntax retained as the fallback for ordinary callers",
353
353
  ],
354
+ compatibleBreakingDigests: [
355
+ "sha256:a59f0910e6df842e7699139472e5dd69ac2fdd7f7213bf2cb346d1d622556874",
356
+ ],
354
357
  }),
355
358
  surface(root, {
356
359
  id: "report-buildchain-issue-action",
@@ -758,7 +761,11 @@ export function evaluateBuildchainContractLock({
758
761
  reasons.push(`surface removed: ${oldSurface.id}`);
759
762
  continue;
760
763
  }
761
- if (nextSurface.breakingDigest !== oldSurface.breakingDigest) {
764
+ const compatibleBreakingDigests = new Set(nextSurface.compatibleBreakingDigests || []);
765
+ if (
766
+ nextSurface.breakingDigest !== oldSurface.breakingDigest
767
+ && !compatibleBreakingDigests.has(oldSurface.breakingDigest)
768
+ ) {
762
769
  reasons.push(`surface breaking digest changed: ${oldSurface.id}`);
763
770
  }
764
771
  }
@@ -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) => ({
@@ -8,6 +8,7 @@ const TRUSTED_PERMISSIONS = new Set(["write", "maintain", "admin"]);
8
8
 
9
9
  export function resolveWebSurfaceProductionDecision({
10
10
  eventName,
11
+ eventAction = "",
11
12
  refName,
12
13
  repository,
13
14
  sourceSha,
@@ -36,9 +37,11 @@ export function resolveWebSurfaceProductionDecision({
36
37
  reason: trusted ? "trusted-manual-dispatch" : "manual-actor-permission-insufficient",
37
38
  });
38
39
  }
40
+ const reviewedReleaseEvent =
41
+ (eventName === "push" && refName === "main") ||
42
+ (eventName === "pull_request" && eventAction === "closed");
39
43
  if (
40
- eventName === "push" &&
41
- refName === "main" &&
44
+ reviewedReleaseEvent &&
42
45
  productionApply === true &&
43
46
  productionReleaseOnMain === true &&
44
47
  releaseApproved === true
@@ -103,9 +106,10 @@ async function main() {
103
106
  }
104
107
  const decision = resolveWebSurfaceProductionDecision({
105
108
  eventName,
109
+ eventAction: process.env.GITHUB_EVENT_ACTION,
106
110
  refName: process.env.GITHUB_REF_NAME,
107
111
  repository,
108
- sourceSha: process.env.GITHUB_SHA,
112
+ sourceSha: process.env.BUILDCHAIN_PRODUCTION_SOURCE_SHA || process.env.GITHUB_SHA,
109
113
  actor,
110
114
  productionApply: bool("BUILDCHAIN_PRODUCTION_APPLY"),
111
115
  productionApproved: bool("BUILDCHAIN_PRODUCTION_APPROVED"),