@kungfu-tech/buildchain 3.0.2 → 3.0.3-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/actions/report-buildchain-issue/README.md +1 -1
  2. package/contracts/buildchain-v2-residuals-v1.json +191 -0
  3. package/dist/site/buildchain-contract.json +58 -35
  4. package/dist/site/buildchain-site.json +33 -33
  5. package/dist/site/controller-registry.json +24 -3
  6. package/dist/site/kfd-claims.json +11 -6
  7. package/dist/site/kfd-upstream-aggregate.json +1 -1
  8. package/dist/site/manual-registry.json +7 -7
  9. package/dist/site/node-api-registry.json +6 -6
  10. package/dist/site/page-registry.json +22 -22
  11. package/dist/site/public-surface-audit.json +10 -5
  12. package/dist/site/publication-registry.json +4 -4
  13. package/dist/site/site-manifest.json +11 -11
  14. package/dist/site/workflow-registry.json +8 -3
  15. package/docs/auditable-demo.md +19 -1
  16. package/docs/consumer-issue-reporting.md +1 -1
  17. package/docs/dev-alpha-candidate-patrol.md +24 -10
  18. package/docs/github-governance-authority.md +23 -30
  19. package/docs/observed-evidence-patrol.md +28 -12
  20. package/docs/release-governance.md +8 -1
  21. package/docs/reusable-build-surface.md +124 -64
  22. package/docs/shifu-gate-profiles.md +7 -1
  23. package/docs/versioning.md +41 -21
  24. package/docs/web-surface-deployments.md +20 -1
  25. package/package.json +1 -1
  26. package/packages/core/artifact-signing.js +1 -0
  27. package/packages/core/buildchain-contract.js +1 -0
  28. package/packages/core/controller-evidence.js +2 -0
  29. package/packages/core/github-governance-authority.js +25 -17
  30. package/packages/core/publication-control-plane-audit.js +28 -0
  31. package/packages/core/release-passport.js +36 -27
  32. package/packages/core/stable-release-gate.js +4 -1
  33. package/scripts/artifact-signing-delegation.mjs +268 -0
  34. package/scripts/audit-github-governance.mjs +32 -13
  35. package/scripts/audit-publication-control-plane.mjs +17 -8
  36. package/scripts/auditable-demo.mjs +147 -2
  37. package/scripts/buildchain-patrol.mjs +1 -1
  38. package/scripts/check-inventory.mjs +1 -0
  39. package/scripts/dev-alpha-candidate-patrol.mjs +20 -0
  40. package/scripts/dispatch-artifact-signing-authority.mjs +7 -1
  41. package/scripts/finalize-native-artifact-signing-result.mjs +114 -31
  42. package/scripts/gate-profile-core.mjs +6 -1
  43. package/scripts/inspect-artifact-signing-requests.mjs +45 -14
  44. package/scripts/observed-evidence.mjs +151 -33
  45. package/scripts/reconcile-github-governance.mjs +8 -1
  46. package/scripts/resolve-artifact-signing-upload-route.mjs +55 -0
  47. package/scripts/run-candidate-body-prefix-renderer.mjs +187 -0
  48. package/scripts/runtime-ref-core.mjs +13 -2
  49. package/scripts/seal-artifact-signing-requests.mjs +51 -6
  50. package/scripts/stable-candidate-qualification.mjs +8 -0
  51. package/scripts/verify-artifact-signing-results.mjs +26 -1
  52. package/scripts/web-surface-production-decision.mjs +19 -3
@@ -91,8 +91,12 @@ async function ensureWorkflowEvidence({ client, repository, workflowFile, workfl
91
91
  let run = await client.findWorkflowRun({ repository, workflowFile, workflowName, headSha, runName, sourceSha });
92
92
  if (successful(run)) return { state: "existing", run };
93
93
 
94
+ let notBefore = "";
95
+ let excludeRunId = "";
94
96
  if (!active(run)) {
95
97
  if (options.dryRun) return { state: "planned", run };
98
+ notBefore = text(run?.created_at);
99
+ excludeRunId = text(run?.id);
96
100
  await client.dispatchWorkflow({ repository, workflowFile, ref, inputs: runName ? { buildchain_ref: headSha } : {} });
97
101
  }
98
102
 
@@ -104,6 +108,8 @@ async function ensureWorkflowEvidence({ client, repository, workflowFile, workfl
104
108
  headSha,
105
109
  runName,
106
110
  sourceSha,
111
+ notBefore,
112
+ excludeRunId,
107
113
  attempts: options.pollAttempts,
108
114
  intervalMs: options.pollIntervalMs,
109
115
  });
@@ -220,6 +226,8 @@ export function createGitHubQualificationClient({
220
226
  || (query.runName && (run.display_title === query.runName || run.name === query.runName))
221
227
  )
222
228
  && (!query.sourceSha || run.head_sha === query.sourceSha)
229
+ && (!query.notBefore || String(run.created_at || "") >= query.notBefore)
230
+ && (!query.excludeRunId || String(run.id || "") !== query.excludeRunId)
223
231
  ))
224
232
  .sort((left, right) => String(right.created_at).localeCompare(String(left.created_at)))[0];
225
233
  }
@@ -27,11 +27,36 @@ function resolveBelow(root, relative, label) {
27
27
  return target;
28
28
  }
29
29
 
30
+ function walk(root, name, output = []) {
31
+ for (const entry of fs.readdirSync(root, { withFileTypes: true })) {
32
+ const child = path.join(root, entry.name);
33
+ if (entry.isDirectory()) walk(child, name, output);
34
+ else if (entry.isFile() && entry.name === name) output.push(child);
35
+ }
36
+ return output;
37
+ }
38
+
39
+ function resolveRequestRoot(root) {
40
+ const direct = path.join(root, "index.json");
41
+ if (fs.existsSync(direct)) return root;
42
+ const candidates = walk(root, "index.json").filter((candidate) => {
43
+ try {
44
+ return JSON.parse(fs.readFileSync(candidate, "utf8")).contract === "kungfu-buildchain-artifact-signing-request-index/v1";
45
+ } catch {
46
+ return false;
47
+ }
48
+ });
49
+ if (candidates.length !== 1) {
50
+ throw new Error(`expected exactly one artifact signing request index, found ${candidates.length}`);
51
+ }
52
+ return path.dirname(candidates[0]);
53
+ }
54
+
30
55
  export function verifyArtifactSigningResults({
31
56
  requestRoot = process.env.BUILDCHAIN_SIGNING_REQUEST_ROOT,
32
57
  resultRoot = process.env.BUILDCHAIN_SIGNING_RESULT_ROOT,
33
58
  } = {}) {
34
- const requests = path.resolve(required(requestRoot, "signing request root"));
59
+ const requests = resolveRequestRoot(path.resolve(required(requestRoot, "signing request root")));
35
60
  const results = path.resolve(required(resultRoot, "signing result root"));
36
61
  const requestIndex = JSON.parse(
37
62
  fs.readFileSync(path.join(requests, "index.json"), "utf8"),
@@ -37,9 +37,7 @@ export function resolveWebSurfaceProductionDecision({
37
37
  reason: trusted ? "trusted-manual-dispatch" : "manual-actor-permission-insufficient",
38
38
  });
39
39
  }
40
- const reviewedReleaseEvent =
41
- (eventName === "push" && refName === "main") ||
42
- (eventName === "pull_request" && eventAction === "closed");
40
+ const reviewedReleaseEvent = eventName === "push" && refName === "main";
43
41
  if (
44
42
  reviewedReleaseEvent &&
45
43
  productionApply === true &&
@@ -57,6 +55,24 @@ export function resolveWebSurfaceProductionDecision({
57
55
  reason: "reviewed-release-pr-merged",
58
56
  });
59
57
  }
58
+ if (
59
+ eventName === "pull_request" &&
60
+ eventAction === "closed" &&
61
+ productionApply === true &&
62
+ productionReleaseOnMain === true &&
63
+ releaseApproved === true
64
+ ) {
65
+ return createWebSurfaceProductionDecision({
66
+ approved: false,
67
+ kind: "none",
68
+ repository,
69
+ sourceSha,
70
+ actor,
71
+ releasePr,
72
+ releaseSource,
73
+ reason: "release-pr-verified-awaiting-main-push",
74
+ });
75
+ }
60
76
  return createWebSurfaceProductionDecision({
61
77
  approved: false,
62
78
  kind: "none",