@kungfu-tech/buildchain 4.0.2-alpha.44 → 4.0.2-alpha.46
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/architecture/agent-change-map.md +1 -1
- package/architecture/maintainability-debt.json +24 -25
- package/architecture/maintainability-policy.json +4 -4
- package/architecture/v4-release-topology.json +9 -6
- package/architecture/v4-universal-workflow-train-admission.json +1 -1
- package/dist/site/buildchain-contract.json +7 -7
- package/dist/site/buildchain-site.json +55 -14
- package/dist/site/capability-registry.json +2 -2
- package/dist/site/kfd-claims.json +29 -5
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +3 -3
- package/dist/site/node-api-registry.json +154 -13
- package/dist/site/page-registry.json +48 -7
- package/dist/site/public-surface-audit.json +7 -3
- package/dist/site/publication-authority-registry.json +5 -17
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/release-provenance.json +2 -1
- package/dist/site/site-manifest.json +7 -7
- package/dist/site/workflow-registry.json +5 -5
- package/docs/MAP.md +1 -0
- package/docs/node-api-reference.md +26 -15
- package/docs/oci-publication.md +82 -0
- package/docs/publish-transaction.md +36 -3
- package/package.json +3 -2
- package/packages/core/buildchain-v4-domain.wasm +0 -0
- package/packages/core/next-development-transition.js +5 -6
- package/packages/core/oci-publication-bundle.js +241 -0
- package/packages/core/publication-sealed-bundle.js +77 -13
- package/packages/core/release-tail-product-capabilities.js +9 -0
- package/packages/core/v4-canonical-contracts.js +1 -0
- package/packages/core/v4-domain-wasm-artifact.js +2 -2
- package/packages/core/v4-product-publication.js +2 -0
- package/scripts/check-v4-release-topology.mjs +14 -4
- package/scripts/generate-channel-promotion-workflow.mjs +2 -19
- package/scripts/generate-v4-universal-workflow-facades.mjs +8 -2
- package/scripts/publication-candidate-kind.mjs +92 -0
- package/scripts/publication-candidate-sealer.mjs +16 -1
- package/scripts/release-candidate-resolver.mjs +6 -17
- package/scripts/resume-from-candidate-run.mjs +10 -17
- package/scripts/site-capability-metadata.mjs +1 -0
- package/scripts/v4-product-publication-intent.mjs +9 -1
- package/scripts/v4-universal-workflow-engine.mjs +2 -0
|
@@ -7,7 +7,7 @@ import { execFileSync } from "node:child_process";
|
|
|
7
7
|
import { Readable } from "node:stream";
|
|
8
8
|
import { pipeline } from "node:stream/promises";
|
|
9
9
|
import { pathToFileURL } from "node:url";
|
|
10
|
-
import {
|
|
10
|
+
import { resolveCandidatePublicationBundle } from "./publication-candidate-sealer.mjs";
|
|
11
11
|
import { writeGitHubOutputs } from "./build-contract-core.mjs";
|
|
12
12
|
import { v4ContentRoot } from "../packages/core/v4-canonical-contracts.js";
|
|
13
13
|
import { v4PublicationQualificationRoot, validateV4PublicationQualificationReceipt } from "../packages/core/v4-publication-qualification.js";
|
|
@@ -725,23 +725,12 @@ export async function resolveReleaseCandidateArtifacts({
|
|
|
725
725
|
const noun = publishArtifactKind === "npm" ? "npm package tarballs" : "platform manifests";
|
|
726
726
|
throw new Error(`expected at least ${minimumPayloadCount} downloaded ${noun}, found ${downloadedRequiredArtifactCount}`);
|
|
727
727
|
}
|
|
728
|
-
const sealedBundle = publishArtifactKind
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
sourceSha: passport.source?.headSha,
|
|
733
|
-
sourceTreeSha: passport.source?.treeHash,
|
|
734
|
-
runtimeSha: releaseCandidateRuntimeSha(passport),
|
|
735
|
-
releaseCandidateRoot: passport.candidateHash,
|
|
736
|
-
npmArtifacts: npmTarballPaths.map((tarballPath) => ({
|
|
737
|
-
path: tarballPath,
|
|
738
|
-
...readNpmPackageArtifact({ tarballPath, mainPackage: publishPackageMain }),
|
|
739
|
-
})),
|
|
740
|
-
releaseAssetPaths,
|
|
741
|
-
})
|
|
742
|
-
: undefined;
|
|
728
|
+
const sealedBundle = resolveCandidatePublicationBundle({ kind: publishArtifactKind, payloadDir, passport,
|
|
729
|
+
runtimeSha: releaseCandidateRuntimeSha(passport), releaseAssetPaths,
|
|
730
|
+
npmArtifacts: npmTarballPaths.map((tarballPath) => ({ path: tarballPath,
|
|
731
|
+
...readNpmPackageArtifact({ tarballPath, mainPackage: publishPackageMain }) })) });
|
|
743
732
|
const manifests = platformManifestPaths.map((manifestPath) => JSON.parse(fs.readFileSync(manifestPath, "utf8"))), publicationVersion = resolveFreshPublicationVersion({ sealedBundle, candidateVersion: passport.target?.version });
|
|
744
|
-
const generatedRequiredArtifacts = generatePublishRequiredArtifacts({
|
|
733
|
+
const generatedRequiredArtifacts = sealedBundle?.requiredArtifacts || generatePublishRequiredArtifacts({
|
|
745
734
|
manifests,
|
|
746
735
|
version: publicationVersion,
|
|
747
736
|
kind: publishArtifactKind,
|
|
@@ -6,6 +6,8 @@ import path from "node:path";
|
|
|
6
6
|
import { execFileSync } from "node:child_process";
|
|
7
7
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
8
8
|
|
|
9
|
+
import { resolveOciCandidate, resolveRecoveredPublicationVersion, resolveRecoveredCandidateVersion } from "./publication-candidate-kind.mjs";
|
|
10
|
+
export { resolveRecoveredPublicationVersion, resolveRecoveredCandidateVersion } from "./publication-candidate-kind.mjs";
|
|
9
11
|
import { writeGitHubOutputs } from "./build-contract-core.mjs";
|
|
10
12
|
import { compareSemver } from "./publication-registry-hydrate.mjs";
|
|
11
13
|
import { normalizeAnchorProvenance, normalizeCandidateRun, recoverCandidateProvenance } from "./release-candidate-anchor-provenance.mjs";
|
|
@@ -695,22 +697,6 @@ export function createRecoveredPublicationCandidate({
|
|
|
695
697
|
};
|
|
696
698
|
return { ...payload, candidateDigest: publicationArtifactCandidateDigest(payload) };
|
|
697
699
|
}
|
|
698
|
-
export function resolveRecoveredPublicationVersion({ artifactVersion, channel, rematerializeOnResume = false } = {}) {
|
|
699
|
-
const version = String(artifactVersion || "").trim(), match = version.match(/^(\d+\.\d+\.\d+)(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/u);
|
|
700
|
-
if (!match) throw new Error(`recovered npm artifact has invalid publication version: ${version || "<empty>"}`);
|
|
701
|
-
return channel === "release" && rematerializeOnResume ? match[1] : version;
|
|
702
|
-
}
|
|
703
|
-
export function resolveRecoveredCandidateVersion({ artifactVersion, publicationVersion, channel, rematerializeOnResume = false, targetRef = "", candidateRef = "" } = {}) {
|
|
704
|
-
const version = String(artifactVersion || "").trim(), target = String(targetRef || "").replace(/^refs\/heads\//u, ""), candidate = String(candidateRef || "").replace(/^refs\/heads\//u, "");
|
|
705
|
-
if (channel !== "release" || !rematerializeOnResume) return version;
|
|
706
|
-
const prefix = `publish-gate/${target}/`;
|
|
707
|
-
if (!target || !candidate.startsWith(prefix)) throw new Error(`stable recovery candidate ref must descend from ${prefix || "publish-gate/<target>/"}`);
|
|
708
|
-
const candidateVersion = candidate.slice(prefix.length);
|
|
709
|
-
if (!/^\d+\.\d+\.\d+-alpha\.\d+$/u.test(candidateVersion)) throw new Error(`stable recovery candidate ref must bind an exact alpha version, got ${candidateVersion || "<empty>"}`);
|
|
710
|
-
if (candidateVersion.replace(/-alpha\.\d+$/u, "") !== publicationVersion) throw new Error(`stable recovery candidate ${candidateVersion} does not match publication ${publicationVersion || "<empty>"}`);
|
|
711
|
-
if ((version.match(/^(\d+\.\d+\.\d+)(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/u)?.[1] || "") !== publicationVersion) throw new Error(`recovered npm artifact version ${version || "<empty>"} does not match publication ${publicationVersion}`);
|
|
712
|
-
return candidateVersion;
|
|
713
|
-
}
|
|
714
700
|
export function createRecoveredPublication({ downloads, bundleRoot, repository, passport, candidateRuntimeSha, publishArtifactKind, publishPackageMain, releasePatterns, platformManifests, channel, targetRef = "", candidateRef = "", rematerializeOnResume = false }) {
|
|
715
701
|
const allFiles = downloads.flatMap((download) => download.files.map((file) => ({ path: path.relative(bundleRoot, file.absolutePath).split(path.sep).join("/"),
|
|
716
702
|
size: file.size, sha256: file.sha256.replace(/^sha256:/, ""), absolutePath: file.absolutePath })))
|
|
@@ -718,6 +704,13 @@ export function createRecoveredPublication({ downloads, bundleRoot, repository,
|
|
|
718
704
|
const kind = String(publishArtifactKind || "npm");
|
|
719
705
|
const releaseMatchers = splitPatterns(releasePatterns).map(patternMatcher);
|
|
720
706
|
const releaseAssets = allFiles.filter((file) => releaseMatchers.some((matcher) => matcher.test(path.basename(file.path))));
|
|
707
|
+
if (kind === "oci") {
|
|
708
|
+
createRecoveredPublicationCandidate({ allFiles, repository, passport, candidateRuntimeSha });
|
|
709
|
+
const sealed = resolveOciCandidate({ payloadRoot: bundleRoot, passport });
|
|
710
|
+
return { manifest: sealed.manifest, bundleRoot: sealed.root, npmArtifacts: [], allFiles, releaseAssets,
|
|
711
|
+
version: sealed.manifest.version, candidateVersion: sealed.manifest.version,
|
|
712
|
+
publishRequiredArtifacts: sealed.requiredArtifacts };
|
|
713
|
+
}
|
|
721
714
|
if (kind !== "npm") {
|
|
722
715
|
createRecoveredPublicationCandidate({ allFiles, repository, passport, candidateRuntimeSha });
|
|
723
716
|
const version = String(passport.target?.version || "").trim();
|
|
@@ -1019,7 +1012,7 @@ export async function resumeFromCandidateRun({
|
|
|
1019
1012
|
npmTarballs: tarballs,
|
|
1020
1013
|
releaseAssets: publication.releaseAssets.map((asset) => outputPath(asset.absolutePath)),
|
|
1021
1014
|
publishRequiredArtifacts: outputPath(requiredArtifactsPath),
|
|
1022
|
-
sealedBundleRoot: publication.manifest ? outputPath(bundleRoot) : "",
|
|
1015
|
+
sealedBundleRoot: publication.manifest ? outputPath(publication.bundleRoot || bundleRoot) : "",
|
|
1023
1016
|
sealedBundleManifest: publication.manifest ? outputPath(sealedManifestPath) : "",
|
|
1024
1017
|
recoveryReceipt: outputPath(recoveryReceiptPath),
|
|
1025
1018
|
stageCapsules: stageCapsuleFile ? outputPath(stageCapsuleFile.absolutePath) : "",
|
|
@@ -206,6 +206,7 @@ export function nodeApiMeta(exportName) {
|
|
|
206
206
|
"./publication-artifact": { group: "reusable-build", summary: "Publication artifact manifest, source bundle, and publication passport APIs." },
|
|
207
207
|
"./publication-package": { group: "reusable-build", summary: "Publication npm package synthesis APIs for Buildchain-managed paper release presets." },
|
|
208
208
|
"./publication-reproducibility": { group: "reusable-build", summary: "Two-clean-build publication byte reproducibility receipt APIs." },
|
|
209
|
+
"./oci-publication": { group: "reusable-build", summary: "Sealed OCI image family verification, provenance, and smoke evidence APIs." },
|
|
209
210
|
"./publication-sealed-bundle": { group: "reusable-build", summary: "Build-once publication bundle manifests and exact-byte resume verification APIs." },
|
|
210
211
|
"./paper": { group: "reusable-build", summary: "Unified Paper work, fleet, scaffold, preflight, npm bootstrap, build, Alpha, status, and resume planning APIs." },
|
|
211
212
|
"./publication-authority": { group: "release-passport-trust", summary: "Sealed publication authority registry, runner provenance, control-plane audit, admission, and independent verification APIs." },
|
|
@@ -65,7 +65,7 @@ export function resolveV4ProductPublicationIntent() {
|
|
|
65
65
|
const sourceSha = env("BUILDCHAIN_SOURCE_SHA", true);
|
|
66
66
|
const manifestPath = env(
|
|
67
67
|
"BUILDCHAIN_SEALED_BUNDLE_MANIFEST",
|
|
68
|
-
artifactKind
|
|
68
|
+
artifactKind !== "custom",
|
|
69
69
|
);
|
|
70
70
|
const manifest = manifestPath ? readJson(manifestPath) : null;
|
|
71
71
|
const requiredArtifacts = readJson(
|
|
@@ -80,6 +80,14 @@ export function resolveV4ProductPublicationIntent() {
|
|
|
80
80
|
repository: env("BUILDCHAIN_REPOSITORY", true),
|
|
81
81
|
artifactKind,
|
|
82
82
|
packageName: name,
|
|
83
|
+
...(manifest?.npmPackages
|
|
84
|
+
? {
|
|
85
|
+
npmPackages: manifest.npmPackages.map((entry) => ({
|
|
86
|
+
...entry,
|
|
87
|
+
sha256: `sha256:${entry.sha256}`,
|
|
88
|
+
})),
|
|
89
|
+
}
|
|
90
|
+
: {}),
|
|
83
91
|
distTag:
|
|
84
92
|
env("BUILDCHAIN_PUBLISH_DIST_TAG") ||
|
|
85
93
|
(channel === "alpha" ? "alpha" : "latest"),
|
|
@@ -306,6 +306,7 @@ async function materializeProductPublicationIntent({
|
|
|
306
306
|
BUILDCHAIN_SEALED_BUNDLE_MANIFEST: candidate.paths.sealedBundleManifest,
|
|
307
307
|
BUILDCHAIN_REQUIRED_ARTIFACTS_PATH:
|
|
308
308
|
candidate.paths.publishRequiredArtifacts,
|
|
309
|
+
BUILDCHAIN_PUBLISH_ARTIFACT_KIND: inputs["publish-artifact-kind"] || "npm",
|
|
309
310
|
BUILDCHAIN_PUBLISH_PACKAGE_MAIN: inputs["publish-package-main"] || "",
|
|
310
311
|
BUILDCHAIN_PUBLISH_DIST_TAG: inputs["publish-dist-tag"] || "",
|
|
311
312
|
BUILDCHAIN_PRODUCT_PUBLICATION_INTENT_PATH: intentPath,
|
|
@@ -449,6 +450,7 @@ async function executeReleasePromotion(request, admission) {
|
|
|
449
450
|
"candidate-build-summary-path": candidate.paths.buildSummary,
|
|
450
451
|
"stage-capsules-path": candidate.paths.stageCapsules,
|
|
451
452
|
"publication-qualification-path": candidate.paths.publicationQualification,
|
|
453
|
+
"publish-artifact-kind": payload.inputs["publish-artifact-kind"] || "npm",
|
|
452
454
|
"sealed-bundle-root": candidate.paths.sealedBundleRoot,
|
|
453
455
|
"sealed-bundle-manifest": candidate.paths.sealedBundleManifest,
|
|
454
456
|
"required-artifacts-path": candidate.paths.publishRequiredArtifacts,
|