@kungfu-tech/buildchain 3.0.8 → 3.0.9-alpha.0
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/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 +27 -22
- package/dist/site/buildchain-site.json +38 -28
- package/dist/site/capability-registry.json +1 -1
- package/dist/site/cli-registry.json +8 -7
- package/dist/site/controller-registry.json +6 -2
- package/dist/site/kfd-claims.json +34 -7
- package/dist/site/kfd-upstream-aggregate.json +10 -10
- package/dist/site/manual-registry.json +6 -6
- package/dist/site/node-api-registry.json +754 -228
- package/dist/site/page-registry.json +28 -18
- 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 +10 -10
- 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/kfd-support.md +7 -7
- package/docs/node-api-reference.md +179 -140
- package/docs/release-passport.md +18 -12
- package/docs/release-train.md +8 -0
- package/package.json +4 -3
- package/packages/core/artifact-verification-envelope.js +114 -0
- package/packages/core/dev-alpha-active-release-train.js +460 -0
- package/packages/core/dev-alpha-candidate-selection.js +181 -0
- 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-passport-contract.js +219 -6
- package/packages/core/release-passport.js +139 -242
- 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-cli-help.mjs +4 -2
- package/scripts/check-inventory.mjs +2 -2
- package/scripts/dev-alpha-candidate-patrol.mjs +196 -201
- package/scripts/generate-site-bundle.mjs +1 -8
- package/scripts/site-capability-metadata.mjs +3 -1
- package/dist/site/schemas/kfd-support-projection-v1.schema.json +0 -106
|
@@ -15,9 +15,18 @@ import {
|
|
|
15
15
|
validateKfd3CollaborationInterfaceReleaseGateEvidence,
|
|
16
16
|
} from "./kfd-gate.js";
|
|
17
17
|
import {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
RELEASE_CHECK_REPORT_CONTRACT,
|
|
19
|
+
RELEASE_PASSPORT_CONTRACT,
|
|
20
|
+
buildReleaseArtifactEvidence,
|
|
21
|
+
collectKfdAdopterReleaseEvidence,
|
|
22
|
+
defaultReleaseAgentIndex as defaultAgentIndex,
|
|
23
|
+
defaultReleaseImpact as defaultImpact,
|
|
24
|
+
defaultReleaseLlmsText as defaultLlmsText,
|
|
25
|
+
defaultReleaseProductMechanism as defaultProductMechanism,
|
|
26
|
+
prepareReleasePassportKfdSections,
|
|
27
|
+
resolveReleasePassportVerificationInputs,
|
|
28
|
+
validateKfdAdopterReleaseEvidence,
|
|
29
|
+
} from "./release-passport-contract.js";
|
|
21
30
|
import { createSurfaceTimestampPolicy } from "./surface-manifest.js";
|
|
22
31
|
import { validatePublishEvidence as validateTransactionPublishEvidence } from "./publish-transaction.js";
|
|
23
32
|
import { normalizeControllerReceiptReferences } from "./controller-evidence.js";
|
|
@@ -25,12 +34,11 @@ import {
|
|
|
25
34
|
normalizeGitHubArtifactAttestationPolicy,
|
|
26
35
|
} from "./github-artifact-attestation.js";
|
|
27
36
|
|
|
28
|
-
export
|
|
37
|
+
export { RELEASE_CHECK_REPORT_CONTRACT, RELEASE_PASSPORT_CONTRACT };
|
|
29
38
|
export const ARTIFACT_EVIDENCE_CONTRACT = "kungfu-buildchain-artifact-evidence";
|
|
30
39
|
export const IMPACT_LEDGER_CONTRACT = "kungfu-buildchain-impact";
|
|
31
40
|
export const AGENT_INDEX_CONTRACT = "kungfu-buildchain-agent-index";
|
|
32
41
|
export const PRODUCT_MECHANISM_CONTRACT = "kungfu-buildchain-product-mechanism";
|
|
33
|
-
export const RELEASE_CHECK_REPORT_CONTRACT = "kungfu-buildchain-release-check-report";
|
|
34
42
|
export const RELEASE_EVIDENCE_ATTACHMENT_CONTRACT = "kungfu-buildchain-release-evidence-attachment";
|
|
35
43
|
export const KFD2_RELEASE_TRUST_PASSPORT_CONTRACT = "kungfu-buildchain-kfd-2-release-trust-passport-audit";
|
|
36
44
|
export const KFD2_TRUST_PROOF_CONTRACT = "kungfu-buildchain-kfd-2-trust-proof";
|
|
@@ -367,84 +375,6 @@ function normalizeAsset(asset, index = 0) {
|
|
|
367
375
|
};
|
|
368
376
|
}
|
|
369
377
|
|
|
370
|
-
function defaultProductMechanism({ repository = "", productName = "Buildchain" } = {}) {
|
|
371
|
-
return {
|
|
372
|
-
schemaVersion: 1,
|
|
373
|
-
contract: PRODUCT_MECHANISM_CONTRACT,
|
|
374
|
-
product: {
|
|
375
|
-
name: productName,
|
|
376
|
-
repository,
|
|
377
|
-
northStar: "GitHub-native release passport protocol for binary and multi-artifact products.",
|
|
378
|
-
},
|
|
379
|
-
trustModel: {
|
|
380
|
-
executionSubstrate: "github-actions",
|
|
381
|
-
releaseAuthority: "protected Buildchain channel refs, exact tags, and release passport evidence",
|
|
382
|
-
runnerRequirement: "runner facts are recorded, but the protocol is runner-agnostic",
|
|
383
|
-
},
|
|
384
|
-
compatibility: {
|
|
385
|
-
promise: "release passport schemas are welded surfaces; additive fields are allowed, breaking semantic changes require a new major line",
|
|
386
|
-
kfd: "KFD-1",
|
|
387
|
-
},
|
|
388
|
-
};
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
function defaultImpact({ tag = "", line = "", decision = "unknown" } = {}) {
|
|
392
|
-
const finalImpact = normalizeImpactLevel(decision);
|
|
393
|
-
return {
|
|
394
|
-
schemaVersion: 1,
|
|
395
|
-
contract: IMPACT_LEDGER_CONTRACT,
|
|
396
|
-
release: { tag, line },
|
|
397
|
-
versionImpact: {
|
|
398
|
-
final: finalImpact,
|
|
399
|
-
source: "default",
|
|
400
|
-
rationale: "No surface impact classification was supplied.",
|
|
401
|
-
},
|
|
402
|
-
surfaceImpacts: [],
|
|
403
|
-
classification: finalImpact,
|
|
404
|
-
breaking: finalImpact === "major",
|
|
405
|
-
security: false,
|
|
406
|
-
migrationRequired: finalImpact === "major",
|
|
407
|
-
summary: "No release impact summary was supplied.",
|
|
408
|
-
recovery: {
|
|
409
|
-
rollback: "Use the previous exact release tag or previous floating channel ref.",
|
|
410
|
-
block: "Fail closed if release passport verification fails.",
|
|
411
|
-
},
|
|
412
|
-
};
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
function defaultAgentIndex({ tag = "", passportPath = "buildchain.release.json" } = {}) {
|
|
416
|
-
return {
|
|
417
|
-
schemaVersion: 1,
|
|
418
|
-
contract: AGENT_INDEX_CONTRACT,
|
|
419
|
-
release: { tag },
|
|
420
|
-
entrypoints: [
|
|
421
|
-
{
|
|
422
|
-
id: "release-passport",
|
|
423
|
-
kind: "json",
|
|
424
|
-
path: passportPath,
|
|
425
|
-
description: "Read this first to verify release completeness, artifacts, impact, and recovery pointers.",
|
|
426
|
-
},
|
|
427
|
-
{
|
|
428
|
-
id: "llms",
|
|
429
|
-
kind: "text",
|
|
430
|
-
path: "llms.txt",
|
|
431
|
-
description: "Short agent-readable release instructions.",
|
|
432
|
-
},
|
|
433
|
-
],
|
|
434
|
-
};
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
function defaultLlmsText({ tag = "", passportPath = "buildchain.release.json" } = {}) {
|
|
438
|
-
return [
|
|
439
|
-
"# Buildchain Release Passport",
|
|
440
|
-
"",
|
|
441
|
-
`Release: ${tag || "unknown"}`,
|
|
442
|
-
"",
|
|
443
|
-
`Start with ${passportPath}. Verify artifact-evidence.json before installing binaries.`,
|
|
444
|
-
"If verification fails, do not install or promote this release.",
|
|
445
|
-
].join("\n");
|
|
446
|
-
}
|
|
447
|
-
|
|
448
378
|
function parseJsonInput(value, fallback = undefined, { cwd = process.cwd(), label = "JSON input" } = {}) {
|
|
449
379
|
const input = String(value || "").trim();
|
|
450
380
|
if (!input) {
|
|
@@ -1230,38 +1160,9 @@ function normalizePromotionRouting(value = undefined) {
|
|
|
1230
1160
|
return JSON.parse(JSON.stringify(value));
|
|
1231
1161
|
}
|
|
1232
1162
|
|
|
1233
|
-
export function createArtifactEvidence({ assets = [], repository = "", tag = "", sourceSha = "", workflow = {} } = {}) {
|
|
1163
|
+
export function createArtifactEvidence({ assets = [], repository = "", tag = "", sourceSha = "", workflow = {}, kfdAdopter = undefined } = {}) {
|
|
1234
1164
|
const normalizedAssets = assets.map((asset, index) => normalizeAsset(asset, index));
|
|
1235
|
-
return {
|
|
1236
|
-
schemaVersion: 1,
|
|
1237
|
-
contract: ARTIFACT_EVIDENCE_CONTRACT,
|
|
1238
|
-
repository: optionalString(repository),
|
|
1239
|
-
release: { tag: optionalString(tag), sourceSha: optionalString(sourceSha) },
|
|
1240
|
-
generatedAt: nowIso(),
|
|
1241
|
-
runner: {
|
|
1242
|
-
kind: optionalString(workflow.runnerKind || workflow.runner?.kind || ""),
|
|
1243
|
-
os: optionalString(workflow.runnerOs || workflow.runner?.os || ""),
|
|
1244
|
-
arch: optionalString(workflow.runnerArch || workflow.runner?.arch || ""),
|
|
1245
|
-
labels: Array.isArray(workflow.runnerLabels) ? workflow.runnerLabels : [],
|
|
1246
|
-
image: optionalString(workflow.runnerImage || workflow.runner?.image || ""),
|
|
1247
|
-
},
|
|
1248
|
-
workflow: {
|
|
1249
|
-
name: optionalString(workflow.name),
|
|
1250
|
-
runId: optionalString(workflow.runId),
|
|
1251
|
-
runAttempt: optionalString(workflow.runAttempt),
|
|
1252
|
-
url: optionalString(workflow.url),
|
|
1253
|
-
},
|
|
1254
|
-
artifacts: normalizedAssets.map((asset) => ({
|
|
1255
|
-
name: asset.name,
|
|
1256
|
-
kind: asset.kind,
|
|
1257
|
-
platform: asset.platform,
|
|
1258
|
-
size: asset.size,
|
|
1259
|
-
sha256: asset.sha256,
|
|
1260
|
-
url: asset.url,
|
|
1261
|
-
githubAssetId: asset.githubAssetId,
|
|
1262
|
-
attestation: optionalString(asset.attestation || ""),
|
|
1263
|
-
})),
|
|
1264
|
-
};
|
|
1165
|
+
return buildReleaseArtifactEvidence({ normalizedAssets, repository, tag, sourceSha, workflow, kfdAdopter });
|
|
1265
1166
|
}
|
|
1266
1167
|
|
|
1267
1168
|
function firstTruthy(...values) {
|
|
@@ -1286,6 +1187,14 @@ function acceptedControllerSourceShas(input) {
|
|
|
1286
1187
|
: [];
|
|
1287
1188
|
}
|
|
1288
1189
|
|
|
1190
|
+
function prepareReleaseKfdAdopterArtifacts({ kfdAdopter, assets, repository, tag, sourceSha, workflow }) {
|
|
1191
|
+
const normalized = kfdAdopter ? structuredClone(kfdAdopter) : undefined;
|
|
1192
|
+
return {
|
|
1193
|
+
normalized,
|
|
1194
|
+
artifactEvidence: createArtifactEvidence({ assets, repository, tag, sourceSha, workflow, kfdAdopter: normalized }),
|
|
1195
|
+
};
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1289
1198
|
export function createReleasePassport({
|
|
1290
1199
|
cwd = process.cwd(),
|
|
1291
1200
|
repository = "",
|
|
@@ -1320,6 +1229,9 @@ export function createReleasePassport({
|
|
|
1320
1229
|
kfd1 = undefined,
|
|
1321
1230
|
kfd2Claims = [],
|
|
1322
1231
|
kfd3 = undefined,
|
|
1232
|
+
kfdAdopter = undefined,
|
|
1233
|
+
kfdAdopterManifestEvidencePath = "",
|
|
1234
|
+
kfdAdopterGateEvidencePath = "",
|
|
1323
1235
|
kfdSupport = undefined,
|
|
1324
1236
|
kfdSupportEvidencePath = "",
|
|
1325
1237
|
invariantPassports = undefined,
|
|
@@ -1332,7 +1244,9 @@ export function createReleasePassport({
|
|
|
1332
1244
|
checkedAt = "",
|
|
1333
1245
|
} = {}) {
|
|
1334
1246
|
const normalizedTag = nonEmptyString(tag, "tag");
|
|
1335
|
-
const
|
|
1247
|
+
const { normalized: normalizedKfdAdopter, artifactEvidence } = prepareReleaseKfdAdopterArtifacts({
|
|
1248
|
+
kfdAdopter, assets, repository, tag: normalizedTag, sourceSha, workflow,
|
|
1249
|
+
});
|
|
1336
1250
|
const normalizedPublishEvidence = normalizePublishEvidence(publishEvidence);
|
|
1337
1251
|
const normalizedPackageSet = normalizePackageSet(packageSet, { packageName, packageVersion, publish });
|
|
1338
1252
|
const normalizedTrustedPublishing = normalizeTrustedPublishing(trustedPublishing, { workflow, publish });
|
|
@@ -1351,23 +1265,20 @@ export function createReleasePassport({
|
|
|
1351
1265
|
const normalizedImpact = normalizeImpactLedger(impact, { tag: normalizedTag, line });
|
|
1352
1266
|
const generatedAt = optionalString(checkedAt) || nowIso();
|
|
1353
1267
|
const kfd1Metadata = resolveKfd1Metadata();
|
|
1354
|
-
const normalizedKfd1 = kfd1?.passportSection ? kfd1 : undefined;
|
|
1355
|
-
const normalizedKfd3 = kfd3?.passportSection ? kfd3 : undefined;
|
|
1356
|
-
const normalizedKfdSupport = kfdSupport ? structuredClone(kfdSupport) : undefined;
|
|
1357
|
-
if (normalizedKfdSupport) {
|
|
1358
|
-
const validation = validateKfdSupportProjection(normalizedKfdSupport, {
|
|
1359
|
-
expectedSourceSha: optionalString(sourceSha),
|
|
1360
|
-
checkedAt: generatedAt,
|
|
1361
|
-
});
|
|
1362
|
-
if (!validation.valid) {
|
|
1363
|
-
throw new Error(`KFD support projection is invalid: ${validation.issues.map((entry) => `${entry.path}: ${entry.message}`).join("; ")}`);
|
|
1364
|
-
}
|
|
1365
|
-
}
|
|
1366
1268
|
const normalizedKfdAgentHub = normalizeKfdAgentHubEvidence(kfdAgentHubEvidence);
|
|
1367
|
-
const
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1269
|
+
const kfdParts = prepareReleasePassportKfdSections({
|
|
1270
|
+
kfd1,
|
|
1271
|
+
kfd2Claims,
|
|
1272
|
+
kfd3,
|
|
1273
|
+
kfdAdopter: normalizedKfdAdopter,
|
|
1274
|
+
kfdSupport,
|
|
1275
|
+
kfd1DefaultKey: kfd1Metadata.key,
|
|
1276
|
+
createKfd2: createKfd2ReleaseTrustPassportAudit,
|
|
1277
|
+
evidencePaths: {
|
|
1278
|
+
manifest: kfdAdopterManifestEvidencePath,
|
|
1279
|
+
gate: kfdAdopterGateEvidencePath,
|
|
1280
|
+
support: kfdSupportEvidencePath,
|
|
1281
|
+
},
|
|
1371
1282
|
});
|
|
1372
1283
|
const builtSourceSha = releaseField(release, "builtSourceSha", "built_source_sha");
|
|
1373
1284
|
const builtSourceTreeSha = releaseField(release, "builtSourceTreeSha", "built_source_tree_sha");
|
|
@@ -1494,10 +1405,7 @@ export function createReleasePassport({
|
|
|
1494
1405
|
["buildFacts", normalizedBuildFacts],
|
|
1495
1406
|
["platformArtifactManifests", normalizedPlatformArtifactManifests],
|
|
1496
1407
|
["distTagPromotion", normalizedDistTagPromotionEvidence],
|
|
1497
|
-
|
|
1498
|
-
["kfd-2", normalizedKfd2],
|
|
1499
|
-
[firstTruthy(normalizedKfd3?.key, "kfd-3"), normalizedKfd3?.passportSection],
|
|
1500
|
-
["kfdSupport", normalizedKfdSupport],
|
|
1408
|
+
...kfdParts.sectionEntries,
|
|
1501
1409
|
["kfdAgentHub", normalizedKfdAgentHub],
|
|
1502
1410
|
["invariantPassports", invariantPassports],
|
|
1503
1411
|
["releaseEvidence", releaseEvidence],
|
|
@@ -1542,10 +1450,7 @@ export function createReleasePassport({
|
|
|
1542
1450
|
artifactName: manifest.artifactName,
|
|
1543
1451
|
})),
|
|
1544
1452
|
distTagPromotionEvidence: normalizedDistTagPromotionEvidence?.path || "",
|
|
1545
|
-
|
|
1546
|
-
kfd2: normalizedKfd2 ? "kfd-2" : "",
|
|
1547
|
-
kfd3: normalizedKfd3 ? `${normalizedKfd3.key || "kfd-3"}` : "",
|
|
1548
|
-
kfdSupport: normalizedKfdSupport ? optionalString(kfdSupportEvidencePath || "kfd-support.json") : "",
|
|
1453
|
+
...kfdParts.evidence,
|
|
1549
1454
|
kfdAgentHub: normalizedKfdAgentHub ? optionalString(kfdAgentHubEvidencePath || "kfd-agent-hub-evidence.json") : "",
|
|
1550
1455
|
invariantPassports: invariantPassports ? "invariantPassports" : "",
|
|
1551
1456
|
releaseEvidence: releaseEvidence.map((entry) => entry.path),
|
|
@@ -1560,6 +1465,37 @@ export function createReleasePassport({
|
|
|
1560
1465
|
};
|
|
1561
1466
|
}
|
|
1562
1467
|
|
|
1468
|
+
function collectKfdAdopterReleaseInputs({ cwd, manifestJson, supportMatrixJson, productGateJsons, sourceSha, checkedAt }) {
|
|
1469
|
+
const manifestMeta = parseJsonInputWithMeta(manifestJson, undefined, { cwd, label: "kfdAdopterManifestJson" });
|
|
1470
|
+
const supportMatrixMeta = parseJsonInputWithMeta(supportMatrixJson, undefined, { cwd, label: "kfdSupportMatrixJson" });
|
|
1471
|
+
const productGateMetas = (productGateJsons || [])
|
|
1472
|
+
.filter(Boolean)
|
|
1473
|
+
.map((gateJson) => parseJsonInputWithMeta(gateJson, undefined, { cwd, label: "kfdProductGateJsons entry" }))
|
|
1474
|
+
.filter((meta) => meta.value);
|
|
1475
|
+
return collectKfdAdopterReleaseEvidence({
|
|
1476
|
+
manifest: manifestMeta.value,
|
|
1477
|
+
gateResults: productGateMetas.map((meta) => meta.value),
|
|
1478
|
+
comparisonMatrix: supportMatrixMeta.value,
|
|
1479
|
+
sourceSha,
|
|
1480
|
+
checkedAt,
|
|
1481
|
+
});
|
|
1482
|
+
}
|
|
1483
|
+
|
|
1484
|
+
function copyReleaseEvidenceAttachments(attachments, outputDir) {
|
|
1485
|
+
const ids = new Set();
|
|
1486
|
+
for (const { reference } of attachments) {
|
|
1487
|
+
if (ids.has(reference.id)) {
|
|
1488
|
+
throw new Error(`release evidence attachment id must be unique: ${reference.id}`);
|
|
1489
|
+
}
|
|
1490
|
+
ids.add(reference.id);
|
|
1491
|
+
}
|
|
1492
|
+
for (const { inputPath, reference } of attachments) {
|
|
1493
|
+
const destinationPath = path.join(outputDir, reference.path);
|
|
1494
|
+
fs.mkdirSync(path.dirname(destinationPath), { recursive: true });
|
|
1495
|
+
fs.copyFileSync(inputPath, destinationPath);
|
|
1496
|
+
}
|
|
1497
|
+
}
|
|
1498
|
+
|
|
1563
1499
|
export function collectGitHubReleasePassport({
|
|
1564
1500
|
cwd = process.cwd(),
|
|
1565
1501
|
tag = "",
|
|
@@ -1590,6 +1526,7 @@ export function collectGitHubReleasePassport({
|
|
|
1590
1526
|
kfd3PrebuildWitnessJsons = [],
|
|
1591
1527
|
kfd3ArtifactWitnessJsons = [],
|
|
1592
1528
|
kfd3ArtifactVerifyCommand = "",
|
|
1529
|
+
kfdAdopterManifestJson = "",
|
|
1593
1530
|
kfdSupportMatrixJson = "",
|
|
1594
1531
|
kfdProductGateJsons = [],
|
|
1595
1532
|
invariantPassportJsons = [],
|
|
@@ -1649,15 +1586,6 @@ export function collectGitHubReleasePassport({
|
|
|
1649
1586
|
cwd,
|
|
1650
1587
|
label: "KFD-3 artifact verify command",
|
|
1651
1588
|
});
|
|
1652
|
-
const kfdSupportMatrixMeta = parseJsonInputWithMeta(
|
|
1653
|
-
kfdSupportMatrixJson,
|
|
1654
|
-
undefined,
|
|
1655
|
-
{ cwd, label: "kfdSupportMatrixJson" },
|
|
1656
|
-
);
|
|
1657
|
-
const kfdProductGateMetas = (kfdProductGateJsons || [])
|
|
1658
|
-
.filter(Boolean)
|
|
1659
|
-
.map((gateJson) => parseJsonInputWithMeta(gateJson, undefined, { cwd, label: "kfdProductGateJsons entry" }))
|
|
1660
|
-
.filter((meta) => meta.value);
|
|
1661
1589
|
const basePassportMeta = parseJsonInputWithMeta(basePassportJson, undefined, { cwd, label: "basePassportJson" });
|
|
1662
1590
|
const invariantPassportMetas = (invariantPassportJsons || [])
|
|
1663
1591
|
.filter(Boolean)
|
|
@@ -1711,9 +1639,6 @@ export function collectGitHubReleasePassport({
|
|
|
1711
1639
|
...kfd3ArtifactWitnessMetas.map((meta) => meta.value),
|
|
1712
1640
|
...(kfd3ArtifactCommandMeta.value ? [kfd3ArtifactCommandMeta.value] : []),
|
|
1713
1641
|
];
|
|
1714
|
-
if (!kfdSupportMatrixMeta.value && kfdProductGateMetas.length > 0) {
|
|
1715
|
-
throw new Error("KFD product gate inputs require --kfd-support-matrix-json");
|
|
1716
|
-
}
|
|
1717
1642
|
const publish = parseJsonInput(publishJson, {}, { cwd, label: "publishJson" });
|
|
1718
1643
|
const assets = [
|
|
1719
1644
|
...(Array.isArray(release.assets) ? release.assets : []),
|
|
@@ -1732,21 +1657,27 @@ export function collectGitHubReleasePassport({
|
|
|
1732
1657
|
index,
|
|
1733
1658
|
}),
|
|
1734
1659
|
);
|
|
1735
|
-
|
|
1736
|
-
for (const { reference } of releaseEvidenceAttachments) {
|
|
1737
|
-
if (releaseEvidenceIds.has(reference.id)) {
|
|
1738
|
-
throw new Error(`release evidence attachment id must be unique: ${reference.id}`);
|
|
1739
|
-
}
|
|
1740
|
-
releaseEvidenceIds.add(reference.id);
|
|
1741
|
-
}
|
|
1742
|
-
for (const { inputPath, reference } of releaseEvidenceAttachments) {
|
|
1743
|
-
const destinationPath = path.join(resolvedOutputDir, reference.path);
|
|
1744
|
-
fs.mkdirSync(path.dirname(destinationPath), { recursive: true });
|
|
1745
|
-
fs.copyFileSync(inputPath, destinationPath);
|
|
1746
|
-
}
|
|
1660
|
+
copyReleaseEvidenceAttachments(releaseEvidenceAttachments, resolvedOutputDir);
|
|
1747
1661
|
const resolvedCheckedAt = optionalString(checkedAt) || nowIso();
|
|
1748
1662
|
const productMechanism = defaultProductMechanism({ repository, productName });
|
|
1749
|
-
const
|
|
1663
|
+
const kfdAdopterEvidence = collectKfdAdopterReleaseInputs({
|
|
1664
|
+
cwd, manifestJson: kfdAdopterManifestJson, supportMatrixJson: kfdSupportMatrixJson,
|
|
1665
|
+
productGateJsons: kfdProductGateJsons, sourceSha, checkedAt: resolvedCheckedAt,
|
|
1666
|
+
});
|
|
1667
|
+
const {
|
|
1668
|
+
manifest: kfdAdopterManifest,
|
|
1669
|
+
manifestGate: kfdAdopterManifestGate,
|
|
1670
|
+
legacyProjection: kfdSupport,
|
|
1671
|
+
binding: kfdAdopter,
|
|
1672
|
+
} = kfdAdopterEvidence;
|
|
1673
|
+
const artifactEvidence = createArtifactEvidence({
|
|
1674
|
+
assets,
|
|
1675
|
+
repository,
|
|
1676
|
+
tag: resolvedTag,
|
|
1677
|
+
sourceSha,
|
|
1678
|
+
workflow,
|
|
1679
|
+
kfdAdopter,
|
|
1680
|
+
});
|
|
1750
1681
|
const bundledPublishEvidencePath = publishEvidenceMeta.value ? "evidence.json" : "";
|
|
1751
1682
|
const impact = mergeAuthoritativeImpactBase(
|
|
1752
1683
|
normalizeImpactLedger(impactMeta.value, { tag: resolvedTag, line, decision: "unknown" }),
|
|
@@ -1767,15 +1698,6 @@ export function collectGitHubReleasePassport({
|
|
|
1767
1698
|
artifactWitnessMetas: kfd3ArtifactWitnessMetas,
|
|
1768
1699
|
artifactCommandMeta: kfd3ArtifactCommandMeta.value ? kfd3ArtifactCommandMeta : undefined,
|
|
1769
1700
|
});
|
|
1770
|
-
const kfdSupport = kfdSupportMatrixMeta.value
|
|
1771
|
-
? createKfdSupportProjection({
|
|
1772
|
-
matrix: kfdSupportMatrixMeta.value,
|
|
1773
|
-
matrixRoot: kfdSupportMatrixMeta.sha256 ? `sha256:${kfdSupportMatrixMeta.sha256}` : "",
|
|
1774
|
-
gateResults: kfdProductGateMetas.map((meta) => meta.value),
|
|
1775
|
-
expectedSourceSha: sourceSha,
|
|
1776
|
-
checkedAt: resolvedCheckedAt,
|
|
1777
|
-
})
|
|
1778
|
-
: undefined;
|
|
1779
1701
|
const passport = mergeAuthoritativePassportBase(createReleasePassport({
|
|
1780
1702
|
cwd,
|
|
1781
1703
|
repository,
|
|
@@ -1820,6 +1742,9 @@ export function collectGitHubReleasePassport({
|
|
|
1820
1742
|
kfd1,
|
|
1821
1743
|
kfd2Claims: kfd2ClaimMetas.map((meta) => meta.value),
|
|
1822
1744
|
kfd3,
|
|
1745
|
+
kfdAdopter,
|
|
1746
|
+
kfdAdopterManifestEvidencePath: kfdAdopter ? "kfd-adopter-manifest.json" : "",
|
|
1747
|
+
kfdAdopterGateEvidencePath: kfdAdopter ? "kfd-adopter-manifest-gate.json" : "",
|
|
1823
1748
|
kfdSupport,
|
|
1824
1749
|
kfdSupportEvidencePath: kfdSupport ? "kfd-support.json" : "",
|
|
1825
1750
|
invariantPassports,
|
|
@@ -1847,6 +1772,8 @@ export function collectGitHubReleasePassport({
|
|
|
1847
1772
|
productMechanism,
|
|
1848
1773
|
kfdAgentHubEvidence: kfdAgentHubEvidenceMeta.value,
|
|
1849
1774
|
kfdSupportEvidence: kfdSupport,
|
|
1775
|
+
kfdAdopterManifest,
|
|
1776
|
+
kfdAdopterManifestGate,
|
|
1850
1777
|
releaseEvidenceDocuments: releaseEvidenceAttachments,
|
|
1851
1778
|
checkedAt: resolvedCheckedAt,
|
|
1852
1779
|
});
|
|
@@ -1857,6 +1784,8 @@ export function collectGitHubReleasePassport({
|
|
|
1857
1784
|
"impact.json": impact,
|
|
1858
1785
|
"agent-index.json": agentIndex,
|
|
1859
1786
|
...(kfdAgentHubEvidenceMeta.value ? { "kfd-agent-hub-evidence.json": kfdAgentHubEvidenceMeta.value } : {}),
|
|
1787
|
+
...(kfdAdopterManifest ? { "kfd-adopter-manifest.json": kfdAdopterManifest } : {}),
|
|
1788
|
+
...(kfdAdopterManifestGate ? { "kfd-adopter-manifest-gate.json": kfdAdopterManifestGate } : {}),
|
|
1860
1789
|
...(kfdSupport ? { "kfd-support.json": kfdSupport } : {}),
|
|
1861
1790
|
"buildchain.release.json": passport,
|
|
1862
1791
|
"check-report.json": checkReport,
|
|
@@ -2154,6 +2083,8 @@ function validateReleaseEvidenceContracts({
|
|
|
2154
2083
|
productMechanism,
|
|
2155
2084
|
kfdAgentHubEvidence,
|
|
2156
2085
|
kfdSupportEvidence,
|
|
2086
|
+
kfdAdopterManifest,
|
|
2087
|
+
kfdAdopterManifestGate,
|
|
2157
2088
|
checkedAt,
|
|
2158
2089
|
issues,
|
|
2159
2090
|
}) {
|
|
@@ -2163,22 +2094,18 @@ function validateReleaseEvidenceContracts({
|
|
|
2163
2094
|
validateContract(agentIndex, AGENT_INDEX_CONTRACT, "agentIndex", issues);
|
|
2164
2095
|
validateContract(productMechanism, PRODUCT_MECHANISM_CONTRACT, "productMechanism", issues);
|
|
2165
2096
|
validateKfdAgentHubReleaseEvidence(passport?.kfdAgentHub, kfdAgentHubEvidence, issues);
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
"release passport KFD support projection must exactly match its sibling evidence",
|
|
2179
|
-
));
|
|
2180
|
-
}
|
|
2181
|
-
} else if (kfdSupportEvidence) {
|
|
2097
|
+
for (const entry of validateKfdAdopterReleaseEvidence({
|
|
2098
|
+
binding: passport?.kfdAdopter,
|
|
2099
|
+
artifactBinding: artifactEvidence?.kfdAdopter,
|
|
2100
|
+
manifest: kfdAdopterManifest,
|
|
2101
|
+
manifestGate: kfdAdopterManifestGate,
|
|
2102
|
+
legacyProjection: kfdSupportEvidence,
|
|
2103
|
+
passportLegacyProjection: passport?.kfdSupport,
|
|
2104
|
+
expectedSourceSha: optionalString(passport?.release?.sourceSha),
|
|
2105
|
+
})) {
|
|
2106
|
+
issues.push(issue("error", entry.code, entry.message, entry.details));
|
|
2107
|
+
}
|
|
2108
|
+
if (!passport?.kfdSupport && kfdSupportEvidence) {
|
|
2182
2109
|
issues.push(issue("error", "kfdSupport.section", "KFD support evidence is present without a release-passport projection"));
|
|
2183
2110
|
}
|
|
2184
2111
|
|
|
@@ -2744,6 +2671,8 @@ export function createReleaseCheckReport({
|
|
|
2744
2671
|
productMechanism,
|
|
2745
2672
|
kfdAgentHubEvidence,
|
|
2746
2673
|
kfdSupportEvidence,
|
|
2674
|
+
kfdAdopterManifest,
|
|
2675
|
+
kfdAdopterManifestGate,
|
|
2747
2676
|
releaseEvidenceDocuments = [],
|
|
2748
2677
|
checkedAt = nowIso(),
|
|
2749
2678
|
} = {}) {
|
|
@@ -2756,6 +2685,8 @@ export function createReleaseCheckReport({
|
|
|
2756
2685
|
productMechanism,
|
|
2757
2686
|
kfdAgentHubEvidence,
|
|
2758
2687
|
kfdSupportEvidence,
|
|
2688
|
+
kfdAdopterManifest,
|
|
2689
|
+
kfdAdopterManifestGate,
|
|
2759
2690
|
checkedAt,
|
|
2760
2691
|
issues,
|
|
2761
2692
|
});
|
|
@@ -2858,63 +2789,29 @@ export async function verifyReleasePassport({
|
|
|
2858
2789
|
agentIndexLocation = "",
|
|
2859
2790
|
productMechanismLocation = "",
|
|
2860
2791
|
kfdAgentHubEvidenceLocation = "",
|
|
2792
|
+
kfdAdopterManifestLocation = "",
|
|
2793
|
+
kfdAdopterManifestGateLocation = "",
|
|
2861
2794
|
kfdSupportEvidenceLocation = "",
|
|
2862
2795
|
checkedAt = nowIso(),
|
|
2863
2796
|
} = {}) {
|
|
2864
|
-
const
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
:
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
:
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
? await readJsonFromLocation(agentIndexLocation)
|
|
2881
|
-
: await resolveSiblingJson(basePath, passport.evidence?.agentIndex) || {};
|
|
2882
|
-
const productMechanism =
|
|
2883
|
-
productMechanismLocation
|
|
2884
|
-
? await readJsonFromLocation(productMechanismLocation)
|
|
2885
|
-
: await resolveSiblingJson(basePath, passport.product?.mechanism) || {};
|
|
2886
|
-
const kfdAgentHubEvidence =
|
|
2887
|
-
kfdAgentHubEvidenceLocation
|
|
2888
|
-
? await readJsonFromLocation(kfdAgentHubEvidenceLocation)
|
|
2889
|
-
: await resolveSiblingJson(basePath, passport.evidence?.kfdAgentHub) || undefined;
|
|
2890
|
-
const kfdSupportEvidence =
|
|
2891
|
-
kfdSupportEvidenceLocation
|
|
2892
|
-
? await readJsonFromLocation(kfdSupportEvidenceLocation)
|
|
2893
|
-
: await resolveSiblingJson(basePath, passport.evidence?.kfdSupport) || undefined;
|
|
2894
|
-
const releaseEvidenceDocuments = [];
|
|
2895
|
-
for (const reference of Array.isArray(passport.releaseEvidence) ? passport.releaseEvidence : []) {
|
|
2896
|
-
const id = String(reference?.id || "");
|
|
2897
|
-
const expectedPath = `release-evidence-${id}.json`;
|
|
2898
|
-
const safePath =
|
|
2899
|
-
/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(id) &&
|
|
2900
|
-
reference?.path === expectedPath;
|
|
2901
|
-
releaseEvidenceDocuments.push({
|
|
2902
|
-
reference,
|
|
2903
|
-
document: safePath
|
|
2904
|
-
? await resolveSiblingJson(basePath, reference.path)
|
|
2905
|
-
: undefined,
|
|
2906
|
-
});
|
|
2907
|
-
}
|
|
2797
|
+
const evidence = await resolveReleasePassportVerificationInputs({
|
|
2798
|
+
passportLocation,
|
|
2799
|
+
locations: {
|
|
2800
|
+
artifactEvidence: artifactEvidenceLocation,
|
|
2801
|
+
publishEvidence: publishEvidenceLocation,
|
|
2802
|
+
impact: impactLocation,
|
|
2803
|
+
agentIndex: agentIndexLocation,
|
|
2804
|
+
productMechanism: productMechanismLocation,
|
|
2805
|
+
kfdAgentHubEvidence: kfdAgentHubEvidenceLocation,
|
|
2806
|
+
kfdAdopterManifest: kfdAdopterManifestLocation,
|
|
2807
|
+
kfdAdopterManifestGate: kfdAdopterManifestGateLocation,
|
|
2808
|
+
kfdSupportEvidence: kfdSupportEvidenceLocation,
|
|
2809
|
+
},
|
|
2810
|
+
readJson: readJsonFromLocation,
|
|
2811
|
+
resolveSibling: resolveSiblingJson,
|
|
2812
|
+
});
|
|
2908
2813
|
return createReleaseCheckReport({
|
|
2909
|
-
|
|
2910
|
-
artifactEvidence,
|
|
2911
|
-
publishEvidence,
|
|
2912
|
-
impact,
|
|
2913
|
-
agentIndex,
|
|
2914
|
-
productMechanism,
|
|
2915
|
-
kfdAgentHubEvidence,
|
|
2916
|
-
kfdSupportEvidence,
|
|
2917
|
-
releaseEvidenceDocuments,
|
|
2814
|
+
...evidence,
|
|
2918
2815
|
checkedAt,
|
|
2919
2816
|
});
|
|
2920
2817
|
}
|
|
@@ -56,6 +56,17 @@ function source(values) {
|
|
|
56
56
|
};
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
function previousSource(values) {
|
|
60
|
+
return {
|
|
61
|
+
sha: exactSha(values.previousSourceSha),
|
|
62
|
+
ref: exact(
|
|
63
|
+
values.previousSourceRef || values.sourceRef,
|
|
64
|
+
/^refs\/heads\/[A-Za-z0-9._/-]+$/,
|
|
65
|
+
"previousSourceRef",
|
|
66
|
+
),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
59
70
|
function campaignId(value) {
|
|
60
71
|
return exact(value, /^[a-z0-9][a-z0-9-]{2,47}$/, "campaignId");
|
|
61
72
|
}
|
|
@@ -192,6 +203,71 @@ export function createMacosJitCampaignPlan(values = {}) {
|
|
|
192
203
|
return { ...plan, digest: digest(plan) };
|
|
193
204
|
}
|
|
194
205
|
|
|
206
|
+
export function createMacosJitSourceRebindPlan(values = {}) {
|
|
207
|
+
const id = campaignId(values.campaignId);
|
|
208
|
+
const boundSource = source(values);
|
|
209
|
+
const priorSource = previousSource(values);
|
|
210
|
+
if (boundSource.sha === priorSource.sha) {
|
|
211
|
+
throw new Error("sourceSha must differ from previousSourceSha");
|
|
212
|
+
}
|
|
213
|
+
if (boundSource.ref !== priorSource.ref) {
|
|
214
|
+
throw new Error("sourceRef must remain unchanged during campaign rebind");
|
|
215
|
+
}
|
|
216
|
+
const aws = commonAws(values);
|
|
217
|
+
const regionConfig = macosJitRegionConfig(aws.region);
|
|
218
|
+
const workflowId = exact(values.workflowId, /^\d+$/, "workflowId");
|
|
219
|
+
if (workflowId !== MACOS_EC2_JIT.workflowId) {
|
|
220
|
+
throw new Error(`workflowId must be ${MACOS_EC2_JIT.workflowId}`);
|
|
221
|
+
}
|
|
222
|
+
const plan = {
|
|
223
|
+
schemaVersion: 1,
|
|
224
|
+
contract: AWS_MACOS_JIT_CONTROLLER_CONTRACT,
|
|
225
|
+
kind: "campaign-source-rebind-plan",
|
|
226
|
+
repository: repository(values.repository),
|
|
227
|
+
account: {
|
|
228
|
+
id: exact(values.accountId, /^\d{12}$/, "accountId"),
|
|
229
|
+
},
|
|
230
|
+
campaign: { id },
|
|
231
|
+
previousSource: priorSource,
|
|
232
|
+
source: boundSource,
|
|
233
|
+
github: {
|
|
234
|
+
workflowId,
|
|
235
|
+
requiredState: "disabled_manually",
|
|
236
|
+
},
|
|
237
|
+
aws: {
|
|
238
|
+
...aws,
|
|
239
|
+
hostId: exact(values.hostId, /^h-[0-9a-f]+$/, "hostId"),
|
|
240
|
+
instanceId: exact(values.instanceId, /^i-[0-9a-f]+$/, "instanceId"),
|
|
241
|
+
},
|
|
242
|
+
safety: {
|
|
243
|
+
applyMode: values.execute === true ? "execute" : "dry-run",
|
|
244
|
+
noAllocation: true,
|
|
245
|
+
noDispatch: true,
|
|
246
|
+
forwardOnlySource: true,
|
|
247
|
+
sameSourceRefRequired: true,
|
|
248
|
+
workflowDisabledRequired: true,
|
|
249
|
+
zeroPriorJobsRequired: true,
|
|
250
|
+
zeroPriorArtifactsRequired: true,
|
|
251
|
+
zeroJitResidueRequired: true,
|
|
252
|
+
zeroEvidenceRequired: true,
|
|
253
|
+
exactCampaignResourcesRequired: true,
|
|
254
|
+
compensatedRollbackRequired: true,
|
|
255
|
+
budget: {
|
|
256
|
+
name: regionConfig.budgetName,
|
|
257
|
+
limitUsd: MACOS_EC2_JIT.budgetLimitUsd,
|
|
258
|
+
metrics: ["UnblendedCost"],
|
|
259
|
+
dimensionFilter: {
|
|
260
|
+
usageTypes: regionConfig.budgetUsageTypes,
|
|
261
|
+
operation: MACOS_EC2_JIT.budgetOperation,
|
|
262
|
+
regions: regionConfig.budgetRegions,
|
|
263
|
+
},
|
|
264
|
+
requiredActualThresholds: [80, 95],
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
};
|
|
268
|
+
return { ...plan, digest: digest(plan) };
|
|
269
|
+
}
|
|
270
|
+
|
|
195
271
|
export function macosAllocateHostsArgs(plan) {
|
|
196
272
|
if (
|
|
197
273
|
plan?.contract !== AWS_MACOS_JIT_CONTROLLER_CONTRACT ||
|