@kungfu-tech/buildchain 4.0.1-alpha.0 → 4.0.1-alpha.3
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/AGENTS.md +13 -5
- package/actions/promote-buildchain-ref/README.md +11 -6
- package/architecture/decisions/0003-two-phase-delivery-warrant.md +152 -0
- package/architecture/internal-capabilities.json +105 -2
- package/architecture/maintainability-policy.json +218 -19
- package/architecture/v3-core-mechanism-inventory.json +2 -0
- package/architecture/v4-delivery-authority-parity.json +250 -0
- package/architecture/v4-delivery-warrant-shadow-fixtures.json +29 -6
- package/architecture/v4-floating-consumer-policy.json +75 -0
- package/architecture/v4-floating-consumer-policy.md +32 -0
- package/architecture/v4-runtime-ref-resume-authority.json +64 -0
- package/architecture/v4-stage-capsule-qualification.json +2 -2
- package/bin/buildchain.mjs +9 -1
- package/bin/internal/trust-release-release-handlers.mjs +5 -0
- package/contracts/dev-delivery-authority-v2.schema.json +662 -0
- package/contracts/fixtures/v4-floating-consumer-policy-v1/cases.json +53 -0
- package/contracts/fixtures/v4-runtime-ref-resume-authority-v1/scenario.json +15 -0
- package/contracts/v4-floating-consumer-policy-receipt-v1.schema.json +105 -0
- package/contracts/v4-runtime-ref-resume-authority-v1.schema.json +235 -0
- package/dist/site/agent-index.json +1 -0
- package/dist/site/artifact-schemas.json +2 -0
- package/dist/site/buildchain-contract.json +186 -33
- package/dist/site/buildchain-site.json +229 -32
- package/dist/site/capability-registry.json +3 -3
- package/dist/site/cli-registry.json +46 -2
- package/dist/site/controller-registry.json +62 -6
- package/dist/site/kfd-claims.json +105 -16
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +7 -7
- package/dist/site/node-api-registry.json +7491 -5290
- package/dist/site/page-registry.json +218 -21
- package/dist/site/public-surface-audit.json +412 -20
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/release-provenance.json +4 -0
- package/dist/site/schemas/dev-delivery-authority-v2.schema.json +662 -0
- package/dist/site/site-manifest.json +11 -11
- package/dist/site/workflow-registry.json +63 -19
- package/docs/MAP.md +3 -0
- package/docs/cli-reference.md +211 -13
- package/docs/dev-delivery-qualification-landing-adr.md +251 -0
- package/docs/dev-delivery-warrant.md +336 -30
- package/docs/lifecycle-protocol.md +41 -0
- package/docs/node-api-reference.md +319 -186
- package/docs/reusable-build-surface.md +41 -0
- package/docs/runtime-train-validation.md +10 -0
- package/docs/v4-runtime-ref-resume-authority.md +69 -0
- package/docs/versioning.md +1 -0
- package/package.json +10 -4
- package/packages/core/artifact-signing.js +61 -0
- package/packages/core/buildchain-config.js +66 -1
- package/packages/core/buildchain-contract.js +3 -2
- package/packages/core/dev-delivery-authority-candidate.js +270 -0
- package/packages/core/dev-delivery-authority-evidence.js +146 -0
- package/packages/core/dev-delivery-authority-landing.js +461 -0
- package/packages/core/dev-delivery-authority-observation.js +48 -0
- package/packages/core/dev-delivery-authority-qualification.js +591 -0
- package/packages/core/dev-delivery-authority-settlement.js +213 -0
- package/packages/core/dev-delivery-authority-state.js +583 -0
- package/packages/core/dev-delivery-candidate-identity.js +13 -0
- package/packages/core/dev-delivery-contract-surface.js +76 -0
- package/packages/core/dev-delivery-execution-failure.js +133 -0
- package/packages/core/dev-delivery-execution-transfer.js +572 -0
- package/packages/core/dev-delivery-landing-admission-core.js +119 -0
- package/packages/core/dev-delivery-landing-readback.js +598 -0
- package/packages/core/dev-delivery-landing-terminal-evidence.js +271 -0
- package/packages/core/dev-delivery-landing-testing-port.js +6 -0
- package/packages/core/dev-delivery-native-execution.js +110 -0
- package/packages/core/dev-delivery-native-proof.js +546 -0
- package/packages/core/dev-delivery-process-boundary.js +551 -0
- package/packages/core/dev-delivery-proof.js +37 -3
- package/packages/core/dev-delivery-provider-attempt.js +127 -0
- package/packages/core/dev-delivery-provider-heartbeat.js +370 -0
- package/packages/core/dev-delivery-warrant-cancellation.js +1 -0
- package/packages/core/dev-delivery-warrant-qualification.js +145 -0
- package/packages/core/dev-delivery-warrant-settlement.js +237 -36
- package/packages/core/dev-delivery-warrant-state.js +565 -0
- package/packages/core/dev-delivery-warrant.js +320 -368
- package/packages/core/index.js +2 -0
- package/packages/core/publication-authority.js +5 -5
- package/packages/core/release-candidate.js +79 -19
- package/packages/core/release-passport.js +239 -33
- package/packages/core/v4-floating-consumer-evidence.js +324 -0
- package/packages/core/v4-floating-consumer-policy.js +446 -0
- package/packages/core/v4-floating-consumer-release-passport.js +126 -0
- package/packages/core/v4-runtime-ref-resume-authority.js +625 -0
- package/packages/core/v4-runtime-selector-persistence.js +228 -0
- package/packages/core/workflow-yaml-contract.js +48 -0
- package/scripts/audit-publication-control-plane.mjs +31 -31
- package/scripts/buildchain-cli-help.mjs +11 -2
- package/scripts/check-inventory.mjs +1 -1
- package/scripts/check-v4-floating-consumer-policy-contract.mjs +198 -0
- package/scripts/check-v4-public-dogfood-contract.mjs +6 -11
- package/scripts/dev-delivery-authority-command-adapters.mjs +206 -0
- package/scripts/dev-delivery-authority-provider.mjs +28 -0
- package/scripts/dev-delivery-authority.mjs +490 -0
- package/scripts/dev-delivery-native-run.mjs +177 -0
- package/scripts/dev-delivery-process-boundary.mjs +260 -0
- package/scripts/dev-delivery-proof.mjs +67 -2
- package/scripts/dev-delivery-provider-heartbeat.mjs +215 -0
- package/scripts/dev-delivery-source-proof-reuse.mjs +631 -0
- package/scripts/dev-delivery-two-phase-resume.mjs +345 -0
- package/scripts/dev-delivery-two-phase.mjs +573 -0
- package/scripts/dev-delivery-warrant-options.mjs +266 -0
- package/scripts/dev-delivery-warrant-store.mjs +227 -0
- package/scripts/dev-delivery-warrant.mjs +227 -193
- package/scripts/dev-pr-auto-merge.mjs +37 -48
- package/scripts/dev-pr-delivery-warrant.mjs +215 -2
- package/scripts/dev-pr-prequeue-guard.mjs +399 -0
- package/scripts/ensure-github-release.mjs +3 -3
- package/scripts/generate-channel-build-workflow.mjs +3 -0
- package/scripts/generate-channel-promotion-workflow.mjs +112 -12
- package/scripts/generate-release-candidate-passport.mjs +41 -33
- package/scripts/generate-site-bundle.mjs +26 -4
- package/scripts/init-repo.mjs +5 -1
- package/scripts/inspect-artifact-signing-requests.mjs +6 -0
- package/scripts/npm-publish-transaction.mjs +103 -91
- package/scripts/resume-from-candidate-run.mjs +11 -14
- package/scripts/seal-artifact-signing-requests.mjs +6 -0
- package/scripts/site-capability-metadata.mjs +14 -0
- package/scripts/v4-consumer-policy.mjs +231 -0
- package/templates/native-dev-delivery.yml +141 -0
|
@@ -1,19 +1,30 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
|
+
import { execFileSync } from "node:child_process";
|
|
4
5
|
import { pathToFileURL } from "node:url";
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
validateReleaseCandidatePassport,
|
|
8
|
-
} from "../packages/core/release-candidate.js";
|
|
6
|
+
import { createReleaseCandidatePassport, validateReleaseCandidatePassport } from "../packages/core/release-candidate.js";
|
|
7
|
+
import { scanV4FloatingConsumerPolicy, v4ConsumerPolicyScannerRoot } from "../packages/core/v4-floating-consumer-policy.js";
|
|
9
8
|
import { writeGitHubOutputs } from "./build-contract-core.mjs";
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
10
|
+
const env = (name, fallback = "") => process.env[name] || fallback;
|
|
11
|
+
const readJsonFile = (filePath) => JSON.parse(fs.readFileSync(filePath, "utf8"));
|
|
14
12
|
|
|
15
|
-
function
|
|
16
|
-
return JSON.parse(
|
|
13
|
+
export function resolveLegacyConsumerPolicyReceipt(options = {}) {
|
|
14
|
+
if (options.json) return { receipt: JSON.parse(options.json), receiptRoot: options.receiptRoot };
|
|
15
|
+
if (options.repository !== "kungfu-systems/buildchain" || options.targetChannel !== "alpha" || options.workflowShellRef !== "v4-alpha" || options.runtimeOverride !== true) return undefined;
|
|
16
|
+
if (!/^[0-9a-f]{40}$/u.test(options.runtimeRef || "") || options.runtimeRef !== options.runtimeSha || options.sourceTreeHash !== options.runtimeTreeHash()) return undefined;
|
|
17
|
+
const root = path.resolve(options.root || ".buildchain/runtime");
|
|
18
|
+
const alphaLock = readJsonFile(path.join(root, ".buildchain/alpha-contract-lock.json"));
|
|
19
|
+
const result = scanV4FloatingConsumerPolicy({
|
|
20
|
+
root, repository: options.repository, sourceSha: options.sourceSha,
|
|
21
|
+
invokedWorkflow: options.invokedWorkflow || ".github/workflows/build.yml", invocationSourcePath: options.invocationSourcePath,
|
|
22
|
+
expectedInvocationChannel: "alpha", resolvedWorkflowSha: alphaLock.buildchain?.resolvedSha,
|
|
23
|
+
resolvedRuntimeSha: options.runtimeSha, scannerRoot: v4ConsumerPolicyScannerRoot(),
|
|
24
|
+
policy: readJsonFile(path.resolve(import.meta.dirname, "../architecture/v4-floating-consumer-policy.json")),
|
|
25
|
+
});
|
|
26
|
+
if (!result.ok) throw new Error(`legacy floating-shell policy receipt invalid: ${result.failures.map(({ code }) => code).join(", ")}`);
|
|
27
|
+
return { receipt: result.receipt, receiptRoot: result.receiptRoot };
|
|
17
28
|
}
|
|
18
29
|
|
|
19
30
|
export function generateReleaseCandidatePassportCli() {
|
|
@@ -21,23 +32,28 @@ export function generateReleaseCandidatePassportCli() {
|
|
|
21
32
|
const outputPath = path.resolve(env("BUILDCHAIN_RC_PASSPORT_PATH", ".buildchain/artifacts/release-candidate-passport.json"));
|
|
22
33
|
const buildSummary = readJsonFile(buildSummaryPath);
|
|
23
34
|
const sourceSha = env("BUILDCHAIN_RC_SOURCE_HEAD_SHA", buildSummary.publishSource?.sha || buildSummary.git?.sha || "");
|
|
24
|
-
const version = env(
|
|
25
|
-
"BUILDCHAIN_RC_VERSION",
|
|
26
|
-
buildSummary.publishSource?.consumerVersion || "",
|
|
27
|
-
);
|
|
35
|
+
const version = env("BUILDCHAIN_RC_VERSION", buildSummary.publishSource?.consumerVersion || "");
|
|
28
36
|
const gateAggregateJson = env("BUILDCHAIN_GATE_PROFILE_AGGREGATE_JSON");
|
|
29
37
|
const gateAggregate = gateAggregateJson ? JSON.parse(gateAggregateJson) : undefined;
|
|
30
38
|
const controllerReceiptJson = env("BUILDCHAIN_CONTROLLER_RECEIPT_JSON");
|
|
31
39
|
const controllerReceipts = controllerReceiptJson ? [JSON.parse(controllerReceiptJson)] : [];
|
|
32
40
|
const familyEvidenceJson = env("BUILDCHAIN_RC_FAMILY_EVIDENCE_JSON");
|
|
33
41
|
const familyEvidence = familyEvidenceJson ? JSON.parse(familyEvidenceJson) : undefined;
|
|
42
|
+
const consumerPolicyJson = env("BUILDCHAIN_V4_POLICY_RECEIPT_JSON");
|
|
43
|
+
const consumerPolicyReceipt = resolveLegacyConsumerPolicyReceipt({
|
|
44
|
+
json: consumerPolicyJson, receiptRoot: env("BUILDCHAIN_V4_POLICY_RECEIPT_ROOT"),
|
|
45
|
+
repository: env("GITHUB_REPOSITORY", buildSummary.git?.repository || ""), sourceSha,
|
|
46
|
+
targetChannel: env("BUILDCHAIN_RC_TARGET_CHANNEL", buildSummary.publishSource?.channel || buildSummary.publishGate?.channel || ""),
|
|
47
|
+
runtimeRef: env("BUILDCHAIN_RUNTIME_REF", buildSummary.runtime?.ref || ""), runtimeSha: env("BUILDCHAIN_RUNTIME_SHA", buildSummary.runtime?.sha || ""),
|
|
48
|
+
workflowShellRef: env("BUILDCHAIN_WORKFLOW_SHELL_REF", buildSummary.runtime?.workflowShellRef || ""), runtimeOverride: buildSummary.runtime?.override === true,
|
|
49
|
+
root: ".buildchain/runtime", invocationSourcePath: env("GITHUB_WORKFLOW_REF"), sourceTreeHash: env("BUILDCHAIN_RC_SOURCE_TREE_HASH"),
|
|
50
|
+
runtimeTreeHash: () => execFileSync("git", ["-C", ".buildchain/runtime", "rev-parse", "HEAD^{tree}"], { encoding: "utf8" }).trim(),
|
|
51
|
+
});
|
|
34
52
|
const passport = createReleaseCandidatePassport({
|
|
35
53
|
repository: env("GITHUB_REPOSITORY", buildSummary.git?.repository || ""),
|
|
36
54
|
pullRequest: {
|
|
37
|
-
number: env("BUILDCHAIN_PULL_REQUEST_NUMBER"),
|
|
38
|
-
|
|
39
|
-
headRef: env("BUILDCHAIN_PULL_REQUEST_HEAD_REF"),
|
|
40
|
-
baseRef: env("BUILDCHAIN_PULL_REQUEST_BASE_REF"),
|
|
55
|
+
number: env("BUILDCHAIN_PULL_REQUEST_NUMBER"), url: env("BUILDCHAIN_PULL_REQUEST_URL"),
|
|
56
|
+
headRef: env("BUILDCHAIN_PULL_REQUEST_HEAD_REF"), baseRef: env("BUILDCHAIN_PULL_REQUEST_BASE_REF"),
|
|
41
57
|
},
|
|
42
58
|
targetChannel: env("BUILDCHAIN_RC_TARGET_CHANNEL", buildSummary.publishSource?.channel || buildSummary.publishGate?.channel || ""),
|
|
43
59
|
version,
|
|
@@ -47,30 +63,21 @@ export function generateReleaseCandidatePassportCli() {
|
|
|
47
63
|
sourceTreeHash: env("BUILDCHAIN_RC_SOURCE_TREE_HASH"),
|
|
48
64
|
buildSummary,
|
|
49
65
|
buildchain: {
|
|
50
|
-
ref: env("BUILDCHAIN_RUNTIME_REF", buildSummary.runtime?.ref || ""),
|
|
51
|
-
|
|
52
|
-
version: env("BUILDCHAIN_RUNTIME_VERSION"),
|
|
53
|
-
workflowShellRef: env("BUILDCHAIN_WORKFLOW_SHELL_REF", buildSummary.runtime?.workflowShellRef || ""),
|
|
66
|
+
ref: env("BUILDCHAIN_RUNTIME_REF", buildSummary.runtime?.ref || ""), sha: env("BUILDCHAIN_RUNTIME_SHA", buildSummary.runtime?.sha || ""),
|
|
67
|
+
version: env("BUILDCHAIN_RUNTIME_VERSION"), workflowShellRef: env("BUILDCHAIN_WORKFLOW_SHELL_REF", buildSummary.runtime?.workflowShellRef || ""),
|
|
54
68
|
},
|
|
55
69
|
gateAggregate,
|
|
56
70
|
familyEvidence,
|
|
71
|
+
consumerPolicyReceipt,
|
|
57
72
|
controllerReceipts,
|
|
58
73
|
workflow: {
|
|
59
|
-
name: env("GITHUB_WORKFLOW"),
|
|
60
|
-
|
|
61
|
-
runAttempt: env("GITHUB_RUN_ATTEMPT", buildSummary.git?.runAttempt || ""),
|
|
62
|
-
url: env("BUILDCHAIN_WORKFLOW_RUN_URL"),
|
|
74
|
+
name: env("GITHUB_WORKFLOW"), runId: env("GITHUB_RUN_ID", buildSummary.git?.runId || ""),
|
|
75
|
+
runAttempt: env("GITHUB_RUN_ATTEMPT", buildSummary.git?.runAttempt || ""), url: env("BUILDCHAIN_WORKFLOW_RUN_URL"),
|
|
63
76
|
},
|
|
64
77
|
});
|
|
65
78
|
const validation = validateReleaseCandidatePassport({
|
|
66
|
-
passport,
|
|
67
|
-
|
|
68
|
-
sourceHeadSha: sourceSha,
|
|
69
|
-
buildSummary,
|
|
70
|
-
});
|
|
71
|
-
if (!validation.ok) {
|
|
72
|
-
throw new Error(`release candidate passport invalid: ${validation.errors.join("; ")}`);
|
|
73
|
-
}
|
|
79
|
+
passport, repository: env("GITHUB_REPOSITORY", buildSummary.git?.repository || ""), sourceHeadSha: sourceSha, buildSummary });
|
|
80
|
+
if (!validation.ok) throw new Error(`release candidate passport invalid: ${validation.errors.join("; ")}`);
|
|
74
81
|
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
75
82
|
fs.writeFileSync(outputPath, `${JSON.stringify(passport, null, 2)}\n`);
|
|
76
83
|
writeGitHubOutputs({
|
|
@@ -84,6 +91,7 @@ export function generateReleaseCandidatePassportCli() {
|
|
|
84
91
|
platformCount: passport.platformMatrix.length,
|
|
85
92
|
gateProfileEvidence: passport.gateProfileEvidence,
|
|
86
93
|
familyEvidence: passport.familyEvidence,
|
|
94
|
+
consumerPolicy: passport.consumerPolicy,
|
|
87
95
|
controllerReceipts: passport.controllerReceipts || [],
|
|
88
96
|
}),
|
|
89
97
|
});
|
|
@@ -46,6 +46,10 @@ import {
|
|
|
46
46
|
const SITE_BUNDLE_CONTRACT = "kungfu-buildchain-site-bundle";
|
|
47
47
|
const PUBLICATION_RELEASE_REGISTRY_CONTRACT = "kungfu-buildchain-publication-release-registry";
|
|
48
48
|
const README_PATH = "README.md";
|
|
49
|
+
const DEV_DELIVERY_AUTHORITY_SCHEMA =
|
|
50
|
+
"schemas/dev-delivery-authority-v2.schema.json";
|
|
51
|
+
const DEV_DELIVERY_AUTHORITY_SCHEMA_SOURCE =
|
|
52
|
+
"contracts/dev-delivery-authority-v2.schema.json";
|
|
49
53
|
const root = path.resolve(import.meta.dirname, "..");
|
|
50
54
|
const outputDir = path.join(root, "dist", "site");
|
|
51
55
|
const requireFromHere = createRequire(import.meta.url);
|
|
@@ -73,6 +77,18 @@ function stableJson(value) {
|
|
|
73
77
|
return `${JSON.stringify(value, null, 2)}\n`;
|
|
74
78
|
}
|
|
75
79
|
|
|
80
|
+
function siteFileBytes(name, value) {
|
|
81
|
+
return name === DEV_DELIVERY_AUTHORITY_SCHEMA
|
|
82
|
+
? readText(DEV_DELIVERY_AUTHORITY_SCHEMA_SOURCE)
|
|
83
|
+
: stableJson(value);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function writeSiteFile(name, value) {
|
|
87
|
+
const filePath = path.join(outputDir, name);
|
|
88
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
89
|
+
fs.writeFileSync(filePath, siteFileBytes(name, value));
|
|
90
|
+
}
|
|
91
|
+
|
|
76
92
|
function env(name) {
|
|
77
93
|
return String(process.env[name] || "").trim();
|
|
78
94
|
}
|
|
@@ -931,6 +947,7 @@ function buildSiteBundle() {
|
|
|
931
947
|
"schemas/release-passport-v1.schema.json",
|
|
932
948
|
"schemas/kfd-agent-hub-adoption.schema.json",
|
|
933
949
|
"schemas/kfd-product-gate-input-v1.schema.json",
|
|
950
|
+
"schemas/dev-delivery-authority-v2.schema.json",
|
|
934
951
|
"kfd-support.json",
|
|
935
952
|
"artifact-evidence.json",
|
|
936
953
|
"product-mechanism.json",
|
|
@@ -965,6 +982,7 @@ function buildSiteBundle() {
|
|
|
965
982
|
"schemas/release-passport-v1.schema.json",
|
|
966
983
|
"schemas/kfd-agent-hub-adoption.schema.json",
|
|
967
984
|
"schemas/kfd-product-gate-input-v1.schema.json",
|
|
985
|
+
"schemas/dev-delivery-authority-v2.schema.json",
|
|
968
986
|
"buildchain-contract.json",
|
|
969
987
|
"kfd-claims.json",
|
|
970
988
|
"product-mechanism.json",
|
|
@@ -1095,6 +1113,7 @@ function buildSiteBundle() {
|
|
|
1095
1113
|
"schemas/release-passport-v1.schema.json",
|
|
1096
1114
|
"schemas/kfd-agent-hub-adoption.schema.json",
|
|
1097
1115
|
"schemas/kfd-product-gate-input-v1.schema.json",
|
|
1116
|
+
"schemas/dev-delivery-authority-v2.schema.json",
|
|
1098
1117
|
"buildchain-contract.json",
|
|
1099
1118
|
"kfd-upstream-aggregate.json",
|
|
1100
1119
|
"kfd-claims.json",
|
|
@@ -1269,6 +1288,9 @@ function buildSiteBundle() {
|
|
|
1269
1288
|
"schemas/release-passport-v1.schema.json": RELEASE_PASSPORT_SCHEMA,
|
|
1270
1289
|
"schemas/kfd-agent-hub-adoption.schema.json": KFD_AGENT_HUB_ADOPTION_SCHEMA,
|
|
1271
1290
|
"schemas/kfd-product-gate-input-v1.schema.json": KFD_PRODUCT_GATE_INPUT_SCHEMA,
|
|
1291
|
+
[DEV_DELIVERY_AUTHORITY_SCHEMA]: readJson(
|
|
1292
|
+
DEV_DELIVERY_AUTHORITY_SCHEMA_SOURCE,
|
|
1293
|
+
),
|
|
1272
1294
|
"badge-endpoint-registry.json": badgeEndpointRegistry,
|
|
1273
1295
|
"publication-registry.json": publicationRegistry,
|
|
1274
1296
|
"buildchain-contract.json": createBuildchainContractWorld({ root, controllerRegistry }),
|
|
@@ -1288,7 +1310,7 @@ export function writeSiteBundle({ check = false } = {}) {
|
|
|
1288
1310
|
const mismatches = [];
|
|
1289
1311
|
for (const [name, value] of Object.entries(files)) {
|
|
1290
1312
|
const filePath = path.join(outputDir, name);
|
|
1291
|
-
const next =
|
|
1313
|
+
const next = siteFileBytes(name, value);
|
|
1292
1314
|
if (check) {
|
|
1293
1315
|
if (existingJson(filePath) !== next) {
|
|
1294
1316
|
mismatches.push(path.relative(root, filePath));
|
|
@@ -1301,11 +1323,11 @@ export function writeSiteBundle({ check = false } = {}) {
|
|
|
1301
1323
|
if (!check) {
|
|
1302
1324
|
for (let iteration = 0; iteration < 5; iteration += 1) {
|
|
1303
1325
|
for (const [name, value] of Object.entries(files)) {
|
|
1304
|
-
|
|
1326
|
+
writeSiteFile(name, value);
|
|
1305
1327
|
}
|
|
1306
1328
|
const nextFiles = buildSiteBundle();
|
|
1307
1329
|
const stable = Object.entries(nextFiles).every(([name, value]) => (
|
|
1308
|
-
existingJson(path.join(outputDir, name)) ===
|
|
1330
|
+
existingJson(path.join(outputDir, name)) === siteFileBytes(name, value)
|
|
1309
1331
|
));
|
|
1310
1332
|
files = nextFiles;
|
|
1311
1333
|
if (stable) {
|
|
@@ -1316,7 +1338,7 @@ export function writeSiteBundle({ check = false } = {}) {
|
|
|
1316
1338
|
}
|
|
1317
1339
|
}
|
|
1318
1340
|
for (const [name, value] of Object.entries(files)) {
|
|
1319
|
-
|
|
1341
|
+
writeSiteFile(name, value);
|
|
1320
1342
|
}
|
|
1321
1343
|
}
|
|
1322
1344
|
return {
|
package/scripts/init-repo.mjs
CHANGED
|
@@ -327,7 +327,9 @@ function workflowArtifactPaths(type) {
|
|
|
327
327
|
}
|
|
328
328
|
|
|
329
329
|
function publicationWorkflowYaml() {
|
|
330
|
-
return
|
|
330
|
+
return `# Commit both .buildchain/contract-lock.json and .buildchain/alpha-contract-lock.json.
|
|
331
|
+
# Persist only @v4 or @v4-alpha; pass temporary train/SHA runtimes through workflow_dispatch.
|
|
332
|
+
name: Build
|
|
331
333
|
|
|
332
334
|
on:
|
|
333
335
|
workflow_dispatch:
|
|
@@ -361,6 +363,8 @@ jobs:
|
|
|
361
363
|
function workflowYaml({ type, runnerPreset, artifactName }) {
|
|
362
364
|
return `# Buildchain v4 lifecycle checkpoints are governed by architecture/v4-platform-stage-checkpoints.json.
|
|
363
365
|
# Do not add undeclared runner-only inputs, outputs, environment, or provider effects.
|
|
366
|
+
# Commit both .buildchain/contract-lock.json and .buildchain/alpha-contract-lock.json.
|
|
367
|
+
# Persist only @v4 or @v4-alpha; pass temporary train/SHA runtimes through workflow_dispatch.
|
|
364
368
|
name: Build
|
|
365
369
|
|
|
366
370
|
on:
|
|
@@ -82,6 +82,10 @@ export function inspectArtifactSigningRequests({
|
|
|
82
82
|
if (seen.has(key))
|
|
83
83
|
throw new Error(`duplicate artifact signing request: ${key}`);
|
|
84
84
|
seen.add(key);
|
|
85
|
+
const {
|
|
86
|
+
entitlementsProfile = "none",
|
|
87
|
+
entitlementsPaths = [],
|
|
88
|
+
} = request.signature;
|
|
85
89
|
const item = {
|
|
86
90
|
id: request.artifact.id,
|
|
87
91
|
slug: safeId(request.artifact.id),
|
|
@@ -104,6 +108,8 @@ export function inspectArtifactSigningRequests({
|
|
|
104
108
|
sourceSha: request.source.sha,
|
|
105
109
|
sourceTreeSha: request.source.treeSha,
|
|
106
110
|
transportFormat: request.artifact.transport?.format || "",
|
|
111
|
+
entitlementsProfile,
|
|
112
|
+
entitlementsPaths: entitlementsPaths.join(","),
|
|
107
113
|
};
|
|
108
114
|
if (request.signature.profile === "detached-signature-v1")
|
|
109
115
|
matrices.detached.push(item);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import crypto from "node:crypto";
|
|
3
3
|
import fs from "node:fs";
|
|
4
|
+
import os from "node:os";
|
|
4
5
|
import path from "node:path";
|
|
5
6
|
import { pathToFileURL } from "node:url";
|
|
6
7
|
import { spawnSyncCommand } from "../packages/core/spawn-command.js";
|
|
@@ -105,6 +106,20 @@ function sealedPackResult() {
|
|
|
105
106
|
};
|
|
106
107
|
}
|
|
107
108
|
|
|
109
|
+
function materializedPackResult({ cwd, registry }) {
|
|
110
|
+
const temporaryRoot = fs.mkdtempSync(path.join(os.tmpdir(), "buildchain-npm-pack-"));
|
|
111
|
+
try {
|
|
112
|
+
const pack = parsePackResult(runNpm({
|
|
113
|
+
cwd,
|
|
114
|
+
args: ["pack", "--json", "--pack-destination", temporaryRoot, `--registry=${registry}`],
|
|
115
|
+
}).stdout);
|
|
116
|
+
return { ...pack, tarballPath: path.join(temporaryRoot, pack.filename), temporaryRoot };
|
|
117
|
+
} catch (error) {
|
|
118
|
+
fs.rmSync(temporaryRoot, { recursive: true, force: true });
|
|
119
|
+
throw error;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
108
123
|
function parseNpmView(stdout) {
|
|
109
124
|
const raw = String(stdout || "").trim();
|
|
110
125
|
if (!raw) {
|
|
@@ -113,8 +128,8 @@ function parseNpmView(stdout) {
|
|
|
113
128
|
const parsed = JSON.parse(raw);
|
|
114
129
|
const dist = parsed?.dist || parsed;
|
|
115
130
|
return {
|
|
116
|
-
integrity: dist?.integrity || "",
|
|
117
|
-
shasum: dist?.shasum || "",
|
|
131
|
+
integrity: dist?.integrity || parsed?.["dist.integrity"] || "",
|
|
132
|
+
shasum: dist?.shasum || parsed?.["dist.shasum"] || "",
|
|
118
133
|
};
|
|
119
134
|
}
|
|
120
135
|
|
|
@@ -188,46 +203,11 @@ export function npmPublishTransaction({
|
|
|
188
203
|
const exactTag = assertPackageVersion({ pkg, expectedVersion });
|
|
189
204
|
const distTag = readEnv("BUILDCHAIN_NPM_DIST_TAG", pkg.version.includes("-") ? "alpha" : "latest");
|
|
190
205
|
|
|
191
|
-
const pack =
|
|
192
|
-
sealedPackResult() ||
|
|
193
|
-
parsePackResult(
|
|
194
|
-
runNpm({
|
|
195
|
-
cwd: resolvedCwd,
|
|
196
|
-
args: ["pack", "--dry-run", "--json", `--registry=${registry}`],
|
|
197
|
-
}).stdout,
|
|
198
|
-
);
|
|
206
|
+
const pack = sealedPackResult() || materializedPackResult({ cwd: resolvedCwd, registry });
|
|
199
207
|
const digest = artifactDigest(pack);
|
|
200
208
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
: publishedDigest({
|
|
204
|
-
cwd: resolvedCwd,
|
|
205
|
-
name: pkg.name,
|
|
206
|
-
version: pkg.version,
|
|
207
|
-
registry,
|
|
208
|
-
});
|
|
209
|
-
let publishAction = "already-published";
|
|
210
|
-
if (existingDigest) {
|
|
211
|
-
if (existingDigest !== digest) {
|
|
212
|
-
throw new Error(`artifact digest mismatch: npm:${pkg.name}@${pkg.version}`);
|
|
213
|
-
}
|
|
214
|
-
} else if (dryRunPublish) {
|
|
215
|
-
publishAction = "dry-run";
|
|
216
|
-
} else {
|
|
217
|
-
runNpm({
|
|
218
|
-
cwd: resolvedCwd,
|
|
219
|
-
args: [
|
|
220
|
-
"publish",
|
|
221
|
-
...(pack.tarballPath ? [pack.tarballPath] : []),
|
|
222
|
-
"--access",
|
|
223
|
-
access,
|
|
224
|
-
"--tag",
|
|
225
|
-
distTag,
|
|
226
|
-
`--registry=${registry}`,
|
|
227
|
-
],
|
|
228
|
-
});
|
|
229
|
-
publishAction = "published";
|
|
230
|
-
const registryDigest = skipRegistryLookup
|
|
209
|
+
try {
|
|
210
|
+
const existingDigest = skipRegistryLookup
|
|
231
211
|
? undefined
|
|
232
212
|
: publishedDigest({
|
|
233
213
|
cwd: resolvedCwd,
|
|
@@ -235,60 +215,92 @@ export function npmPublishTransaction({
|
|
|
235
215
|
version: pkg.version,
|
|
236
216
|
registry,
|
|
237
217
|
});
|
|
238
|
-
|
|
239
|
-
|
|
218
|
+
let publishAction = "already-published";
|
|
219
|
+
if (existingDigest) {
|
|
220
|
+
if (existingDigest !== digest) {
|
|
221
|
+
throw new Error(`artifact digest mismatch: npm:${pkg.name}@${pkg.version}`);
|
|
222
|
+
}
|
|
223
|
+
} else if (dryRunPublish) {
|
|
224
|
+
publishAction = "dry-run";
|
|
225
|
+
} else {
|
|
226
|
+
runNpm({
|
|
227
|
+
cwd: resolvedCwd,
|
|
228
|
+
args: [
|
|
229
|
+
"publish",
|
|
230
|
+
...(pack.tarballPath ? [pack.tarballPath] : []),
|
|
231
|
+
"--access",
|
|
232
|
+
access,
|
|
233
|
+
"--tag",
|
|
234
|
+
distTag,
|
|
235
|
+
`--registry=${registry}`,
|
|
236
|
+
],
|
|
237
|
+
});
|
|
238
|
+
publishAction = "published";
|
|
239
|
+
const registryDigest = skipRegistryLookup
|
|
240
|
+
? undefined
|
|
241
|
+
: publishedDigest({
|
|
242
|
+
cwd: resolvedCwd,
|
|
243
|
+
name: pkg.name,
|
|
244
|
+
version: pkg.version,
|
|
245
|
+
registry,
|
|
246
|
+
});
|
|
247
|
+
if (registryDigest && registryDigest !== digest) {
|
|
248
|
+
throw new Error(`artifact digest mismatch: npm:${pkg.name}@${pkg.version}`);
|
|
249
|
+
}
|
|
240
250
|
}
|
|
241
|
-
}
|
|
242
251
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
version: pkg.version,
|
|
271
|
-
"exact-tag": exactTag,
|
|
272
|
-
"dist-tag": distTag,
|
|
273
|
-
"artifact-digest": digest,
|
|
274
|
-
"publish-action": publishAction,
|
|
275
|
-
"publish-evidence": resolvedEvidencePath,
|
|
276
|
-
});
|
|
277
|
-
return {
|
|
278
|
-
schemaVersion: 1,
|
|
279
|
-
package: {
|
|
280
|
-
name: pkg.name,
|
|
252
|
+
const evidencePath = readEnv("BUILDCHAIN_PUBLISH_EVIDENCE");
|
|
253
|
+
if (!evidencePath) {
|
|
254
|
+
throw new Error("BUILDCHAIN_PUBLISH_EVIDENCE is required");
|
|
255
|
+
}
|
|
256
|
+
const evidence = {
|
|
257
|
+
schema: 1,
|
|
258
|
+
version: expectedVersion || pkg.version,
|
|
259
|
+
channel: readEnv("BUILDCHAIN_CHANNEL"),
|
|
260
|
+
source_sha: readEnv("BUILDCHAIN_SOURCE_SHA"),
|
|
261
|
+
release_sha: readEnv("BUILDCHAIN_RELEASE_SHA"),
|
|
262
|
+
target_ref: readEnv("BUILDCHAIN_TARGET_REF"),
|
|
263
|
+
release_material_sha: readEnv("BUILDCHAIN_RELEASE_MATERIAL_SHA", readEnv("BUILDCHAIN_RELEASE_SHA")),
|
|
264
|
+
publish_tooling_sha: readEnv("BUILDCHAIN_PUBLISH_TOOLING_SHA", readEnv("BUILDCHAIN_RELEASE_SHA")),
|
|
265
|
+
artifacts: [{
|
|
266
|
+
group: "node",
|
|
267
|
+
kind: "npm",
|
|
268
|
+
name: pkg.name,
|
|
269
|
+
ref: pkg.version,
|
|
270
|
+
digest,
|
|
271
|
+
}],
|
|
272
|
+
};
|
|
273
|
+
const resolvedEvidencePath = writeEvidence({
|
|
274
|
+
cwd: resolvedCwd,
|
|
275
|
+
evidencePath,
|
|
276
|
+
evidence,
|
|
277
|
+
});
|
|
278
|
+
writeGitHubOutputs({
|
|
281
279
|
version: pkg.version,
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
280
|
+
"exact-tag": exactTag,
|
|
281
|
+
"dist-tag": distTag,
|
|
282
|
+
"artifact-digest": digest,
|
|
283
|
+
"publish-action": publishAction,
|
|
284
|
+
"publish-evidence": resolvedEvidencePath,
|
|
285
|
+
});
|
|
286
|
+
return {
|
|
287
|
+
schemaVersion: 1,
|
|
288
|
+
package: {
|
|
289
|
+
name: pkg.name,
|
|
290
|
+
version: pkg.version,
|
|
291
|
+
},
|
|
292
|
+
exactTag,
|
|
293
|
+
distTag,
|
|
294
|
+
registry,
|
|
295
|
+
publishAction,
|
|
296
|
+
pack: { ...pack, temporaryRoot: undefined },
|
|
297
|
+
sealedBundleRoot: readEnv("BUILDCHAIN_SEALED_BUNDLE_ROOT"),
|
|
298
|
+
evidencePath: resolvedEvidencePath,
|
|
299
|
+
evidence,
|
|
300
|
+
};
|
|
301
|
+
} finally {
|
|
302
|
+
if (pack.temporaryRoot) fs.rmSync(pack.temporaryRoot, { recursive: true, force: true });
|
|
303
|
+
}
|
|
292
304
|
}
|
|
293
305
|
|
|
294
306
|
function usage() {
|
|
@@ -8,12 +8,11 @@ import { pathToFileURL } from "node:url";
|
|
|
8
8
|
import { writeGitHubOutputs } from "./build-contract-core.mjs";
|
|
9
9
|
import {
|
|
10
10
|
generatePublishRequiredArtifacts,
|
|
11
|
-
readNpmPackageArtifact,
|
|
12
|
-
selectReleaseCandidateArtifacts,
|
|
13
|
-
} from "./release-candidate-resolver.mjs";
|
|
14
|
-
import {
|
|
15
11
|
githubDownload,
|
|
16
12
|
githubJson,
|
|
13
|
+
readNpmPackageArtifact,
|
|
14
|
+
selectPayloadArtifacts,
|
|
15
|
+
selectReleaseCandidateArtifacts,
|
|
17
16
|
unzip,
|
|
18
17
|
verifyArtifactArchive,
|
|
19
18
|
} from "./release-candidate-resolver.mjs";
|
|
@@ -156,7 +155,7 @@ async function downloadArtifact({ artifact, repoInfo, apiUrl, token, archiveDir,
|
|
|
156
155
|
};
|
|
157
156
|
}
|
|
158
157
|
|
|
159
|
-
function candidateArtifactNames({ passport, selected, artifacts, artifactPatterns }) {
|
|
158
|
+
export function candidateArtifactNames({ passport, selected, artifacts, artifactPatterns }) {
|
|
160
159
|
const names = new Set([selected.passport.name, selected.summary.name]);
|
|
161
160
|
for (const reference of passport.controllerReceipts || []) {
|
|
162
161
|
if (!reference.artifact) throw new Error(`Passport controller receipt ${reference.controllerId} has no artifact identity`);
|
|
@@ -171,11 +170,9 @@ function candidateArtifactNames({ passport, selected, artifacts, artifactPattern
|
|
|
171
170
|
for (const artifact of artifacts) {
|
|
172
171
|
if (manifestPattern.test(String(artifact.name || ""))) names.add(artifact.name);
|
|
173
172
|
}
|
|
174
|
-
const
|
|
175
|
-
for (const
|
|
176
|
-
|
|
177
|
-
}
|
|
178
|
-
return names;
|
|
173
|
+
const publicationNames = new Set(selectPayloadArtifacts({ artifacts, artifactName: selected.prefix, sourceSha: selected.sourceSha, patterns: artifactPatterns }).map((artifact) => artifact.name));
|
|
174
|
+
for (const name of publicationNames) names.add(name);
|
|
175
|
+
return { names, publicationNames };
|
|
179
176
|
}
|
|
180
177
|
|
|
181
178
|
export function normalizePlatformManifests(downloads, passport) {
|
|
@@ -352,7 +349,7 @@ async function recoverCandidateEvidence({
|
|
|
352
349
|
for (const artifact of [selected.passport, selected.summary]) initialDownloads.push(await downloadArtifact({ artifact, repoInfo, apiUrl, token, archiveDir, bundleRoot, fetchImpl }));
|
|
353
350
|
const passport = readOnlyJson(initialDownloads[0].files.filter((file) => path.basename(file.path) === "release-candidate-passport.json"), "release-candidate-passport.json");
|
|
354
351
|
const buildSummary = readOnlyJson(initialDownloads[1].files.filter((file) => path.basename(file.path) === "build-summary.json"), "build-summary.json");
|
|
355
|
-
const requiredNames = candidateArtifactNames({ passport, selected, artifacts, artifactPatterns });
|
|
352
|
+
const { names: requiredNames, publicationNames } = candidateArtifactNames({ passport, selected, artifacts, artifactPatterns });
|
|
356
353
|
const chosen = artifacts.filter((artifact) => requiredNames.has(artifact.name));
|
|
357
354
|
if (chosen.length !== requiredNames.size) {
|
|
358
355
|
const found = new Set(chosen.map((artifact) => artifact.name));
|
|
@@ -363,7 +360,7 @@ async function recoverCandidateEvidence({
|
|
|
363
360
|
for (const artifact of chosen.filter((entry) => ![selected.passport.id, selected.summary.id].includes(entry.id))) downloads.push(await downloadArtifact({ artifact, repoInfo, apiUrl, token, archiveDir, bundleRoot, fetchImpl }));
|
|
364
361
|
return {
|
|
365
362
|
run, workflow, selected, resolvedOutput, bundleRoot, initialDownloads,
|
|
366
|
-
passport, buildSummary, chosen, downloads,
|
|
363
|
+
passport, buildSummary, chosen, downloads, publicationNames,
|
|
367
364
|
};
|
|
368
365
|
}
|
|
369
366
|
|
|
@@ -396,7 +393,7 @@ export async function resumeFromCandidateRun({
|
|
|
396
393
|
try {
|
|
397
394
|
const {
|
|
398
395
|
run, workflow, selected, resolvedOutput, bundleRoot, initialDownloads,
|
|
399
|
-
passport, buildSummary, chosen, downloads,
|
|
396
|
+
passport, buildSummary, chosen, downloads, publicationNames,
|
|
400
397
|
} = await recoverCandidateEvidence({
|
|
401
398
|
repoInfo, runId, artifactName, artifactPatterns, requiredArtifactCount,
|
|
402
399
|
outputDir, apiUrl, token, fetchImpl, archiveDir,
|
|
@@ -412,7 +409,7 @@ export async function resumeFromCandidateRun({
|
|
|
412
409
|
const controllerReceipts = normalizeControllerReceipts(downloads, passport);
|
|
413
410
|
const productPayloadManifests = normalizeProductPayloadManifests(downloads);
|
|
414
411
|
const publication = createRecoveredPublication({
|
|
415
|
-
downloads,
|
|
412
|
+
downloads: downloads.filter(({ artifact }) => publicationNames.has(artifact.name)),
|
|
416
413
|
bundleRoot,
|
|
417
414
|
repository: repoInfo.fullName,
|
|
418
415
|
passport,
|
|
@@ -381,6 +381,12 @@ export function sealArtifactSigningRequests({
|
|
|
381
381
|
signature: {
|
|
382
382
|
profile: declaration.profile,
|
|
383
383
|
required: declaration.required,
|
|
384
|
+
...(declaration.entitlementsProfile !== "none"
|
|
385
|
+
? {
|
|
386
|
+
entitlementsProfile: declaration.entitlementsProfile,
|
|
387
|
+
entitlementsPaths: declaration.entitlementsPaths,
|
|
388
|
+
}
|
|
389
|
+
: {}),
|
|
384
390
|
},
|
|
385
391
|
});
|
|
386
392
|
const check = validateArtifactSigningRequest(request);
|
|
@@ -92,6 +92,17 @@ export function cliCommandMeta(id) {
|
|
|
92
92
|
"kfd-upstream-roles": { group: "kfd-trust", purpose: "List Buildchain-managed KFD upstream role values and inference policy." },
|
|
93
93
|
lifecycle: { group: "reusable-build", purpose: "Run configured lifecycle commands and write deterministic artifact manifests." },
|
|
94
94
|
dev: { group: "governance-versioning", purpose: "Inspect protected development-channel governance command families." },
|
|
95
|
+
"dev-authority-admit-merge-group": { group: "governance-versioning", purpose: "Verify that one exact candidate holds the exclusive Landing Warrant before merge_group admission." },
|
|
96
|
+
"dev-authority-complete-qualification": { group: "governance-versioning", purpose: "Bind qualification evidence and release one bounded Qualification Lease without granting landing authority." },
|
|
97
|
+
"dev-authority-heartbeat-landing": { group: "governance-versioning", purpose: "Extend the exact fenced Landing Warrant while final landing work remains live." },
|
|
98
|
+
"dev-authority-heartbeat-qualification": { group: "governance-versioning", purpose: "Extend one exact fenced Qualification Lease while qualification work remains live." },
|
|
99
|
+
"dev-authority-lease-landing": { group: "governance-versioning", purpose: "Issue or retain the single exclusive Landing Warrant for a qualified candidate." },
|
|
100
|
+
"dev-authority-lease-qualification": { group: "governance-versioning", purpose: "Issue one qualification-only lease within the configured bounded lane count." },
|
|
101
|
+
"dev-authority-migrate": { group: "governance-versioning", purpose: "Migrate one exact v1 Warrant state into v2 without rewriting candidate or fencing evidence." },
|
|
102
|
+
"dev-authority-observe": { group: "governance-versioning", purpose: "Read bounded Qualification Leases and the exclusive Landing Warrant without mutating authority." },
|
|
103
|
+
"dev-authority-recover": { group: "governance-versioning", purpose: "Recover expired qualification or Landing authority and emit one rooted wake instruction." },
|
|
104
|
+
"dev-authority-settle": { group: "governance-versioning", purpose: "Settle terminal candidate evidence idempotently and release held qualification or Landing authority immediately." },
|
|
105
|
+
"dev-authority-submit": { group: "governance-versioning", purpose: "Submit an exact candidate to the opt-in bounded-qualification authority state." },
|
|
95
106
|
"dev-proof-classify": { group: "governance-versioning", purpose: "Classify source-qualified candidate changes against a current integration base." },
|
|
96
107
|
"dev-proof-integration": { group: "governance-versioning", purpose: "Seal final exact integration delivery proof for a warranted candidate." },
|
|
97
108
|
"dev-proof-replay": { group: "governance-versioning", purpose: "Replay source qualification against a Project Cut without rewriting candidate source." },
|
|
@@ -174,6 +185,7 @@ export function nodeApiMeta(exportName) {
|
|
|
174
185
|
"./build-facts": { group: "observability-diagnostics", summary: "Git source, version, module output, product artifact, and legacy Kungfu build fact APIs." },
|
|
175
186
|
"./candidate-timeline": { group: "observability-diagnostics", summary: "Source-bound candidate event normalization, per-attempt critical-path-safe aggregation, and compact reporting APIs." },
|
|
176
187
|
"./channel-candidate": { group: "governance-versioning", summary: "Exact-source channel candidate decisions, same-SHA workflow evidence validation, and deterministic source-lock reference APIs." },
|
|
188
|
+
"./dev-delivery-authority": { group: "governance-versioning", summary: "Opt-in bounded Qualification Lease, exclusive Landing Warrant, provider-attempt admission and heartbeat readback, terminal sealing, and expired-Landing verification APIs." },
|
|
177
189
|
"./dev-delivery-warrant": { group: "governance-versioning", summary: "Durable fair Dev Delivery Warrant queue, fenced lease, and split source and integration proof APIs." },
|
|
178
190
|
"./cache-evidence": { group: "observability-diagnostics", summary: "Content-addressed cache operation receipts and source/platform-bound evidence-set verification APIs." },
|
|
179
191
|
"./diagnostics": { group: "observability-diagnostics", summary: "Native diagnostics collection, summarization, cache, compiler, and process-sampler APIs." },
|
|
@@ -201,6 +213,8 @@ export function nodeApiMeta(exportName) {
|
|
|
201
213
|
"./kfd-agent-hub": { group: "kfd-trust", summary: "Declarative Agent Hub adapter inspection, fixed-suite execution, exact KFD cut locking, and agent explanation APIs." },
|
|
202
214
|
"./release-passport-contract": { group: "release-passport-trust", summary: "Standalone release passport JSON Schema, ownership/check manifest, and structural validation APIs." },
|
|
203
215
|
"./release-candidate": { group: "reusable-build", summary: "PR-stage release-candidate artifact, passport, and promote-only resolver APIs." },
|
|
216
|
+
"./v4-floating-consumer-policy": { group: "governance-versioning", summary: "Semantic floating-selector admission, dual-lock receipt, and independent v4 consumer certification APIs." },
|
|
217
|
+
"./v4-runtime-ref-resume-authority": { group: "release-passport-trust", summary: "Transient exact-runtime authorization, persisted-selector rejection, fresh-attempt Stage Capsule reuse, and A+B Passport lineage APIs." },
|
|
204
218
|
"./release-candidate-recovery": { group: "release-passport-trust", summary: "Fail-closed verification and immutable receipts for reusing a successful sealed candidate run without rebuilding product payloads." },
|
|
205
219
|
"./release-train": { group: "governance-versioning", summary: "Frozen Release Cut identity, rooted Release Train transitions, Dev observations, supersession, replay, and legacy read compatibility APIs." },
|
|
206
220
|
"./stable-candidate-ledger": { group: "governance-versioning", summary: "Immutable alpha candidate ledger, qualification, revocation, selection, and exact stable source-lock APIs." },
|