@kungfu-tech/buildchain 3.0.8 → 3.0.9-alpha.1
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/actions/promote-buildchain-ref/README.md +8 -7
- package/bin/buildchain.mjs +34 -33
- package/bin/internal/trust-release-release-handlers.mjs +5 -0
- package/contracts/fixtures/kfd-adopter-release-v1/kfd-4-perspective.json +16 -0
- package/contracts/fixtures/kfd-adopter-release-v1/kfd-4-replay.json +57 -0
- package/contracts/release-cut-v1.schema.json +1 -0
- package/contracts/release-train-transition-v1.schema.json +1 -0
- package/dist/site/agent-index.json +0 -1
- package/dist/site/artifact-schemas.json +0 -2
- package/dist/site/badge-endpoint-registry.json +9 -9
- package/dist/site/badges/v1/kfd-8/aligned.json +1 -1
- package/dist/site/badges/v1/kfd-8/declared.json +1 -1
- package/dist/site/badges/v1/kfd-8/downgraded.json +1 -1
- package/dist/site/badges/v1/kfd-8/draft.json +1 -1
- package/dist/site/badges/v1/kfd-8/failed.json +1 -1
- package/dist/site/badges/v1/kfd-8/missing.json +1 -1
- package/dist/site/badges/v1/kfd-8/passed.json +1 -1
- package/dist/site/badges/v1/kfd-8/planned.json +1 -1
- package/dist/site/buildchain-contract.json +38 -34
- package/dist/site/buildchain-site.json +59 -39
- package/dist/site/capability-registry.json +1 -1
- package/dist/site/cli-registry.json +8 -7
- package/dist/site/controller-registry.json +13 -5
- package/dist/site/kfd-claims.json +35 -8
- package/dist/site/kfd-upstream-aggregate.json +10 -10
- package/dist/site/manual-registry.json +9 -9
- package/dist/site/node-api-registry.json +1143 -320
- package/dist/site/page-registry.json +46 -26
- package/dist/site/public-surface-audit.json +19 -9
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/release-passport-check-manifest.json +33 -5
- package/dist/site/release-provenance.json +2 -1
- package/dist/site/schemas/release-passport-v1.schema.json +3 -0
- package/dist/site/site-manifest.json +13 -13
- package/dist/site/workflow-registry.json +19 -9
- package/docs/aws-us-elastic-runner-burst-plane.md +15 -3
- package/docs/cli-reference.md +6 -6
- package/docs/cli.md +2 -3
- package/docs/dev-alpha-candidate-patrol.md +45 -20
- package/docs/dev-delivery-warrant.md +12 -2
- package/docs/kfd-support.md +7 -7
- package/docs/node-api-reference.md +295 -246
- package/docs/release-passport.md +25 -12
- package/docs/release-train.md +54 -4
- package/docs/reusable-build-surface.md +26 -9
- package/docs/runtime-train-validation.md +6 -0
- package/docs/versioning.md +3 -2
- package/package.json +4 -3
- package/packages/core/artifact-verification-envelope.js +114 -0
- package/packages/core/buildchain-channel-identity.js +119 -0
- package/packages/core/buildchain-compatibility-proof.js +32 -0
- package/packages/core/buildchain-contract.js +7 -0
- package/packages/core/controller-evidence.js +2 -1
- package/packages/core/dev-alpha-active-release-train.js +460 -0
- package/packages/core/dev-alpha-candidate-selection.js +181 -0
- package/packages/core/dev-delivery-warrant.js +15 -4
- package/packages/core/index.js +4 -5
- package/packages/core/kfd-adopter-manifest.js +390 -0
- package/packages/core/kfd-product-gates.js +0 -300
- package/packages/core/release-blocker-priority.js +192 -0
- package/packages/core/release-passport-contract.js +219 -6
- package/packages/core/release-passport.js +139 -242
- package/packages/core/release-train.js +220 -0
- package/scripts/aws-macos-jit-controller-core.mjs +76 -0
- package/scripts/aws-macos-jit-controller.mjs +29 -0
- package/scripts/aws-macos-jit-source-rebind.mjs +503 -0
- package/scripts/buildchain-channel-router.mjs +18 -2
- package/scripts/buildchain-cli-help.mjs +4 -2
- package/scripts/buildchain-contract-lock.mjs +11 -1
- package/scripts/check-inventory.mjs +4 -4
- package/scripts/dev-alpha-candidate-patrol.mjs +196 -201
- package/scripts/generate-buildchain-kfd-witnesses.mjs +88 -94
- package/scripts/generate-channel-build-workflow.mjs +78 -31
- package/scripts/generate-site-bundle.mjs +1 -8
- package/scripts/promotion-channel-router.mjs +5 -3
- package/scripts/release-train-self-dogfood.mjs +579 -0
- package/scripts/runtime-ref-core.mjs +4 -17
- package/scripts/site-capability-metadata.mjs +3 -1
- package/dist/site/schemas/kfd-support-projection-v1.schema.json +0 -106
|
@@ -1,8 +1,18 @@
|
|
|
1
|
+
import path from "node:path";
|
|
1
2
|
import kfdStandards from "@kungfu-tech/kfd/standards.json" with { type: "json" };
|
|
2
3
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
createKfdAdopterManifestGate,
|
|
5
|
+
createKfdLegacySupportMatrixProjection,
|
|
6
|
+
validateKfdLegacySupportMatrixProjection,
|
|
7
|
+
} from "./kfd-adopter-manifest.js";
|
|
8
|
+
import {
|
|
9
|
+
createKfdAdopterReleaseBinding,
|
|
10
|
+
installedKfdPackageArtifactRoot,
|
|
11
|
+
validateKfdAdopterReleaseBinding,
|
|
12
|
+
} from "./artifact-verification-envelope.js";
|
|
13
|
+
|
|
14
|
+
export const RELEASE_PASSPORT_CONTRACT = "kungfu-buildchain-release-passport";
|
|
15
|
+
export const RELEASE_CHECK_REPORT_CONTRACT = "kungfu-buildchain-release-check-report";
|
|
6
16
|
|
|
7
17
|
export const RELEASE_PASSPORT_SCHEMA_ID =
|
|
8
18
|
"https://buildchain.libkungfu.dev/schemas/release-passport-v1.schema.json";
|
|
@@ -100,6 +110,7 @@ export const RELEASE_PASSPORT_SCHEMA = {
|
|
|
100
110
|
"kfd-1": OBJECT,
|
|
101
111
|
"kfd-2": OBJECT,
|
|
102
112
|
"kfd-3": OBJECT,
|
|
113
|
+
kfdAdopter: OBJECT,
|
|
103
114
|
kfdSupport: OBJECT,
|
|
104
115
|
},
|
|
105
116
|
additionalProperties: true,
|
|
@@ -123,6 +134,7 @@ const BUILDCHAIN_AGGREGATION_FIELDS = [
|
|
|
123
134
|
"platformArtifactManifests",
|
|
124
135
|
"distTagPromotion",
|
|
125
136
|
"controllerReceipts",
|
|
137
|
+
"kfdAdopter",
|
|
126
138
|
"kfdSupport",
|
|
127
139
|
"githubArtifactAttestations",
|
|
128
140
|
"artifacts",
|
|
@@ -163,11 +175,12 @@ export function createReleasePassportCheckManifest({ standards = kfdStandards }
|
|
|
163
175
|
result: "check-report.json",
|
|
164
176
|
},
|
|
165
177
|
kfdSupportProjection: {
|
|
166
|
-
|
|
167
|
-
|
|
178
|
+
authorityContract: "kfd.adopter-conformance-manifest/v1",
|
|
179
|
+
gateContract: "kungfu-buildchain-kfd-adopter-manifest-gate",
|
|
180
|
+
bindingContract: "kungfu-buildchain-kfd-adopter-release-binding",
|
|
168
181
|
evidence: "kfd-support.json",
|
|
169
182
|
rule:
|
|
170
|
-
"The
|
|
183
|
+
"The standard adopter manifest is the sole declaration authority; the legacy support matrix is an exact derived projection only.",
|
|
171
184
|
},
|
|
172
185
|
},
|
|
173
186
|
ownership: {
|
|
@@ -199,6 +212,14 @@ export function createReleasePassportCheckManifest({ standards = kfdStandards }
|
|
|
199
212
|
when: "kfdSupport is present",
|
|
200
213
|
pointer: "evidence.kfdSupport",
|
|
201
214
|
},
|
|
215
|
+
{
|
|
216
|
+
when: "kfdAdopter is present",
|
|
217
|
+
pointer: "evidence.kfdAdopterManifest",
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
when: "kfdAdopter is present",
|
|
221
|
+
pointer: "evidence.kfdAdopterGate",
|
|
222
|
+
},
|
|
202
223
|
],
|
|
203
224
|
rule:
|
|
204
225
|
"The normative checker resolves every declared sibling relative to the passport and fails closed on missing required evidence, digest drift, or semantic mismatch.",
|
|
@@ -264,3 +285,195 @@ export function validateReleasePassportSchema(passport) {
|
|
|
264
285
|
issues,
|
|
265
286
|
};
|
|
266
287
|
}
|
|
288
|
+
|
|
289
|
+
function passportStableJson(value) {
|
|
290
|
+
if (Array.isArray(value)) return `[${value.map(passportStableJson).join(",")}]`;
|
|
291
|
+
if (value && typeof value === "object") {
|
|
292
|
+
return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${passportStableJson(value[key])}`).join(",")}}`;
|
|
293
|
+
}
|
|
294
|
+
return JSON.stringify(value);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
function passportOptional(value) {
|
|
298
|
+
return value === undefined || value === null ? "" : String(value);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
export function defaultReleaseProductMechanism({ repository = "", productName = "Buildchain" } = {}) {
|
|
302
|
+
return {
|
|
303
|
+
schemaVersion: 1,
|
|
304
|
+
contract: "kungfu-buildchain-product-mechanism",
|
|
305
|
+
product: { name: productName, repository, northStar: "GitHub-native release passport protocol for binary and multi-artifact products." },
|
|
306
|
+
trustModel: {
|
|
307
|
+
executionSubstrate: "github-actions",
|
|
308
|
+
releaseAuthority: "protected Buildchain channel refs, exact tags, and release passport evidence",
|
|
309
|
+
runnerRequirement: "runner facts are recorded, but the protocol is runner-agnostic",
|
|
310
|
+
},
|
|
311
|
+
compatibility: {
|
|
312
|
+
promise: "release passport schemas are welded surfaces; additive fields are allowed, breaking semantic changes require a new major line",
|
|
313
|
+
kfd: "KFD-1",
|
|
314
|
+
},
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
export function defaultReleaseImpact({ tag = "", line = "", decision = "unknown" } = {}) {
|
|
319
|
+
const normalized = String(decision).toLowerCase();
|
|
320
|
+
const final = ["unknown", "patch", "minor", "major"].includes(normalized) ? normalized : String(decision);
|
|
321
|
+
return {
|
|
322
|
+
schemaVersion: 1,
|
|
323
|
+
contract: "kungfu-buildchain-impact",
|
|
324
|
+
release: { tag, line },
|
|
325
|
+
versionImpact: { final, source: "default", rationale: "No surface impact classification was supplied." },
|
|
326
|
+
surfaceImpacts: [],
|
|
327
|
+
classification: final,
|
|
328
|
+
breaking: final === "major",
|
|
329
|
+
security: false,
|
|
330
|
+
migrationRequired: final === "major",
|
|
331
|
+
summary: "No release impact summary was supplied.",
|
|
332
|
+
recovery: { rollback: "Use the previous exact release tag or previous floating channel ref.", block: "Fail closed if release passport verification fails." },
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
export function defaultReleaseAgentIndex({ tag = "", passportPath = "buildchain.release.json" } = {}) {
|
|
337
|
+
return {
|
|
338
|
+
schemaVersion: 1,
|
|
339
|
+
contract: "kungfu-buildchain-agent-index",
|
|
340
|
+
release: { tag },
|
|
341
|
+
entrypoints: [
|
|
342
|
+
{ id: "release-passport", kind: "json", path: passportPath, description: "Read this first to verify release completeness, artifacts, impact, and recovery pointers." },
|
|
343
|
+
{ id: "llms", kind: "text", path: "llms.txt", description: "Short agent-readable release instructions." },
|
|
344
|
+
],
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
export function defaultReleaseLlmsText({ tag = "", passportPath = "buildchain.release.json" } = {}) {
|
|
349
|
+
return [
|
|
350
|
+
"# Buildchain Release Passport",
|
|
351
|
+
"",
|
|
352
|
+
`Release: ${tag || "unknown"}`,
|
|
353
|
+
"",
|
|
354
|
+
`Start with ${passportPath}. Verify artifact-evidence.json before installing binaries.`,
|
|
355
|
+
"If verification fails, do not install or promote this release.",
|
|
356
|
+
].join("\n");
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
export function buildReleaseArtifactEvidence({ normalizedAssets = [], repository = "", tag = "", sourceSha = "", workflow = {}, kfdAdopter } = {}) {
|
|
360
|
+
return {
|
|
361
|
+
schemaVersion: 1,
|
|
362
|
+
contract: "kungfu-buildchain-artifact-evidence",
|
|
363
|
+
repository: passportOptional(repository),
|
|
364
|
+
release: { tag: passportOptional(tag), sourceSha: passportOptional(sourceSha) },
|
|
365
|
+
generatedAt: new Date().toISOString(),
|
|
366
|
+
runner: {
|
|
367
|
+
kind: passportOptional(workflow.runnerKind || workflow.runner?.kind || ""),
|
|
368
|
+
os: passportOptional(workflow.runnerOs || workflow.runner?.os || ""),
|
|
369
|
+
arch: passportOptional(workflow.runnerArch || workflow.runner?.arch || ""),
|
|
370
|
+
labels: Array.isArray(workflow.runnerLabels) ? workflow.runnerLabels : [],
|
|
371
|
+
image: passportOptional(workflow.runnerImage || workflow.runner?.image || ""),
|
|
372
|
+
},
|
|
373
|
+
workflow: {
|
|
374
|
+
name: passportOptional(workflow.name),
|
|
375
|
+
runId: passportOptional(workflow.runId),
|
|
376
|
+
runAttempt: passportOptional(workflow.runAttempt),
|
|
377
|
+
url: passportOptional(workflow.url),
|
|
378
|
+
},
|
|
379
|
+
artifacts: normalizedAssets.map((asset) => ({
|
|
380
|
+
name: asset.name, kind: asset.kind, platform: asset.platform, size: asset.size,
|
|
381
|
+
sha256: asset.sha256, url: asset.url, githubAssetId: asset.githubAssetId,
|
|
382
|
+
attestation: passportOptional(asset.attestation || ""),
|
|
383
|
+
})),
|
|
384
|
+
...(kfdAdopter ? { kfdAdopter: structuredClone(kfdAdopter) } : {}),
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
export function prepareReleasePassportKfdSections({ kfd1, kfd2Claims, kfd3, kfdAdopter, kfdSupport, kfd1DefaultKey, createKfd2, evidencePaths = {} } = {}) {
|
|
389
|
+
const one = kfd1?.passportSection ? kfd1 : undefined;
|
|
390
|
+
const three = kfd3?.passportSection ? kfd3 : undefined;
|
|
391
|
+
const adopter = kfdAdopter ? structuredClone(kfdAdopter) : undefined;
|
|
392
|
+
const support = kfdSupport ? structuredClone(kfdSupport) : undefined;
|
|
393
|
+
const two = createKfd2({ explicitClaims: kfd2Claims, kfd1Section: one?.passportSection, kfd3Section: three?.passportSection });
|
|
394
|
+
return {
|
|
395
|
+
sectionEntries: [
|
|
396
|
+
[one?.key || kfd1DefaultKey, one?.passportSection], ["kfd-2", two],
|
|
397
|
+
[three?.key || "kfd-3", three?.passportSection], ["kfdAdopter", adopter], ["kfdSupport", support],
|
|
398
|
+
],
|
|
399
|
+
evidence: {
|
|
400
|
+
kfd1: one ? `${one.key || kfd1DefaultKey}` : "", kfd2: two ? "kfd-2" : "", kfd3: three ? `${three.key || "kfd-3"}` : "",
|
|
401
|
+
kfdAdopterManifest: adopter ? evidencePaths.manifest || "kfd-adopter-manifest.json" : "",
|
|
402
|
+
kfdAdopterGate: adopter ? evidencePaths.gate || "kfd-adopter-manifest-gate.json" : "",
|
|
403
|
+
kfdSupport: support ? evidencePaths.support || "kfd-support.json" : "",
|
|
404
|
+
},
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
export function collectKfdAdopterReleaseEvidence({ manifest, gateResults = [], comparisonMatrix, sourceSha = "", checkedAt } = {}) {
|
|
409
|
+
if (!manifest) {
|
|
410
|
+
if (comparisonMatrix || gateResults.length > 0) {
|
|
411
|
+
throw new Error("KFD support and product-gate inputs require --kfd-adopter-manifest-json; --kfd-support-matrix-json is comparison-only");
|
|
412
|
+
}
|
|
413
|
+
return {};
|
|
414
|
+
}
|
|
415
|
+
const manifestGate = createKfdAdopterManifestGate({
|
|
416
|
+
manifest, packageArtifactRoot: installedKfdPackageArtifactRoot(), gateResults,
|
|
417
|
+
expectedSourceSha: sourceSha, checkedAt,
|
|
418
|
+
});
|
|
419
|
+
const legacyProjection = createKfdLegacySupportMatrixProjection({ manifest, manifestGate });
|
|
420
|
+
if (comparisonMatrix) {
|
|
421
|
+
const comparison = validateKfdLegacySupportMatrixProjection(comparisonMatrix, { manifest, manifestGate });
|
|
422
|
+
if (!comparison.valid) {
|
|
423
|
+
throw new Error(`legacy KFD support matrix drifted from the standard adopter manifest: ${JSON.stringify(comparison.issues)}`);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
return {
|
|
427
|
+
manifest, manifestGate, legacyProjection,
|
|
428
|
+
binding: createKfdAdopterReleaseBinding({ manifest, manifestGate, legacyProjection, expectedSourceSha: sourceSha }),
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
export function validateKfdAdopterReleaseEvidence({ binding, artifactBinding, manifest, manifestGate, legacyProjection, passportLegacyProjection, expectedSourceSha = "" } = {}) {
|
|
433
|
+
if (!binding) {
|
|
434
|
+
return passportLegacyProjection
|
|
435
|
+
? [{ code: "kfdSupport.authority", message: "legacy KFD support projection requires the standard adopter manifest binding" }]
|
|
436
|
+
: [];
|
|
437
|
+
}
|
|
438
|
+
const issues = validateKfdAdopterReleaseBinding(binding, {
|
|
439
|
+
manifest, manifestGate, legacyProjection, expectedSourceSha,
|
|
440
|
+
}).issues.map((entry) => ({ code: `kfdAdopter.${entry.path || entry.code}`, message: entry.message, details: entry }));
|
|
441
|
+
if (!artifactBinding || passportStableJson(artifactBinding) !== passportStableJson(binding)) {
|
|
442
|
+
issues.push({ code: "kfdAdopter.artifactEvidence", message: "release passport and artifact evidence must bind the same exact KFD adopter closure" });
|
|
443
|
+
}
|
|
444
|
+
if (!passportLegacyProjection || !legacyProjection
|
|
445
|
+
|| passportStableJson(legacyProjection) !== passportStableJson(passportLegacyProjection)) {
|
|
446
|
+
issues.push({ code: "kfdAdopter.legacyProjection", message: "legacy support projection must exactly match the manifest-derived passport sibling" });
|
|
447
|
+
}
|
|
448
|
+
return issues;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
async function explicitOrSibling({ location, basePath, sibling, readJson, resolveSibling, fallback }) {
|
|
452
|
+
if (location) return readJson(location);
|
|
453
|
+
return await resolveSibling(basePath, sibling) || fallback;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
export async function resolveReleasePassportVerificationInputs({ passportLocation, locations = {}, readJson, resolveSibling } = {}) {
|
|
457
|
+
const passport = await readJson(passportLocation);
|
|
458
|
+
const basePath = /^https?:\/\//.test(passportLocation) ? passportLocation : path.resolve(passportLocation);
|
|
459
|
+
const resolve = (location, sibling, fallback) => explicitOrSibling({ location, basePath, sibling, readJson, resolveSibling, fallback });
|
|
460
|
+
const releaseEvidenceDocuments = [];
|
|
461
|
+
for (const reference of Array.isArray(passport.releaseEvidence) ? passport.releaseEvidence : []) {
|
|
462
|
+
const id = String(reference?.id || "");
|
|
463
|
+
const safePath = /^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(id) && reference?.path === `release-evidence-${id}.json`;
|
|
464
|
+
releaseEvidenceDocuments.push({ reference, document: safePath ? await resolveSibling(basePath, reference.path) : undefined });
|
|
465
|
+
}
|
|
466
|
+
return {
|
|
467
|
+
passport,
|
|
468
|
+
artifactEvidence: await resolve(locations.artifactEvidence, passport.evidence?.artifactEvidence, {}),
|
|
469
|
+
publishEvidence: await resolve(locations.publishEvidence, passport.evidence?.publishEvidence, {}),
|
|
470
|
+
impact: await resolve(locations.impact, passport.evidence?.impact, {}),
|
|
471
|
+
agentIndex: await resolve(locations.agentIndex, passport.evidence?.agentIndex, {}),
|
|
472
|
+
productMechanism: await resolve(locations.productMechanism, passport.product?.mechanism, {}),
|
|
473
|
+
kfdAgentHubEvidence: await resolve(locations.kfdAgentHubEvidence, passport.evidence?.kfdAgentHub),
|
|
474
|
+
kfdAdopterManifest: await resolve(locations.kfdAdopterManifest, passport.evidence?.kfdAdopterManifest),
|
|
475
|
+
kfdAdopterManifestGate: await resolve(locations.kfdAdopterManifestGate, passport.evidence?.kfdAdopterGate),
|
|
476
|
+
kfdSupportEvidence: await resolve(locations.kfdSupportEvidence, passport.evidence?.kfdSupport),
|
|
477
|
+
releaseEvidenceDocuments,
|
|
478
|
+
};
|
|
479
|
+
}
|