@kungfu-tech/buildchain 3.0.2-alpha.0 → 3.0.2-alpha.10
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.
- package/README.md +4 -2
- package/actions/github-artifact-attestation/README.md +10 -0
- package/actions/promote-buildchain-ref/README.md +7 -0
- package/bin/buildchain.mjs +5 -0
- package/bin/internal/trust-release-cli.mjs +74 -3
- package/contracts/auditable-demo-media-profiles-v1.json +168 -0
- package/contracts/evidence/auditable-demo-web-delivery-v1.json +103 -0
- package/contracts/fixtures/auditable-demo-web-delivery-v1/complete-transcript.txt +2 -0
- package/contracts/fixtures/auditable-demo-web-delivery-v1/public-projection.json +16 -0
- package/contracts/fixtures/auditable-demo-web-delivery-v1/scene.json +12 -0
- package/dist/site/artifact-schemas.json +5 -1
- package/dist/site/buildchain-contract.json +133 -34
- package/dist/site/buildchain-site.json +159 -40
- package/dist/site/capability-registry.json +14 -13
- package/dist/site/cli-registry.json +12 -0
- package/dist/site/controller-registry.json +72 -4
- package/dist/site/kfd-claims.json +338 -20
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +24 -9
- package/dist/site/node-api-registry.json +89 -11
- package/dist/site/page-registry.json +135 -25
- package/dist/site/public-surface-audit.json +203 -21
- package/dist/site/publication-authority-registry.json +72 -2
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/release-model.json +2 -1
- package/dist/site/release-passport-check-manifest.json +1 -0
- package/dist/site/release-provenance.json +6 -0
- package/dist/site/schemas/release-passport-v1.schema.json +6 -0
- package/dist/site/site-manifest.json +21 -13
- package/dist/site/workflow-registry.json +167 -13
- package/docs/MAP.md +5 -1
- package/docs/auditable-demo.md +55 -3
- package/docs/binary-distribution.md +7 -0
- package/docs/cli.md +9 -0
- package/docs/dev-alpha-candidate-patrol.md +111 -0
- package/docs/github-artifact-attestation.md +219 -0
- package/docs/release-governance.md +32 -0
- package/docs/release-passport.md +13 -0
- package/docs/reusable-build-surface.md +83 -61
- package/docs/runtime-train-validation.md +21 -0
- package/docs/versioning.md +1 -0
- package/package.json +8 -1
- package/packages/core/artifact-signing-result.js +228 -0
- package/packages/core/artifact-signing.js +412 -0
- package/packages/core/buildchain-config.js +58 -0
- package/packages/core/buildchain-contract.js +14 -0
- package/packages/core/buildchain-kfd-claims.js +5 -0
- package/packages/core/buildchain-publication-authority.js +3 -0
- package/packages/core/cache-evidence.js +288 -0
- package/packages/core/channel-candidate.js +186 -0
- package/packages/core/detached-artifact-signature.js +121 -0
- package/packages/core/diagnostics.js +276 -10
- package/packages/core/github-artifact-attestation.js +642 -0
- package/packages/core/github-governance-authority.js +77 -16
- package/packages/core/index.js +62 -0
- package/packages/core/publication-authority.js +1 -1
- package/packages/core/release-passport-contract.js +2 -0
- package/packages/core/release-passport.js +60 -3
- package/scripts/auditable-demo.mjs +520 -28
- package/scripts/build-contract-core.mjs +31 -0
- package/scripts/buildchain-channel-router.mjs +8 -2
- package/scripts/check-inventory.mjs +9 -0
- package/scripts/create-github-artifact-attestation-policy.mjs +62 -0
- package/scripts/dev-alpha-candidate-patrol.mjs +864 -0
- package/scripts/dispatch-artifact-signing-authority.mjs +152 -0
- package/scripts/finalize-native-artifact-signing-result.mjs +96 -0
- package/scripts/generate-channel-promotion-workflow.mjs +6 -0
- package/scripts/generate-site-bundle.mjs +20 -0
- package/scripts/import-artifact-signing-results.mjs +76 -0
- package/scripts/inspect-artifact-signing-requests.mjs +101 -0
- package/scripts/locked-source-checkout.mjs +48 -0
- package/scripts/materialize-artifact-signing-request.mjs +66 -0
- package/scripts/merge-artifact-signing-results.mjs +76 -0
- package/scripts/publish-github-artifact-attestation-evidence.mjs +201 -0
- package/scripts/reconcile-github-governance.mjs +158 -25
- package/scripts/release-candidate-resolver.mjs +12 -0
- package/scripts/release-line-policy.mjs +27 -0
- package/scripts/runtime-ref-core.mjs +10 -6
- package/scripts/seal-artifact-signing-requests.mjs +368 -0
- package/scripts/shifu-gate-profile.mjs +26 -20
- package/scripts/sign-detached-artifact-requests.mjs +237 -0
- package/scripts/stage-github-artifact-attestation-inputs.mjs +65 -0
- package/scripts/verify-artifact-signing-results.mjs +99 -0
|
@@ -31,6 +31,36 @@ export const RUNNER_PRESETS = Object.freeze({
|
|
|
31
31
|
capabilities: ["node", "native-toolchain", "product-artifacts", "rust"],
|
|
32
32
|
},
|
|
33
33
|
],
|
|
34
|
+
"kungfu-v4-native": [
|
|
35
|
+
{
|
|
36
|
+
id: "linux-x64",
|
|
37
|
+
name: "Linux x64",
|
|
38
|
+
platform: "linux",
|
|
39
|
+
runner: '["self-hosted","Linux","X64","kungfu-build-v4-linux-x64"]',
|
|
40
|
+
capabilities: ["node", "native-toolchain", "product-artifacts", "rust"],
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
id: "linux-arm64",
|
|
44
|
+
name: "Linux ARM64",
|
|
45
|
+
platform: "linux",
|
|
46
|
+
runner: '["ubuntu-24.04-arm"]',
|
|
47
|
+
capabilities: ["node", "native-toolchain", "product-artifacts", "rust"],
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
id: "macos-arm64",
|
|
51
|
+
name: "macOS ARM64",
|
|
52
|
+
platform: "macos",
|
|
53
|
+
runner: '["self-hosted","macOS","ARM64","kungfu-build-v4-macos-arm64"]',
|
|
54
|
+
capabilities: ["node", "native-toolchain", "product-artifacts", "rust"],
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
id: "windows-x64",
|
|
58
|
+
name: "Windows x64",
|
|
59
|
+
platform: "windows",
|
|
60
|
+
runner: '["self-hosted","Windows","X64","kungfu-build-v4-windows-x64"]',
|
|
61
|
+
capabilities: ["node", "native-toolchain", "product-artifacts", "rust"],
|
|
62
|
+
},
|
|
63
|
+
],
|
|
34
64
|
});
|
|
35
65
|
|
|
36
66
|
export const LINUX_CONTAINER_PRESETS = Object.freeze({
|
|
@@ -46,6 +76,7 @@ const RUNNER_PRESET_ALIASES = Object.freeze({
|
|
|
46
76
|
kungfu: "kungfu-v4-self-hosted",
|
|
47
77
|
"kungfu-self-hosted": "kungfu-v4-self-hosted",
|
|
48
78
|
"kungfu-v4": "kungfu-v4-self-hosted",
|
|
79
|
+
"kungfu-v4-four-platform": "kungfu-v4-native",
|
|
49
80
|
});
|
|
50
81
|
|
|
51
82
|
const LINUX_CONTAINER_PRESET_ALIASES = Object.freeze({
|
|
@@ -9,6 +9,7 @@ const STABLE_PUBLISH_CHANNELS = new Set(["release", "major"]);
|
|
|
9
9
|
const OFFICIAL_REF = /^v(\d+)(?:\.\d+)?(?:-alpha)?$/;
|
|
10
10
|
const EXACT_SHA = /^[0-9a-f]{40}$/i;
|
|
11
11
|
const TRAIN_REF = /^(?:refs\/heads\/)?train\/v(\d+)\/v\d+\.\d+\/[A-Za-z0-9._/-]+$/;
|
|
12
|
+
const AUTHORITY_REF = /^(?:refs\/heads\/)?authority\/v(\d+)\/v\d+\.\d+\/[A-Za-z0-9._/-]+$/;
|
|
12
13
|
const SEMVER_TAG = /^refs\/tags\/v?\d+\.\d+\.\d+(?:-([0-9A-Za-z.-]+))?$/;
|
|
13
14
|
|
|
14
15
|
function normalized(value) {
|
|
@@ -36,6 +37,8 @@ function majorFrom(value) {
|
|
|
36
37
|
if (official) return Number(official[1]);
|
|
37
38
|
const train = text.match(TRAIN_REF);
|
|
38
39
|
if (train) return Number(train[1]);
|
|
40
|
+
const authority = text.match(AUTHORITY_REF);
|
|
41
|
+
if (authority) return Number(authority[1]);
|
|
39
42
|
const embedded = text.match(/(?:^|\/)v(\d+)(?:$|[./-])/);
|
|
40
43
|
if (embedded) return Number(embedded[1]);
|
|
41
44
|
const version = text.match(/^(\d+)\.\d+\.\d+/);
|
|
@@ -57,6 +60,9 @@ function classifyRequestedRef(value) {
|
|
|
57
60
|
if (TRAIN_REF.test(value) || TRAIN_REF.test(ref)) {
|
|
58
61
|
return { kind: "override", ref: normalized(value).replace(/^refs\/heads\//, "") };
|
|
59
62
|
}
|
|
63
|
+
if (AUTHORITY_REF.test(value) || AUTHORITY_REF.test(ref)) {
|
|
64
|
+
return { kind: "override", ref: normalized(value).replace(/^refs\/heads\//, "") };
|
|
65
|
+
}
|
|
60
66
|
const official = ref.match(OFFICIAL_REF);
|
|
61
67
|
if (official) {
|
|
62
68
|
return {
|
|
@@ -65,7 +71,7 @@ function classifyRequestedRef(value) {
|
|
|
65
71
|
major: Number(official[1]),
|
|
66
72
|
};
|
|
67
73
|
}
|
|
68
|
-
throw new Error("buildchain-ref must be an official vN/vN.M channel, a train ref, or an exact 40-character SHA");
|
|
74
|
+
throw new Error("buildchain-ref must be an official vN/vN.M channel, a train ref, an authority ref, or an exact 40-character SHA");
|
|
69
75
|
}
|
|
70
76
|
|
|
71
77
|
function selected(channel, major, source, reason) {
|
|
@@ -100,7 +106,7 @@ export function resolveBuildchainChannel({
|
|
|
100
106
|
throw new Error(`buildchain-channel=${channel} conflicts with buildchain-ref=${explicitRef.ref}`);
|
|
101
107
|
}
|
|
102
108
|
if (channel !== "auto" && explicitRef.kind === "override") {
|
|
103
|
-
throw new Error("train and exact-SHA buildchain-ref overrides require buildchain-channel=auto");
|
|
109
|
+
throw new Error("train, authority, and exact-SHA buildchain-ref overrides require buildchain-channel=auto");
|
|
104
110
|
}
|
|
105
111
|
return {
|
|
106
112
|
channel: explicitRef.kind,
|
|
@@ -68,8 +68,14 @@ const requiredPaths = [
|
|
|
68
68
|
"docs/product-mechanism.md",
|
|
69
69
|
"docs/readme-badges.md",
|
|
70
70
|
"docs/release-passport.md",
|
|
71
|
+
"docs/github-artifact-attestation.md",
|
|
71
72
|
"docs/shifu-gate-profiles.md",
|
|
72
73
|
"docs/auditable-demo.md",
|
|
74
|
+
"contracts/auditable-demo-media-profiles-v1.json",
|
|
75
|
+
"contracts/evidence/auditable-demo-web-delivery-v1.json",
|
|
76
|
+
"contracts/fixtures/auditable-demo-web-delivery-v1/complete-transcript.txt",
|
|
77
|
+
"contracts/fixtures/auditable-demo-web-delivery-v1/public-projection.json",
|
|
78
|
+
"contracts/fixtures/auditable-demo-web-delivery-v1/scene.json",
|
|
73
79
|
"docs/release-propagation.md",
|
|
74
80
|
"docs/site-bundle-contract.md",
|
|
75
81
|
"docs/toolkit-observability.md",
|
|
@@ -358,6 +364,9 @@ if (rootPackage.exports?.["./kfd-gate"] !== "./packages/core/kfd-gate.js") {
|
|
|
358
364
|
if (rootPackage.exports?.["./release-passport"] !== "./packages/core/release-passport.js") {
|
|
359
365
|
throw new Error("root package must export @kungfu-tech/buildchain/release-passport");
|
|
360
366
|
}
|
|
367
|
+
if (rootPackage.exports?.["./github-artifact-attestation"] !== "./packages/core/github-artifact-attestation.js") {
|
|
368
|
+
throw new Error("root package must export @kungfu-tech/buildchain/github-artifact-attestation");
|
|
369
|
+
}
|
|
361
370
|
if (rootPackage.exports?.["./release-passport-contract"] !== "./packages/core/release-passport-contract.js") {
|
|
362
371
|
throw new Error("root package must export @kungfu-tech/buildchain/release-passport-contract");
|
|
363
372
|
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import process from "node:process";
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
GITHUB_ARTIFACT_ATTESTATION_WORKFLOW,
|
|
9
|
+
createGitHubArtifactAttestationPolicy,
|
|
10
|
+
githubArtifactAttestationSha256File,
|
|
11
|
+
} from "../packages/core/github-artifact-attestation.js";
|
|
12
|
+
|
|
13
|
+
function env(name, fallback = "") {
|
|
14
|
+
return String(process.env[name] || fallback).trim();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function required(name) {
|
|
18
|
+
const value = env(name);
|
|
19
|
+
if (!value) throw new Error(`${name} is required`);
|
|
20
|
+
return value;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const cwd = path.resolve(env("BUILDCHAIN_SOURCE_CWD", "."));
|
|
24
|
+
const subjectRelativePath = required("BUILDCHAIN_GITHUB_ATTESTATION_SUBJECT_PATH").replace(/\\/g, "/");
|
|
25
|
+
const subjectPath = path.resolve(cwd, subjectRelativePath);
|
|
26
|
+
const manifestPath = path.resolve(required("BUILDCHAIN_GITHUB_ATTESTATION_PLATFORM_MANIFEST"));
|
|
27
|
+
const outputPath = path.resolve(required("BUILDCHAIN_GITHUB_ATTESTATION_POLICY_OUTPUT"));
|
|
28
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
|
|
29
|
+
const manifestEntry = (manifest.files || []).find((entry) => (
|
|
30
|
+
String(entry.path || "").replace(/\\/g, "/") === subjectRelativePath
|
|
31
|
+
));
|
|
32
|
+
if (!manifestEntry) throw new Error(`platform manifest does not contain ${subjectRelativePath}`);
|
|
33
|
+
const digest = githubArtifactAttestationSha256File(subjectPath);
|
|
34
|
+
const size = fs.statSync(subjectPath).size;
|
|
35
|
+
if (`sha256:${String(manifestEntry.sha256 || "").toLowerCase()}` !== digest || Number(manifestEntry.size) !== size) {
|
|
36
|
+
throw new Error("subject bytes do not match the final platform manifest");
|
|
37
|
+
}
|
|
38
|
+
const manifestDigest = githubArtifactAttestationSha256File(manifestPath);
|
|
39
|
+
const runtimeSha = required("BUILDCHAIN_RUNTIME_SHA").toLowerCase();
|
|
40
|
+
const signerSha = required("BUILDCHAIN_GITHUB_ATTESTATION_SIGNER_SHA").toLowerCase();
|
|
41
|
+
const policy = createGitHubArtifactAttestationPolicy({
|
|
42
|
+
subject: { name: path.basename(subjectPath), path: subjectRelativePath, size, digest },
|
|
43
|
+
caller: {
|
|
44
|
+
repository: required("BUILDCHAIN_SOURCE_REPOSITORY"),
|
|
45
|
+
sourceSha: required("BUILDCHAIN_SOURCE_SHA").toLowerCase(),
|
|
46
|
+
sourceTreeSha: required("BUILDCHAIN_SOURCE_TREE_SHA").toLowerCase(),
|
|
47
|
+
},
|
|
48
|
+
signer: {
|
|
49
|
+
repository: "kungfu-systems/buildchain",
|
|
50
|
+
workflowPath: GITHUB_ARTIFACT_ATTESTATION_WORKFLOW,
|
|
51
|
+
workflowDigest: signerSha,
|
|
52
|
+
},
|
|
53
|
+
build: {
|
|
54
|
+
platform: required("BUILDCHAIN_PLATFORM_ID"),
|
|
55
|
+
platformManifestDigest: manifestDigest,
|
|
56
|
+
runnerReceiptRoot: manifestDigest,
|
|
57
|
+
buildchainRuntimeSha: runtimeSha,
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
61
|
+
fs.writeFileSync(outputPath, `${JSON.stringify(policy, null, 2)}\n`);
|
|
62
|
+
process.stdout.write(`github-artifact-attestation-policy=${outputPath}\n`);
|