@kungfu-tech/buildchain 4.0.2-alpha.18 → 4.0.2-alpha.19

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.
@@ -19,6 +19,7 @@
19
19
  "exactShaExecutionAuthority": true,
20
20
  "consumerSourceMutationPerIncident": false,
21
21
  "consumerAdmission": "verified-caller-exact-repository-workflow-and-source",
22
+ "reviewRuntimeBinding": "reviewed-head-or-protected-alpha-merge-to-exact-runtime",
22
23
  "buildchainReleasePromotionPerIncident": false,
23
24
  "selfDogfoodUsesPublicContract": true
24
25
  },
@@ -23,12 +23,12 @@
23
23
  "statuses": "write"
24
24
  },
25
25
  "contractRoots": [
26
- "sha256:00609cb90d5abb76801ff66235606da025c6be5b071a6e69c1f87dda69cc45e6",
27
- "sha256:0b3e13541e5e1b11b1f6f719ee45fa5828f17de41cd832895ff9b15add03a98b",
28
26
  "sha256:65a0c2fc3faecaddf5076fff086b5d6e12eb9ba27796efc10aed19f2d93b9457",
29
- "sha256:7ca5dffff9eaff8b9265d35c7d8573b8cedd56a69dc26c12e4a5c26e723412b0",
27
+ "sha256:82c1924f4573f35a895361f9134df66a1868dc921d2c1db8707890b8ca06d61e",
30
28
  "sha256:83d6b141d3c60ac5b861029a7c6241ee0ca8e6674dd346d27d476151dd16ea6c",
31
29
  "sha256:b6737ed958e8f53f7770b1c214c092591573ad63af41e05797117d9b7b212ed8",
30
+ "sha256:ca0592275354f0690756e3f11accdd23615987827c346618c50c2e8a2807ad4d",
31
+ "sha256:cf3c5a79de580525953e1fc02b2b2937a1d1a50219b4464510dd5b4725ca9ca5",
32
32
  "sha256:d6ad9cf661c0ba3825cabdc7185fd122a60fc1929dfc799cda3352650588663f"
33
33
  ],
34
34
  "targetRef": "dev/v4/v4.0",
@@ -4,7 +4,7 @@
4
4
  "product": {
5
5
  "name": "Buildchain",
6
6
  "package": "@kungfu-tech/buildchain",
7
- "version": "4.0.2-alpha.18",
7
+ "version": "4.0.2-alpha.19",
8
8
  "repository": "https://github.com/kungfu-systems/buildchain"
9
9
  },
10
10
  "majorLine": "v4",
@@ -5444,5 +5444,5 @@
5444
5444
  "compatibilityFactCutRoot": "sha256:f61b975d4a96c921cc4bd37fb3ed9a0596b47004fe34dc7219979d697e3707f9",
5445
5445
  "compatibilityProofRegistryRoot": "sha256:b7194b811e4d3af2df4390bc4d1731e16a86215bd64ee18cb630dd5492f4fb63",
5446
5446
  "compatibilityDigest": "sha256:20411029d83211dff426fb6535a608902129844a5ccb4788db77d3f81becb839",
5447
- "contractDigest": "sha256:c4229b90af47dcb0c9185125eccf3f7efce2864193a9965c33bc3265e5e7443d"
5447
+ "contractDigest": "sha256:c2b9ad11851e7dd02ac71124b936e302ed5f1bd44a93442c0f447b3207e1f7c8"
5448
5448
  }
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "contract": "kungfu-buildchain-site-bundle",
4
- "generatedAt": "2026-09-02T08:40:46.000Z",
5
- "publishedAt": "2026-09-02T08:40:46.000Z",
4
+ "generatedAt": "2026-09-02T11:40:32.000Z",
5
+ "publishedAt": "2026-09-02T11:40:32.000Z",
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": "22de41c1a85ebce3c1b97eb74e900f42539023de",
22
+ "sourceRevision": "8e04604d6eca3d33cdcf08bc2ebab7cf9846d02b",
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": "4.0.2-alpha.18",
40
+ "version": "4.0.2-alpha.19",
41
41
  "versionSource": "package.json#version"
42
42
  },
43
43
  "source": {
@@ -21,7 +21,7 @@
21
21
  "contract": "kungfu-buildchain-public-surface-reverse-audit",
22
22
  "path": "dist/site/public-surface-audit.json",
23
23
  "status": "passed",
24
- "sha256": "11894452f93a79ae1fa288151026d1deb1a28386b19676cce7ffffbedf5a4dab",
24
+ "sha256": "fc6a90595c540584eb3b8250611a4188c60d429403d7aa090fee2267fe8d5af6",
25
25
  "summary": {
26
26
  "cliCommandCount": 117,
27
27
  "workflowCount": 74,
@@ -246,7 +246,7 @@
246
246
  "contract": "kungfu-buildchain-public-surface-reverse-audit",
247
247
  "path": "dist/site/public-surface-audit.json",
248
248
  "status": "passed",
249
- "sha256": "11894452f93a79ae1fa288151026d1deb1a28386b19676cce7ffffbedf5a4dab",
249
+ "sha256": "fc6a90595c540584eb3b8250611a4188c60d429403d7aa090fee2267fe8d5af6",
250
250
  "summary": {
251
251
  "cliCommandCount": 117,
252
252
  "workflowCount": 74,
@@ -4,7 +4,7 @@
4
4
  "product": {
5
5
  "id": "kungfu-tech-buildchain",
6
6
  "name": "@kungfu-tech/buildchain",
7
- "version": "4.0.2-alpha.18",
7
+ "version": "4.0.2-alpha.19",
8
8
  "repository": "https://github.com/kungfu-systems/buildchain"
9
9
  },
10
10
  "source": {
@@ -8904,7 +8904,7 @@
8904
8904
  "workflowRegistryPath": "dist/site/workflow-registry.json",
8905
8905
  "pageRegistryPath": "dist/site/page-registry.json",
8906
8906
  "cliRegistryDigest": "fbc23073bbae240489a2f826b2c26daadc58e704050c5f8df366509f5c5a1c3e",
8907
- "workflowRegistryDigest": "9456d5097ff8a07fbb4d711c0c2b738349f2cb89efcfcad180018779c2986790",
8907
+ "workflowRegistryDigest": "646fd4e2fdb5b774648fd2a05b2579436069c8dfa42a846e423ed82b281d7c64",
8908
8908
  "pageRegistryDigest": "ae0b1b9c7b883027cf53403221ff2fe2e41ad1aa4d16851d4550e89947d6d6d7"
8909
8909
  },
8910
8910
  "comparison": {
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "contract": "kungfu-buildchain-publication-release-registry",
4
- "generatedAt": "2026-09-02T08:40:46.000Z",
5
- "publishedAt": "2026-09-02T08:40:46.000Z",
4
+ "generatedAt": "2026-09-02T11:40:32.000Z",
5
+ "publishedAt": "2026-09-02T11:40:32.000Z",
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": "22de41c1a85ebce3c1b97eb74e900f42539023de",
22
+ "sourceRevision": "8e04604d6eca3d33cdcf08bc2ebab7cf9846d02b",
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": "4.0.2-alpha.18",
35
+ "version": "4.0.2-alpha.19",
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-09-02T08:40:46.000Z",
5
- "publishedAt": "2026-09-02T08:40:46.000Z",
4
+ "generatedAt": "2026-09-02T11:40:32.000Z",
5
+ "publishedAt": "2026-09-02T11:40:32.000Z",
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": "22de41c1a85ebce3c1b97eb74e900f42539023de",
22
+ "sourceRevision": "8e04604d6eca3d33cdcf08bc2ebab7cf9846d02b",
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": "4.0.2-alpha.18",
40
+ "version": "4.0.2-alpha.19",
41
41
  "versionSource": "package.json#version"
42
42
  },
43
43
  "entrypoint": "buildchain-site.json",
@@ -1926,7 +1926,7 @@
1926
1926
  "status": "preview",
1927
1927
  "owner": "buildchain-workflows",
1928
1928
  "maturity": "preview",
1929
- "introducedVersion": "4.0.2-alpha.18",
1929
+ "introducedVersion": "4.0.2-alpha.19",
1930
1930
  "compatibilityPromise": "preserved-through-the-v3-major-line",
1931
1931
  "deprecationReplacement": "",
1932
1932
  "sunsetCondition": "explicit-breaking-change-review-in-a-future-major-line",
@@ -1947,7 +1947,7 @@
1947
1947
  "status": "preview",
1948
1948
  "owner": "buildchain-workflows",
1949
1949
  "maturity": "preview",
1950
- "introducedVersion": "4.0.2-alpha.18",
1950
+ "introducedVersion": "4.0.2-alpha.19",
1951
1951
  "compatibilityPromise": "preserved-through-the-v3-major-line",
1952
1952
  "deprecationReplacement": "",
1953
1953
  "sunsetCondition": "explicit-breaking-change-review-in-a-future-major-line",
@@ -1968,7 +1968,7 @@
1968
1968
  "status": "preview",
1969
1969
  "owner": "buildchain-workflows",
1970
1970
  "maturity": "preview",
1971
- "introducedVersion": "4.0.2-alpha.18",
1971
+ "introducedVersion": "4.0.2-alpha.19",
1972
1972
  "compatibilityPromise": "preserved-through-the-v3-major-line",
1973
1973
  "deprecationReplacement": "",
1974
1974
  "sunsetCondition": "explicit-breaking-change-review-in-a-future-major-line",
@@ -2019,7 +2019,7 @@
2019
2019
  "status": "preview",
2020
2020
  "owner": "buildchain-workflows",
2021
2021
  "maturity": "preview",
2022
- "introducedVersion": "4.0.2-alpha.18",
2022
+ "introducedVersion": "4.0.2-alpha.19",
2023
2023
  "compatibilityPromise": "preserved-through-the-v3-major-line",
2024
2024
  "deprecationReplacement": "",
2025
2025
  "sunsetCondition": "explicit-breaking-change-review-in-a-future-major-line",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kungfu-tech/buildchain",
3
- "version": "4.0.2-alpha.18",
3
+ "version": "4.0.2-alpha.19",
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",
@@ -345,69 +345,55 @@ function validatePolicy(value) {
345
345
  }
346
346
 
347
347
  function validateReviewEvidence(value) {
348
- exactKeys(
349
- value,
350
- [
351
- "repository",
352
- "pullRequest",
353
- "headSha",
354
- "baseRef",
355
- "approvals",
356
- "checks",
357
- "observedAt",
358
- ],
359
- "reviewEvidence",
360
- );
348
+ const hasBinding = Object.hasOwn(value || {}, "runtimeBinding");
349
+ exactKeys(value, ["repository", "pullRequest", "headSha", "baseRef", "approvals", "checks", "observedAt", ...(hasBinding ? ["runtimeBinding"] : [])], "reviewEvidence");
361
350
  const approvals = value.approvals.map((approval, index) => {
362
- exactKeys(
363
- approval,
364
- ["reviewer", "commitSha", "submittedAt"],
365
- `reviewEvidence.approvals[${index}]`,
366
- );
351
+ exactKeys(approval, ["reviewer", "commitSha", "submittedAt"], `reviewEvidence.approvals[${index}]`);
367
352
  return {
368
- reviewer: nonEmpty(
369
- approval.reviewer,
370
- `reviewEvidence.approvals[${index}].reviewer`,
371
- ),
372
- commitSha: exactSha(
373
- approval.commitSha,
374
- `reviewEvidence.approvals[${index}].commitSha`,
375
- ),
376
- submittedAt: timestamp(
377
- approval.submittedAt,
378
- `reviewEvidence.approvals[${index}].submittedAt`,
379
- ),
353
+ reviewer: nonEmpty(approval.reviewer, `reviewEvidence.approvals[${index}].reviewer`),
354
+ commitSha: exactSha(approval.commitSha, `reviewEvidence.approvals[${index}].commitSha`),
355
+ submittedAt: timestamp(approval.submittedAt, `reviewEvidence.approvals[${index}].submittedAt`),
380
356
  };
381
357
  });
382
358
  const checks = value.checks.map((check, index) => {
383
- exactKeys(
384
- check,
385
- ["name", "status", "conclusion"],
386
- `reviewEvidence.checks[${index}]`,
387
- );
359
+ const hasCommit = Object.hasOwn(check || {}, "commitSha");
360
+ exactKeys(check, ["name", "status", "conclusion", ...(hasCommit ? ["commitSha"] : [])], `reviewEvidence.checks[${index}]`);
388
361
  return {
389
362
  name: nonEmpty(check.name, `reviewEvidence.checks[${index}].name`),
390
363
  status: nonEmpty(check.status, `reviewEvidence.checks[${index}].status`),
391
- conclusion: nonEmpty(
392
- check.conclusion,
393
- `reviewEvidence.checks[${index}].conclusion`,
394
- ),
364
+ conclusion: nonEmpty(check.conclusion, `reviewEvidence.checks[${index}].conclusion`),
365
+ ...(hasCommit ? { commitSha: exactSha(check.commitSha, `reviewEvidence.checks[${index}].commitSha`) } : {}),
395
366
  };
396
367
  });
368
+ let runtimeBinding;
369
+ if (hasBinding) {
370
+ exactKeys(value.runtimeBinding, ["kind", "runtimeSha", "parentShas", "mergedAt"], "reviewEvidence.runtimeBinding");
371
+ const kind = nonEmpty(value.runtimeBinding.kind, "reviewEvidence.runtimeBinding.kind");
372
+ if (!new Set(["reviewed-head", "protected-alpha-merge"]).has(kind)) fail("invalid-runtime-binding", "review evidence runtime binding kind is unsupported");
373
+ const parentShas = value.runtimeBinding.parentShas.map((parent, index) => exactSha(parent, `reviewEvidence.runtimeBinding.parentShas[${index}]`));
374
+ if (new Set(parentShas).size !== parentShas.length) fail("invalid-runtime-binding", "review evidence runtime parents must be duplicate-free");
375
+ runtimeBinding = { kind, runtimeSha: exactSha(value.runtimeBinding.runtimeSha, "reviewEvidence.runtimeBinding.runtimeSha"), parentShas, mergedAt: value.runtimeBinding.mergedAt === null ? null : timestamp(value.runtimeBinding.mergedAt, "reviewEvidence.runtimeBinding.mergedAt") };
376
+ }
397
377
  return {
398
378
  repository: repository(value.repository, "reviewEvidence.repository"),
399
- pullRequest: positiveInteger(
400
- value.pullRequest,
401
- "reviewEvidence.pullRequest",
402
- ),
379
+ pullRequest: positiveInteger(value.pullRequest, "reviewEvidence.pullRequest"),
403
380
  headSha: exactSha(value.headSha, "reviewEvidence.headSha"),
404
381
  baseRef: nonEmpty(value.baseRef, "reviewEvidence.baseRef"),
405
- approvals,
406
- checks,
382
+ approvals, checks,
407
383
  observedAt: timestamp(value.observedAt, "reviewEvidence.observedAt"),
384
+ ...(runtimeBinding ? { runtimeBinding } : {}),
408
385
  };
409
386
  }
410
387
 
388
+ function reviewedRuntimeSha(request, policy, evidence, runtimeSha) {
389
+ const binding = evidence.runtimeBinding || { kind: "reviewed-head", runtimeSha: evidence.headSha, parentShas: [], mergedAt: null };
390
+ if (binding.runtimeSha !== runtimeSha) fail("review-runtime-mismatch", "review evidence runtime binding does not match the candidate");
391
+ const direct = binding.kind === "reviewed-head" && evidence.headSha === runtimeSha && evidence.baseRef === policy.targetRef && binding.mergedAt === null;
392
+ const alphaMerge = binding.kind === "protected-alpha-merge" && request.mode === "alpha" && evidence.baseRef === "alpha/v4/v4.0" && binding.parentShas.length === 2 && binding.parentShas.includes(evidence.headSha) && binding.mergedAt !== null && Date.parse(binding.mergedAt) <= Date.parse(evidence.observedAt);
393
+ if (!direct && !alphaMerge) fail("review-identity-mismatch", "review evidence does not bind the candidate runtime");
394
+ return evidence.headSha;
395
+ }
396
+
411
397
  export function v4UniversalWorkflowAdmissionRoot(value) {
412
398
  return documentRoot("universal-workflow-admission", validatePolicy(value));
413
399
  }
@@ -478,17 +464,16 @@ export function admitV4UniversalWorkflow({
478
464
  const reviewEvidence = validateReviewEvidence(reviewEvidenceValue);
479
465
  if (
480
466
  reviewEvidence.repository !== request.candidate.repository ||
481
- reviewEvidence.pullRequest !== request.candidate.reviewPullRequest ||
482
- reviewEvidence.headSha !== runtimeSha ||
483
- reviewEvidence.baseRef !== policy.targetRef
467
+ reviewEvidence.pullRequest !== request.candidate.reviewPullRequest
484
468
  )
485
469
  fail(
486
470
  "review-identity-mismatch",
487
471
  "review evidence does not bind the candidate",
488
472
  );
473
+ const reviewedSha = reviewedRuntimeSha(request, policy, reviewEvidence, runtimeSha);
489
474
  const approvedReviewers = new Set(
490
475
  reviewEvidence.approvals
491
- .filter((approval) => approval.commitSha === runtimeSha)
476
+ .filter((approval) => approval.commitSha === reviewedSha)
492
477
  .map((approval) => approval.reviewer),
493
478
  );
494
479
  const admittedApprovalCount = policy.allowedReviewers.filter((reviewer) =>
@@ -512,7 +497,8 @@ export function admitV4UniversalWorkflow({
512
497
  checks.length === 0 ||
513
498
  checks.some(
514
499
  (check) =>
515
- check.status !== "completed" || check.conclusion !== "success",
500
+ check.status !== "completed" || check.conclusion !== "success" ||
501
+ (check.commitSha !== undefined && check.commitSha !== runtimeSha),
516
502
  )
517
503
  );
518
504
  })
@@ -118,6 +118,10 @@ assert.equal(contract.bootstrap.consumerSourceMutationPerIncident, false);
118
118
  assert.equal(contract.bootstrap.buildchainReleasePromotionPerIncident, false);
119
119
  assert.equal(contract.bootstrap.selfDogfoodUsesPublicContract, true);
120
120
  assert.equal(contract.bootstrap.recoveryDependsOnPublishedBuildchain, false);
121
+ assert.equal(
122
+ contract.bootstrap.reviewRuntimeBinding,
123
+ "reviewed-head-or-protected-alpha-merge-to-exact-runtime",
124
+ );
121
125
  assert.deepEqual(
122
126
  contract.capabilityAdapters.map(({ id }) => id).sort(),
123
127
  [...admissionPolicy.allowedCapabilities].sort(),
@@ -168,6 +172,10 @@ assert.match(
168
172
  bootstrapSource,
169
173
  /ascii_downcase\) == "kungfu-origin"[\s\S]*\.name == "check"[\s\S]*map\(select\(\.status == "completed" and \(\.conclusion \/\/ ""\) != ""\)\)[\s\S]*candidate\/architecture\/v4-universal-workflow-train-admission\.json/u,
170
174
  );
175
+ assert.match(
176
+ bootstrapSource,
177
+ /CANDIDATE_MODE:[\s\S]*\.merged == true[\s\S]*\.merge_commit_sha == \$expected[\s\S]*\.base\.ref == "alpha\/v4\/v4\.0"[\s\S]*commitSha: \$expected[\s\S]*runtimeBinding:/u,
178
+ );
171
179
  const consumerTemplate = fs.readFileSync(
172
180
  path.join(root, contract.bootstrap.consumerTemplate),
173
181
  "utf8",