@kungfu-tech/buildchain 2.10.3 → 2.10.4

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 (37) hide show
  1. package/README.md +1 -0
  2. package/actions/promote-buildchain-ref/README.md +10 -7
  3. package/dist/site/badge-endpoint-registry.json +160 -0
  4. package/dist/site/badges/v1/kfd-4/aligned.json +14 -0
  5. package/dist/site/badges/v1/kfd-4/declared.json +14 -0
  6. package/dist/site/badges/v1/kfd-4/downgraded.json +14 -0
  7. package/dist/site/badges/v1/kfd-4/draft.json +14 -0
  8. package/dist/site/badges/v1/kfd-4/failed.json +14 -0
  9. package/dist/site/badges/v1/kfd-4/missing.json +14 -0
  10. package/dist/site/badges/v1/kfd-4/passed.json +14 -0
  11. package/dist/site/badges/v1/kfd-4/planned.json +14 -0
  12. package/dist/site/buildchain-contract.json +13 -13
  13. package/dist/site/buildchain-site.json +24 -24
  14. package/dist/site/capability-registry.json +1 -1
  15. package/dist/site/kfd-claims.json +4 -4
  16. package/dist/site/manual-registry.json +5 -5
  17. package/dist/site/node-api-registry.json +9 -9
  18. package/dist/site/page-registry.json +14 -14
  19. package/dist/site/public-surface-audit.json +1 -1
  20. package/dist/site/site-manifest.json +9 -9
  21. package/docs/readme-badges.md +14 -10
  22. package/docs/release-candidate.md +4 -1
  23. package/docs/release-governance.md +5 -2
  24. package/docs/release-passport.md +5 -2
  25. package/docs/reusable-build-surface.md +5 -2
  26. package/package.json +2 -2
  27. package/packages/core/artifact-passport.js +37 -11
  28. package/packages/core/badges.js +1 -0
  29. package/packages/core/buildchain-contract.js +1 -1
  30. package/packages/core/buildchain-kfd-claims.js +1 -1
  31. package/packages/core/index.js +1 -0
  32. package/packages/core/readme-badges.js +98 -39
  33. package/packages/core/release-passport.js +1 -0
  34. package/scripts/check-inventory.mjs +2 -0
  35. package/scripts/generate-site-bundle.mjs +11 -6
  36. package/scripts/web-surface-production-release-pr.mjs +88 -3
  37. package/scripts/web-surface.mjs +39 -1
@@ -3,6 +3,7 @@ import fs from "node:fs";
3
3
  import path from "node:path";
4
4
  import crypto from "node:crypto";
5
5
  import { pathToFileURL } from "node:url";
6
+ import { createRequire } from "node:module";
6
7
  import { createBuildchainContractWorld } from "../packages/core/buildchain-contract.js";
7
8
  import {
8
9
  BUILDCHAIN_AGENT_MANUALS,
@@ -23,6 +24,7 @@ const SITE_BUNDLE_CONTRACT = "kungfu-buildchain-site-bundle";
23
24
  const README_PATH = "README.md";
24
25
  const root = path.resolve(import.meta.dirname, "..");
25
26
  const outputDir = path.join(root, "dist", "site");
27
+ const requireFromHere = createRequire(import.meta.url);
26
28
 
27
29
  function readText(rel) {
28
30
  return fs.readFileSync(path.join(root, rel), "utf8");
@@ -32,6 +34,13 @@ function readJson(rel) {
32
34
  return JSON.parse(readText(rel));
33
35
  }
34
36
 
37
+ function readPackageKfdStandards() {
38
+ const standardsPath = requireFromHere.resolve("@kungfu-tech/kfd/standards.json", {
39
+ paths: [root],
40
+ });
41
+ return JSON.parse(fs.readFileSync(standardsPath, "utf8"));
42
+ }
43
+
35
44
  function writeJson(filePath, value) {
36
45
  fs.mkdirSync(path.dirname(filePath), { recursive: true });
37
46
  fs.writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\n`);
@@ -247,7 +256,7 @@ const CAPABILITY_GROUPS = Object.freeze([
247
256
  {
248
257
  id: "kfd-trust",
249
258
  title: "KFD Trust and Surface Closure",
250
- summary: "Discover KFD-1, KFD-2, and KFD-3 support, public surface reverse audits, and product capability queries.",
259
+ summary: "Discover KFD trust support, public surface reverse audits, and product capability queries.",
251
260
  audience: ["agent", "maintainer"],
252
261
  maturity: "stable",
253
262
  },
@@ -921,11 +930,7 @@ function buildSiteBundle() {
921
930
  instruction: "Use this bundle as the package-owned fact source for Buildchain pages. Do not infer current release mechanics from prose alone.",
922
931
  };
923
932
  const badgeEndpointRegistry = createReadmeBadgeEndpointRegistry({
924
- kfdSpecs: [
925
- { key: "kfd-1", label: "KFD-1", text: "contract world" },
926
- { key: "kfd-2", label: "KFD-2", text: "release trust passport" },
927
- { key: "kfd-3", label: "KFD-3", text: "collaboration interface" },
928
- ],
933
+ kfdStandards: readPackageKfdStandards(),
929
934
  });
930
935
 
931
936
  const homepageSections = [
@@ -1,4 +1,6 @@
1
1
  #!/usr/bin/env node
2
+ import fs from "node:fs";
3
+ import path from "node:path";
2
4
 
3
5
  function requiredString(value, name) {
4
6
  const normalized = String(value || "").trim();
@@ -28,6 +30,27 @@ function parseJson(value, name) {
28
30
  }
29
31
  }
30
32
 
33
+ function readArg(name, fallback = "") {
34
+ const index = process.argv.indexOf(`--${name}`);
35
+ if (index === -1) return fallback;
36
+ return process.argv[index + 1] || "";
37
+ }
38
+
39
+ function readJsonFile(filePath, name) {
40
+ const normalized = requiredString(filePath, name);
41
+ try {
42
+ return JSON.parse(fs.readFileSync(path.resolve(normalized), "utf8"));
43
+ } catch (error) {
44
+ throw new Error(`${name} must point to valid JSON: ${error.message}`);
45
+ }
46
+ }
47
+
48
+ function writeJsonFile(filePath, value) {
49
+ const resolved = path.resolve(requiredString(filePath, "output"));
50
+ fs.mkdirSync(path.dirname(resolved), { recursive: true });
51
+ fs.writeFileSync(resolved, `${JSON.stringify(value, null, 2)}\n`);
52
+ }
53
+
31
54
  function runUrl({ serverUrl = "", repository = "", runId = "" } = {}) {
32
55
  if (!serverUrl || !repository || !runId) return "";
33
56
  return `${serverUrl.replace(/\/$/, "")}/${repository}/actions/runs/${runId}`;
@@ -39,6 +62,51 @@ function urlsFromResult(result = {}) {
39
62
  return result.url ? { default: result.url } : {};
40
63
  }
41
64
 
65
+ export function compactProductionReleasePrSummary(result = {}) {
66
+ const manifest = result.manifest && typeof result.manifest === "object" ? result.manifest : {};
67
+ return {
68
+ schemaVersion: 1,
69
+ contract: "kungfu-buildchain-web-surface-production-release-pr-summary",
70
+ sourceContract: result.contract || "",
71
+ channel: result.channel || manifest.channel || "",
72
+ alias: result.alias || manifest.alias || "",
73
+ status: result.status || "",
74
+ applyMode: result.applyMode || "",
75
+ actor: result.actor || "",
76
+ runId: result.runId || "",
77
+ appliedAt: result.appliedAt || "",
78
+ url: result.url || "",
79
+ urls: urlsFromResult(result),
80
+ sourceSha: result.sourceSha || manifest.sourceSha || "",
81
+ artifactHash: result.artifactHash || manifest.artifactHash || "",
82
+ target: result.target || "",
83
+ manifestKey: result.manifestKey || "",
84
+ surfaceBindings: Array.isArray(result.surfaceBindings)
85
+ ? result.surfaceBindings.map((binding) => ({
86
+ surface: binding.surface || "",
87
+ pathPrefix: binding.pathPrefix || "",
88
+ objectPrefix: binding.objectPrefix || "",
89
+ url: binding.url || "",
90
+ manifestKey: binding.manifestKey || "",
91
+ accessControl: binding.accessControl || "",
92
+ healthStrategy: binding.healthStrategy || "",
93
+ }))
94
+ : [],
95
+ };
96
+ }
97
+
98
+ export function readStagingReleasePrSummary(env = process.env) {
99
+ const summaryPath = optionalString(env.STAGING_RELEASE_PR_SUMMARY_PATH);
100
+ if (summaryPath) {
101
+ return compactProductionReleasePrSummary(readJsonFile(summaryPath, "STAGING_RELEASE_PR_SUMMARY_PATH"));
102
+ }
103
+ const resultPath = optionalString(env.STAGING_APPLY_RESULT_PATH);
104
+ if (resultPath) {
105
+ return compactProductionReleasePrSummary(readJsonFile(resultPath, "STAGING_APPLY_RESULT_PATH"));
106
+ }
107
+ return compactProductionReleasePrSummary(parseJson(env.STAGING_APPLY_RESULT_JSON, "STAGING_APPLY_RESULT_JSON"));
108
+ }
109
+
42
110
  export function releaseBranchName({ prefix = "release/", channel = "production", sourceSha = "" } = {}) {
43
111
  const normalizedPrefix = optionalString(prefix) || "release/";
44
112
  const normalizedChannel = slugify(channel || "production");
@@ -276,7 +344,7 @@ export async function openProductionReleasePr({
276
344
  }
277
345
 
278
346
  export async function webSurfaceProductionReleasePrCli(env = process.env) {
279
- const stagingResult = parseJson(env.STAGING_APPLY_RESULT_JSON, "STAGING_APPLY_RESULT_JSON");
347
+ const stagingResult = readStagingReleasePrSummary(env);
280
348
  const sourceSha = optionalString(stagingResult.sourceSha) || requiredString(env.GITHUB_SHA, "GITHUB_SHA");
281
349
  const result = await openProductionReleasePr({
282
350
  apiUrl: env.GITHUB_API_URL || "https://api.github.com",
@@ -307,9 +375,26 @@ export async function webSurfaceProductionReleasePrCli(env = process.env) {
307
375
  return result;
308
376
  }
309
377
 
378
+ export function writeProductionReleasePrSummaryCli(env = process.env) {
379
+ const input = readArg("input", env.STAGING_APPLY_RESULT_PATH || "");
380
+ const output = readArg("output", env.STAGING_RELEASE_PR_SUMMARY_PATH || "");
381
+ const result = input
382
+ ? readJsonFile(input, "input")
383
+ : parseJson(env.STAGING_APPLY_RESULT_JSON, "STAGING_APPLY_RESULT_JSON");
384
+ const summary = compactProductionReleasePrSummary(result);
385
+ writeJsonFile(output, summary);
386
+ return summary;
387
+ }
388
+
310
389
  if (import.meta.url === `file://${process.argv[1]}`) {
311
- webSurfaceProductionReleasePrCli().catch((error) => {
390
+ try {
391
+ if (process.argv[2] === "write-summary") {
392
+ writeProductionReleasePrSummaryCli();
393
+ } else {
394
+ await webSurfaceProductionReleasePrCli();
395
+ }
396
+ } catch (error) {
312
397
  console.error(error.stack || error.message);
313
398
  process.exitCode = 1;
314
- });
399
+ }
315
400
  }
@@ -103,6 +103,42 @@ function writeFailureResult({ output, mode, cwd, error }) {
103
103
  return result;
104
104
  }
105
105
 
106
+ export function compactWebSurfaceApplyResult(result = {}) {
107
+ const manifest = result.manifest && typeof result.manifest === "object" ? result.manifest : {};
108
+ return {
109
+ schemaVersion: 1,
110
+ contract: "kungfu-buildchain-web-surface-deploy-apply-summary",
111
+ sourceContract: result.contract || "",
112
+ channel: result.channel || manifest.channel || "",
113
+ alias: result.alias || manifest.alias || "",
114
+ applyMode: result.applyMode || "",
115
+ status: result.status || "",
116
+ actor: result.actor || "",
117
+ runId: result.runId || "",
118
+ appliedAt: result.appliedAt || "",
119
+ url: result.url || "",
120
+ urls: result.urls && typeof result.urls === "object" ? result.urls : {},
121
+ sourceSha: result.sourceSha || manifest.sourceSha || "",
122
+ artifactHash: result.artifactHash || manifest.artifactHash || "",
123
+ adapter: result.adapter || "",
124
+ target: result.target || "",
125
+ objectPrefix: result.objectPrefix || "",
126
+ manifestKey: result.manifestKey || "",
127
+ invalidationPaths: Array.isArray(result.invalidationPaths) ? result.invalidationPaths : [],
128
+ surfaceBindings: Array.isArray(result.surfaceBindings)
129
+ ? result.surfaceBindings.map((binding) => ({
130
+ surface: binding.surface || "",
131
+ pathPrefix: binding.pathPrefix || "",
132
+ objectPrefix: binding.objectPrefix || "",
133
+ url: binding.url || "",
134
+ manifestKey: binding.manifestKey || "",
135
+ accessControl: binding.accessControl || "",
136
+ healthStrategy: binding.healthStrategy || "",
137
+ }))
138
+ : [],
139
+ };
140
+ }
141
+
106
142
  export function webSurfaceCli() {
107
143
  const mode = readArg("mode", process.env.BUILDCHAIN_WEB_SURFACE_MODE || "validate");
108
144
  const cwd = readArg("cwd", process.env.BUILDCHAIN_WORKDIR || process.cwd());
@@ -184,6 +220,7 @@ export function webSurfaceCli() {
184
220
  ...(publishedAt ? { appliedAt: publishedAt } : {}),
185
221
  });
186
222
  writeJson(result, output);
223
+ const applySummary = compactWebSurfaceApplyResult(result);
187
224
  writeGitHubOutputs({
188
225
  "web-surface-channel": result.channel,
189
226
  "web-surface-alias": result.alias,
@@ -194,7 +231,8 @@ export function webSurfaceCli() {
194
231
  "web-surface-apply-status": result.status,
195
232
  "web-surface-manifest-json": JSON.stringify(result.manifest),
196
233
  "web-surface-bindings-json": JSON.stringify(result.surfaceBindings || []),
197
- "web-surface-apply-result-json": JSON.stringify(result),
234
+ "web-surface-apply-summary-json": JSON.stringify(applySummary),
235
+ "web-surface-apply-result-json": JSON.stringify(applySummary),
198
236
  });
199
237
  assertApplySucceeded(result);
200
238
  return result;