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

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 (115) hide show
  1. package/AGENTS.md +1 -1
  2. package/CONTRIBUTING.md +1 -1
  3. package/README.md +32 -1
  4. package/actions/promote-buildchain-ref/README.md +90 -19
  5. package/actions/report-buildchain-issue/README.md +19 -1
  6. package/actions/run-lifecycle/README.md +5 -0
  7. package/actions/validate-config/README.md +19 -1
  8. package/bin/buildchain.mjs +41 -241
  9. package/bin/internal/command-registry.mjs +82 -0
  10. package/bin/internal/trust-release-cli.mjs +1 -0
  11. package/contracts/auditable-demo-media-profiles-v1.json +116 -1
  12. package/contracts/buildchain-v2-residuals-v1.json +0 -45
  13. package/contracts/evidence/auditable-demo-responsive-web-delivery-v1.json +143 -0
  14. package/contracts/evidence/auditable-demo-web-delivery-v1.json +7 -3
  15. package/contracts/fixtures/auditable-demo-responsive-web-delivery-v1/complete-transcript.txt +2 -0
  16. package/contracts/fixtures/auditable-demo-responsive-web-delivery-v1/public-projection.json +16 -0
  17. package/contracts/fixtures/auditable-demo-responsive-web-delivery-v1/scene.json +12 -0
  18. package/dist/site/buildchain-contract.json +161 -42
  19. package/dist/site/buildchain-site.json +180 -84
  20. package/dist/site/capability-registry.json +6 -6
  21. package/dist/site/cli-registry.json +932 -98
  22. package/dist/site/controller-registry.json +97 -5
  23. package/dist/site/kfd-claims.json +316 -23
  24. package/dist/site/kfd-upstream-aggregate.json +1 -1
  25. package/dist/site/manual-registry.json +20 -20
  26. package/dist/site/node-api-registry.json +371 -56
  27. package/dist/site/page-registry.json +155 -59
  28. package/dist/site/public-surface-audit.json +286 -24
  29. package/dist/site/publication-registry.json +4 -4
  30. package/dist/site/release-provenance.json +3 -0
  31. package/dist/site/site-manifest.json +24 -24
  32. package/dist/site/workflow-registry.json +570 -79
  33. package/docs/MAP.md +22 -4
  34. package/docs/auditable-demo.md +35 -12
  35. package/docs/aws-us-elastic-runner-burst-plane.md +381 -0
  36. package/docs/cli.md +143 -12
  37. package/docs/consumer-issue-reporting.md +19 -1
  38. package/docs/github-governance-authority.md +2 -2
  39. package/docs/lifecycle-protocol.md +20 -2
  40. package/docs/migration-inventory.md +24 -5
  41. package/docs/ownership.md +19 -1
  42. package/docs/publication-artifacts.md +185 -18
  43. package/docs/publication-authority.md +4 -4
  44. package/docs/publish-transaction.md +78 -31
  45. package/docs/release-candidate.md +24 -0
  46. package/docs/release-flow.md +50 -32
  47. package/docs/release-governance.md +31 -31
  48. package/docs/release-passport.md +4 -0
  49. package/docs/release-propagation.md +57 -12
  50. package/docs/reusable-build-surface.md +95 -27
  51. package/docs/runtime-train-validation.md +20 -2
  52. package/docs/stable-candidate-patrol.md +6 -6
  53. package/docs/toolkit-observability.md +22 -0
  54. package/docs/versioning.md +6 -4
  55. package/docs/web-surface-deployments.md +62 -0
  56. package/package.json +7 -5
  57. package/packages/core/README.md +61 -4
  58. package/packages/core/buildchain-contract.js +8 -4
  59. package/packages/core/cache-evidence.js +1 -0
  60. package/packages/core/diagnostics.js +105 -30
  61. package/packages/core/github-governance-authority.js +10 -25
  62. package/packages/core/index.js +40 -0
  63. package/packages/core/paper-fleet.js +260 -0
  64. package/packages/core/paper-repository.js +210 -0
  65. package/packages/core/paper-work.js +365 -0
  66. package/packages/core/paper.js +3180 -0
  67. package/packages/core/public-surface-audit.js +26 -75
  68. package/packages/core/public-surface-cli.js +117 -0
  69. package/packages/core/publication-artifact.js +1 -6
  70. package/packages/core/publication-authority.js +1 -0
  71. package/packages/core/publication-reproducibility.js +947 -0
  72. package/packages/core/publication-sealed-bundle.js +190 -0
  73. package/packages/core/publish-transaction.js +147 -17
  74. package/packages/core/release-candidate.js +234 -0
  75. package/packages/core/release-passport.js +483 -201
  76. package/packages/core/release-propagation.js +175 -1
  77. package/scripts/auditable-demo.mjs +119 -5
  78. package/scripts/aws-codebuild-toolchain.mjs +285 -0
  79. package/scripts/aws-macos-jit-core.mjs +378 -0
  80. package/scripts/aws-macos-jit.mjs +123 -0
  81. package/scripts/aws-runner-burst-core.mjs +248 -0
  82. package/scripts/aws-runner-burst.mjs +79 -0
  83. package/scripts/aws-windows-jit-core.mjs +374 -0
  84. package/scripts/aws-windows-jit.mjs +121 -0
  85. package/scripts/build-contract-core.mjs +69 -6
  86. package/scripts/build-standalone-binary.mjs +23 -0
  87. package/scripts/buildchain-cli-help.mjs +256 -0
  88. package/scripts/buildchain-contract-lock.mjs +1 -1
  89. package/scripts/check-internal-architecture.mjs +69 -2
  90. package/scripts/check-inventory.mjs +69 -2
  91. package/scripts/check-javascript-syntax.mjs +31 -0
  92. package/scripts/check-maintainability.mjs +371 -0
  93. package/scripts/compiler-cache-evidence.mjs +221 -0
  94. package/scripts/dev-alpha-candidate-patrol.mjs +268 -43
  95. package/scripts/finalize-native-artifact-signing-result.mjs +75 -4
  96. package/scripts/generate-channel-promotion-workflow.mjs +3 -12
  97. package/scripts/generate-release-candidate-passport.mjs +4 -0
  98. package/scripts/generate-site-bundle.mjs +68 -188
  99. package/scripts/import-artifact-signing-results.mjs +64 -5
  100. package/scripts/inspect-artifact-signing-requests.mjs +7 -0
  101. package/scripts/maintainability-metrics.mjs +339 -0
  102. package/scripts/npm-publish-transaction.mjs +57 -6
  103. package/scripts/paper-work-fleet-cli.mjs +563 -0
  104. package/scripts/paper.mjs +631 -0
  105. package/scripts/promotion-channel-router.mjs +16 -4
  106. package/scripts/publication-reproducibility.mjs +62 -0
  107. package/scripts/release-propagation.mjs +39 -0
  108. package/scripts/resolve-build-contract.mjs +6 -0
  109. package/scripts/route-offline-runners.mjs +236 -0
  110. package/scripts/run-lifecycle-core.mjs +62 -1
  111. package/scripts/runtime-ref-core.mjs +23 -2
  112. package/scripts/seal-artifact-signing-requests.mjs +13 -6
  113. package/scripts/site-capability-metadata.mjs +202 -0
  114. package/scripts/stable-candidate-qualification.mjs +42 -0
  115. package/scripts/web-surface-core.mjs +272 -86
@@ -1,6 +1,12 @@
1
1
  import crypto from "node:crypto";
2
2
  import fs from "node:fs";
3
3
  import path from "node:path";
4
+ import {
5
+ commandId,
6
+ enumerateCliCommandsFromBin,
7
+ } from "./public-surface-cli.js";
8
+
9
+ export { enumerateCliCommandsFromBin } from "./public-surface-cli.js";
4
10
 
5
11
  export const BUILDCHAIN_PUBLIC_SURFACE_AUDIT_CONTRACT = "kungfu-buildchain-public-surface-reverse-audit";
6
12
 
@@ -40,79 +46,6 @@ function listDirectories(root, dir) {
40
46
  .sort();
41
47
  }
42
48
 
43
- function commandId(first = "", second = "", third = "") {
44
- const head = String(first || "").trim();
45
- const sub = String(second || "").trim();
46
- const leaf = String(third || "").trim();
47
- const normalizedLeaf = leaf === "..." ? "" : leaf;
48
- if (!head) return "";
49
- if (["-h", "--help", "help"].includes(head)) return "help";
50
- if (["-v", "--version", "version"].includes(head)) return "version";
51
- if (head === "release" && ["--dry-run", "dry-run", "explain"].includes(sub)) return "release-dry-run";
52
- if (head === "release" && sub === "line") return "release-line-open";
53
- if (head === "release") return "release-transaction";
54
- if (head === "transaction") return "transaction-inspect";
55
- if (head === "collect" && sub) return `collect-${sub}`;
56
- if (head === "verify" && sub) return `verify-${sub}`;
57
- if (head === "explain" && sub) return `explain-${sub}`;
58
- if (head === "inspect" && sub) return `inspect-${sub}`;
59
- if (head === "npm" && sub) return `npm-${sub}`;
60
- if (head === "lifecycle" && sub) return "lifecycle";
61
- if (head === "log" && sub) return "logging";
62
- if (head === "diagnostics" && sub) return `diagnostics-${sub}`;
63
- if (head === "facts" && sub) return "build-facts";
64
- if (head === "kfd") {
65
- if (!sub || sub === "...") return "kfd";
66
- if (sub === "schema") return normalizedLeaf ? `kfd-schema-${normalizedLeaf}` : "kfd-schema";
67
- if (sub === "upstream") return normalizedLeaf ? `kfd-upstream-${normalizedLeaf}` : "kfd-upstream";
68
- if (/^[1-9][0-9]*$/.test(sub)) return normalizedLeaf ? `kfd-${sub}-${normalizedLeaf}` : `kfd-${sub}`;
69
- return `kfd-${sub}`;
70
- }
71
- if (head === "sample" && sub) return `sample-${sub}`;
72
- if (head === "badges" && sub) return `badges-${sub}`;
73
- if (head === "homebrew" && sub) return `homebrew-${sub}`;
74
- if (head === "release-propagation") return "release-propagation";
75
- if (head === "publish-source") return "publish-source";
76
- if (head === "publication-artifact" && sub) return `publication-artifact-${sub}`;
77
- if (head === "publication-artifact") return "publication-artifact";
78
- if (head === "publication" && sub) return `publication-artifact-${sub}`;
79
- if (head === "publication") return "publication-artifact";
80
- if (head === "build-contract") return "build-contract";
81
- if (head === "infra-contract") return "infra-contract";
82
- if (head === "web-surface") return "web-surface";
83
- return head;
84
- }
85
-
86
- export function enumerateCliCommandsFromBin({ root = process.cwd(), binPath = "bin/buildchain.mjs" } = {}) {
87
- const source = readText(root, binPath);
88
- const dispatchSource = [
89
- source,
90
- ...listFiles(root, "bin/internal", (name) => name.endsWith(".mjs"))
91
- .map((relPath) => readText(root, relPath)),
92
- ].join("\n");
93
- const usageMatch = source.match(/return `Usage:\n([\s\S]*?)`;\n}/);
94
- const usage = usageMatch?.[1] || "";
95
- const usageCommands = [];
96
- for (const line of usage.split(/\r?\n/)) {
97
- const match = line.trim().match(/^buildchain\s+([^\s]+)(?:\s+([^\s]+))?(?:\s+([^\s]+))?/);
98
- if (!match) continue;
99
- usageCommands.push({
100
- id: commandId(match[1], match[2], match[3]),
101
- usage: line.trim().replace(/\s+/g, " "),
102
- });
103
- }
104
- const dispatchCommands = [...dispatchSource.matchAll(/if\s*\(\s*command\s*===\s*"([^"]+)"/g)]
105
- .map((match) => commandId(match[1]));
106
- return uniqueSorted([
107
- ...usageCommands.map((entry) => entry.id),
108
- ...dispatchCommands,
109
- ]).map((id) => ({
110
- id,
111
- source: "bin/buildchain.mjs",
112
- usage: usageCommands.find((entry) => entry.id === id)?.usage || `buildchain ${id}`,
113
- }));
114
- }
115
-
116
49
  function parseYamlWorkflowCall(text) {
117
50
  const lines = text.split(/\r?\n/);
118
51
  const result = { reusable: false, inputs: [], secrets: [], outputs: [] };
@@ -330,8 +263,26 @@ export function collectPublicSurfaceReverseAudit({
330
263
  mode: "closed-world-enumerable",
331
264
  scope: "Buildchain CLI usage/dispatch, reusable workflow inputs, action inputs, site pages, and documentation command references",
332
265
  residualRisk: [
333
- "Shell commands delegated through helper scripts are only counted when exposed through bin/buildchain.mjs usage or docs.",
334
- "YAML parsing is limited to first-class action/workflow inputs, not arbitrary step environment variables.",
266
+ {
267
+ id: "public-surface-helper-command-enumeration",
268
+ definedBy: "https://kfd.libkungfu.dev/schemas/kfd-2/trust-taxonomy.schema.json#/$defs/residualRisk",
269
+ riskType: "natural-language-semantic-risk",
270
+ trustImpact: "downgrade-warning",
271
+ machineProvability: "not-machine-verifiable",
272
+ agentAction: "semantic-review-required",
273
+ owner: "Buildchain maintainers",
274
+ reason: "Shell commands delegated through helper scripts are counted only when exposed through bin/buildchain.mjs usage or documentation.",
275
+ },
276
+ {
277
+ id: "public-surface-yaml-enumeration",
278
+ definedBy: "https://kfd.libkungfu.dev/schemas/kfd-2/trust-taxonomy.schema.json#/$defs/residualRisk",
279
+ riskType: "natural-language-semantic-risk",
280
+ trustImpact: "downgrade-warning",
281
+ machineProvability: "not-machine-verifiable",
282
+ agentAction: "semantic-review-required",
283
+ owner: "Buildchain maintainers",
284
+ reason: "YAML enumeration covers first-class action and workflow inputs, not arbitrary step environment variables.",
285
+ },
335
286
  ],
336
287
  },
337
288
  };
@@ -0,0 +1,117 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+
4
+ function readText(root, relPath) {
5
+ return fs.readFileSync(path.join(root, relPath), "utf8");
6
+ }
7
+
8
+ function listFiles(root, dir, predicate = () => true) {
9
+ const base = path.join(root, dir);
10
+ if (!fs.existsSync(base)) return [];
11
+ return fs
12
+ .readdirSync(base, { withFileTypes: true })
13
+ .filter((entry) => entry.isFile() && predicate(entry.name))
14
+ .map((entry) => `${dir}/${entry.name}`)
15
+ .sort();
16
+ }
17
+
18
+ function uniqueSorted(values) {
19
+ return [...new Set(values.filter(Boolean))].sort();
20
+ }
21
+
22
+ function releaseCommandId(sub) {
23
+ if (["--dry-run", "dry-run", "explain"].includes(sub))
24
+ return "release-dry-run";
25
+ if (sub === "line") return "release-line-open";
26
+ return "release-transaction";
27
+ }
28
+
29
+ function kfdCommandId(sub, leaf) {
30
+ if (!sub || sub === "...") return "kfd";
31
+ if (["schema", "upstream"].includes(sub) || /^[1-9][0-9]*$/.test(sub)) {
32
+ return leaf ? `kfd-${sub}-${leaf}` : `kfd-${sub}`;
33
+ }
34
+ return `kfd-${sub}`;
35
+ }
36
+
37
+ function paperCommandId(sub, leaf) {
38
+ if (sub === "bootstrap" && leaf === "npm") return "paper-bootstrap-npm";
39
+ if (["work", "fleet"].includes(sub) && leaf) return `paper-${sub}-${leaf}`;
40
+ return sub ? `paper-${sub}` : "paper";
41
+ }
42
+
43
+ export function commandId(first = "", second = "", third = "") {
44
+ const head = String(first || "").trim();
45
+ const sub = String(second || "").trim();
46
+ const leaf =
47
+ String(third || "").trim() === "..." ? "" : String(third || "").trim();
48
+ const paired = new Set([
49
+ "collect",
50
+ "verify",
51
+ "explain",
52
+ "inspect",
53
+ "npm",
54
+ "diagnostics",
55
+ "sample",
56
+ "badges",
57
+ "homebrew",
58
+ ]);
59
+ if (!head) return "";
60
+ if (["-h", "--help", "help"].includes(head)) return "help";
61
+ if (["-v", "--version", "version"].includes(head)) return "version";
62
+ if (head === "release") return releaseCommandId(sub);
63
+ if (head === "transaction") return "transaction-inspect";
64
+ if (paired.has(head) && sub) return `${head}-${sub}`;
65
+ if (head === "lifecycle" && sub) return "lifecycle";
66
+ if (head === "log" && sub) return "logging";
67
+ if (head === "facts" && sub) return "build-facts";
68
+ if (head === "kfd") return kfdCommandId(sub, leaf);
69
+ if (["release-propagation", "publish-source"].includes(head)) return head;
70
+ if (["publication-artifact", "publication"].includes(head)) {
71
+ return sub ? `publication-artifact-${sub}` : "publication-artifact";
72
+ }
73
+ if (head === "paper") return paperCommandId(sub, leaf);
74
+ return head;
75
+ }
76
+
77
+ function usageCommands(source) {
78
+ const usageMatch = source.match(/`Usage:\n([\s\S]*?)`;/);
79
+ const rows = [];
80
+ for (const line of (usageMatch?.[1] || "").split(/\r?\n/)) {
81
+ const match = line
82
+ .trim()
83
+ .match(/^buildchain\s+([^\s]+)(?:\s+([^\s]+))?(?:\s+([^\s]+))?/);
84
+ if (!match) continue;
85
+ rows.push({
86
+ id: commandId(match[1], match[2], match[3]),
87
+ usage: line.trim().replace(/\s+/g, " "),
88
+ });
89
+ }
90
+ return rows;
91
+ }
92
+
93
+ export function enumerateCliCommandsFromBin({
94
+ root = process.cwd(),
95
+ binPath = "bin/buildchain.mjs",
96
+ } = {}) {
97
+ const binSource = readText(root, binPath);
98
+ const helpSource = readText(root, "scripts/buildchain-cli-help.mjs");
99
+ const dispatchSource = [
100
+ binSource,
101
+ ...listFiles(root, "bin/internal", (name) => name.endsWith(".mjs")).map(
102
+ (relPath) => readText(root, relPath),
103
+ ),
104
+ ].join("\n");
105
+ const usage = usageCommands(helpSource);
106
+ const dispatch = [
107
+ ...dispatchSource.matchAll(/if\s*\(\s*command\s*===\s*"([^"]+)"/g),
108
+ ].map((match) => commandId(match[1]));
109
+ return uniqueSorted([...usage.map((entry) => entry.id), ...dispatch]).map(
110
+ (id) => ({
111
+ id,
112
+ source: "bin/buildchain.mjs",
113
+ usage:
114
+ usage.find((entry) => entry.id === id)?.usage || `buildchain ${id}`,
115
+ }),
116
+ );
117
+ }
@@ -253,7 +253,7 @@ export function createPublicationSourceBundle({
253
253
  } = {}) {
254
254
  const outputPath = path.resolve(cwd, output);
255
255
  fs.mkdirSync(path.dirname(outputPath), { recursive: true });
256
- const paths = sourcePaths.length > 0 ? sourcePaths : ["."];
256
+ const paths = [...(sourcePaths.length > 0 ? sourcePaths : ["."])].sort();
257
257
  execFileSync("git", [
258
258
  "archive",
259
259
  "--format=tar.gz",
@@ -501,11 +501,6 @@ function mergePublicationRegistryVersions({ registries = [], publicationId }) {
501
501
  if (registry.publication?.id !== publicationId) {
502
502
  throw new Error(`publication archive registry id mismatch: expected ${publicationId}, got ${registry.publication?.id || "(missing)"}`);
503
503
  }
504
- if (registry.historyPolicy === "cumulative-authenticated-hydration") {
505
- const declaredVersions = new Set(registry.versions.map((record) => String(record?.version || "")));
506
- const missingVersions = [...versions.keys()].filter((version) => !declaredVersions.has(version));
507
- if (missingVersions.length > 0) throw new Error(`cumulative publication archive registry dropped accepted versions: ${missingVersions.join(", ")}`);
508
- }
509
504
  for (const record of registry.versions) {
510
505
  const version = String(record?.version || "").trim();
511
506
  if (!version) throw new Error("publication archive registry record is missing version");
@@ -649,6 +649,7 @@ function validatePublicationEvidence(publicationEvidence, admission) {
649
649
  platformMatrix: passport.platformMatrix,
650
650
  buildchain: passport.buildchain,
651
651
  ...(passport.gateProfileEvidence ? { gateProfileEvidence: passport.gateProfileEvidence } : {}),
652
+ ...(passport.familyEvidence ? { familyEvidence: passport.familyEvidence } : {}),
652
653
  ...(passport.controllerReceipts ? { controllerReceipts: passport.controllerReceipts } : {}),
653
654
  });
654
655
  if (normalizeDigest(passport.candidateHash, "releaseCandidatePassport.candidateHash") !== candidateHash) {