@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.
Files changed (57) hide show
  1. package/actions/promote-buildchain-ref/README.md +8 -7
  2. package/bin/buildchain.mjs +34 -33
  3. package/bin/internal/trust-release-release-handlers.mjs +5 -0
  4. package/dist/site/agent-index.json +0 -1
  5. package/dist/site/artifact-schemas.json +0 -2
  6. package/dist/site/badge-endpoint-registry.json +9 -9
  7. package/dist/site/badges/v1/kfd-8/aligned.json +1 -1
  8. package/dist/site/badges/v1/kfd-8/declared.json +1 -1
  9. package/dist/site/badges/v1/kfd-8/downgraded.json +1 -1
  10. package/dist/site/badges/v1/kfd-8/draft.json +1 -1
  11. package/dist/site/badges/v1/kfd-8/failed.json +1 -1
  12. package/dist/site/badges/v1/kfd-8/missing.json +1 -1
  13. package/dist/site/badges/v1/kfd-8/passed.json +1 -1
  14. package/dist/site/badges/v1/kfd-8/planned.json +1 -1
  15. package/dist/site/buildchain-contract.json +27 -22
  16. package/dist/site/buildchain-site.json +38 -28
  17. package/dist/site/capability-registry.json +1 -1
  18. package/dist/site/cli-registry.json +8 -7
  19. package/dist/site/controller-registry.json +6 -2
  20. package/dist/site/kfd-claims.json +34 -7
  21. package/dist/site/kfd-upstream-aggregate.json +10 -10
  22. package/dist/site/manual-registry.json +6 -6
  23. package/dist/site/node-api-registry.json +754 -228
  24. package/dist/site/page-registry.json +28 -18
  25. package/dist/site/public-surface-audit.json +19 -9
  26. package/dist/site/publication-registry.json +4 -4
  27. package/dist/site/release-passport-check-manifest.json +33 -5
  28. package/dist/site/release-provenance.json +2 -1
  29. package/dist/site/schemas/release-passport-v1.schema.json +3 -0
  30. package/dist/site/site-manifest.json +10 -10
  31. package/dist/site/workflow-registry.json +19 -9
  32. package/docs/aws-us-elastic-runner-burst-plane.md +15 -3
  33. package/docs/cli-reference.md +6 -6
  34. package/docs/cli.md +2 -3
  35. package/docs/dev-alpha-candidate-patrol.md +45 -20
  36. package/docs/kfd-support.md +7 -7
  37. package/docs/node-api-reference.md +179 -140
  38. package/docs/release-passport.md +18 -12
  39. package/docs/release-train.md +8 -0
  40. package/package.json +4 -3
  41. package/packages/core/artifact-verification-envelope.js +114 -0
  42. package/packages/core/dev-alpha-active-release-train.js +460 -0
  43. package/packages/core/dev-alpha-candidate-selection.js +181 -0
  44. package/packages/core/index.js +4 -5
  45. package/packages/core/kfd-adopter-manifest.js +390 -0
  46. package/packages/core/kfd-product-gates.js +0 -300
  47. package/packages/core/release-passport-contract.js +219 -6
  48. package/packages/core/release-passport.js +139 -242
  49. package/scripts/aws-macos-jit-controller-core.mjs +76 -0
  50. package/scripts/aws-macos-jit-controller.mjs +29 -0
  51. package/scripts/aws-macos-jit-source-rebind.mjs +503 -0
  52. package/scripts/buildchain-cli-help.mjs +4 -2
  53. package/scripts/check-inventory.mjs +2 -2
  54. package/scripts/dev-alpha-candidate-patrol.mjs +196 -201
  55. package/scripts/generate-site-bundle.mjs +1 -8
  56. package/scripts/site-capability-metadata.mjs +3 -1
  57. 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
- createKfdSupportProjection,
19
- validateKfdSupportProjection,
20
- } from "./kfd-product-gates.js";
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 const RELEASE_PASSPORT_CONTRACT = "kungfu-buildchain-release-passport";
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 artifactEvidence = createArtifactEvidence({ assets, repository, tag: normalizedTag, sourceSha, workflow });
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 normalizedKfd2 = createKfd2ReleaseTrustPassportAudit({
1368
- explicitClaims: kfd2Claims,
1369
- kfd1Section: normalizedKfd1?.passportSection,
1370
- kfd3Section: normalizedKfd3?.passportSection,
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
- [firstTruthy(normalizedKfd1?.key, kfd1Metadata.key), normalizedKfd1?.passportSection],
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
- kfd1: normalizedKfd1 ? `${normalizedKfd1.key || kfd1Metadata.key}` : "",
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
- const releaseEvidenceIds = new Set();
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 artifactEvidence = createArtifactEvidence({ assets, repository, tag: resolvedTag, sourceSha, workflow });
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
- if (passport?.kfdSupport) {
2167
- const validation = validateKfdSupportProjection(passport.kfdSupport, {
2168
- expectedSourceSha: optionalString(passport?.release?.sourceSha),
2169
- checkedAt,
2170
- });
2171
- for (const entry of validation.issues) {
2172
- issues.push(issue("error", `kfdSupport.${entry.path || entry.code}`, entry.message, entry));
2173
- }
2174
- if (!kfdSupportEvidence || stableJson(kfdSupportEvidence) !== stableJson(passport.kfdSupport)) {
2175
- issues.push(issue(
2176
- "error",
2177
- "kfdSupport.evidence",
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 passport = await readJsonFromLocation(passportLocation);
2865
- const basePath = /^https?:\/\//.test(passportLocation) ? passportLocation : path.resolve(passportLocation);
2866
- const artifactEvidence =
2867
- artifactEvidenceLocation
2868
- ? await readJsonFromLocation(artifactEvidenceLocation)
2869
- : await resolveSiblingJson(basePath, passport.evidence?.artifactEvidence) || {};
2870
- const publishEvidence =
2871
- publishEvidenceLocation
2872
- ? await readJsonFromLocation(publishEvidenceLocation)
2873
- : await resolveSiblingJson(basePath, passport.evidence?.publishEvidence) || {};
2874
- const impact =
2875
- impactLocation
2876
- ? await readJsonFromLocation(impactLocation)
2877
- : await resolveSiblingJson(basePath, passport.evidence?.impact) || {};
2878
- const agentIndex =
2879
- agentIndexLocation
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
- passport,
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 ||