@kungfu-tech/buildchain 3.0.1 → 3.0.2-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.
Files changed (64) hide show
  1. package/README.md +5 -3
  2. package/actions/promote-buildchain-ref/README.md +7 -0
  3. package/bin/buildchain.mjs +173 -513
  4. package/bin/internal/cli-options.mjs +79 -0
  5. package/bin/internal/trust-release-cli.mjs +469 -0
  6. package/dist/site/agent-index.json +2 -0
  7. package/dist/site/artifact-schemas.json +5 -0
  8. package/dist/site/badge-endpoint-registry.json +18 -18
  9. package/dist/site/badges/v1/kfd-12/aligned.json +1 -1
  10. package/dist/site/badges/v1/kfd-12/declared.json +1 -1
  11. package/dist/site/badges/v1/kfd-12/downgraded.json +1 -1
  12. package/dist/site/badges/v1/kfd-12/draft.json +1 -1
  13. package/dist/site/badges/v1/kfd-12/failed.json +1 -1
  14. package/dist/site/badges/v1/kfd-12/missing.json +1 -1
  15. package/dist/site/badges/v1/kfd-12/passed.json +1 -1
  16. package/dist/site/badges/v1/kfd-12/planned.json +1 -1
  17. package/dist/site/badges/v1/kfd-13/aligned.json +1 -1
  18. package/dist/site/badges/v1/kfd-13/declared.json +1 -1
  19. package/dist/site/badges/v1/kfd-13/downgraded.json +1 -1
  20. package/dist/site/badges/v1/kfd-13/draft.json +1 -1
  21. package/dist/site/badges/v1/kfd-13/failed.json +1 -1
  22. package/dist/site/badges/v1/kfd-13/missing.json +1 -1
  23. package/dist/site/badges/v1/kfd-13/passed.json +1 -1
  24. package/dist/site/badges/v1/kfd-13/planned.json +1 -1
  25. package/dist/site/buildchain-contract.json +68 -28
  26. package/dist/site/buildchain-site.json +28 -18
  27. package/dist/site/capability-registry.json +3 -3
  28. package/dist/site/cli-registry.json +108 -0
  29. package/dist/site/controller-registry.json +36 -4
  30. package/dist/site/kfd-claims.json +156 -12
  31. package/dist/site/kfd-upstream-aggregate.json +20 -11
  32. package/dist/site/manual-registry.json +3 -3
  33. package/dist/site/node-api-registry.json +36 -10
  34. package/dist/site/page-registry.json +20 -10
  35. package/dist/site/public-surface-audit.json +122 -10
  36. package/dist/site/publication-registry.json +4 -4
  37. package/dist/site/release-passport-check-manifest.json +11 -0
  38. package/dist/site/release-provenance.json +4 -0
  39. package/dist/site/schemas/kfd-product-gate-input-v1.schema.json +164 -0
  40. package/dist/site/schemas/kfd-support-projection-v1.schema.json +106 -0
  41. package/dist/site/schemas/release-passport-v1.schema.json +3 -0
  42. package/dist/site/site-manifest.json +7 -7
  43. package/dist/site/workflow-registry.json +17 -5
  44. package/docs/cli.md +9 -2
  45. package/docs/kfd-support.md +43 -7
  46. package/docs/release-passport.md +15 -0
  47. package/package.json +7 -3
  48. package/packages/core/cache-evidence.js +288 -0
  49. package/packages/core/diagnostics.js +276 -10
  50. package/packages/core/github-governance-authority.js +71 -16
  51. package/packages/core/index.js +27 -0
  52. package/packages/core/kfd-product-gates.js +865 -0
  53. package/packages/core/kfd.js +16 -7
  54. package/packages/core/kfd3-surface-register.js +105 -1
  55. package/packages/core/public-surface-audit.js +6 -1
  56. package/packages/core/release-passport-contract.js +13 -0
  57. package/packages/core/release-passport.js +87 -3
  58. package/scripts/check-internal-architecture.mjs +171 -0
  59. package/scripts/check-inventory.mjs +4 -0
  60. package/scripts/generate-site-bundle.mjs +24 -0
  61. package/scripts/locked-source-checkout.mjs +48 -0
  62. package/scripts/promotion-routing-evidence.mjs +73 -0
  63. package/scripts/reconcile-github-governance.mjs +158 -25
  64. package/scripts/shifu-gate-profile.mjs +26 -20
@@ -19,6 +19,11 @@ import {
19
19
  readBuildchainLogEvents,
20
20
  summarizeBuildchainLogEvents,
21
21
  } from "./logging.js";
22
+ import {
23
+ cacheEvidenceDigest,
24
+ createCacheEvidenceSet,
25
+ createCacheOperationReceipt,
26
+ } from "./cache-evidence.js";
22
27
 
23
28
  export const BUILDCHAIN_DIAGNOSTICS_CONTRACT = "kungfu-buildchain-diagnostics";
24
29
  export const BUILDCHAIN_LIFECYCLE_OBSERVABILITY_CONTRACT =
@@ -568,18 +573,37 @@ function collectCompilerCacheTool({ command, attempts, cwd, runCommand }) {
568
573
  export function collectCompilerCacheDiagnostics({
569
574
  cwd = process.cwd(),
570
575
  runCommand = defaultDiagnosticCommandRunner,
576
+ env = process.env,
571
577
  } = {}) {
572
578
  const resolvedCwd = path.resolve(cwd);
579
+ const ccache = collectCompilerCacheTool({
580
+ command: "ccache",
581
+ attempts: [
582
+ { args: ["--show-stats", "--json"], format: "json" },
583
+ { args: ["--show-stats"], format: "text" },
584
+ ],
585
+ cwd: resolvedCwd,
586
+ runCommand,
587
+ });
588
+ ccache.logStats = env.CCACHE_STATSLOG
589
+ ? collectCompilerCacheTool({
590
+ command: "ccache",
591
+ attempts: [
592
+ {
593
+ args: ["--print-log-stats", "--format", "json"],
594
+ format: "json",
595
+ },
596
+ ],
597
+ cwd: resolvedCwd,
598
+ runCommand,
599
+ })
600
+ : {
601
+ available: false,
602
+ command: "ccache",
603
+ error: "CCACHE_STATSLOG is not configured",
604
+ };
573
605
  return {
574
- ccache: collectCompilerCacheTool({
575
- command: "ccache",
576
- attempts: [
577
- { args: ["--show-stats", "--json"], format: "json" },
578
- { args: ["--show-stats"], format: "text" },
579
- ],
580
- cwd: resolvedCwd,
581
- runCommand,
582
- }),
606
+ ccache,
583
607
  sccache: collectCompilerCacheTool({
584
608
  command: "sccache",
585
609
  attempts: [
@@ -591,6 +615,238 @@ export function collectCompilerCacheDiagnostics({
591
615
  };
592
616
  }
593
617
 
618
+ function unavailableMetric(unit, reason, source = null, evidenceRoot = null) {
619
+ return {
620
+ status: "unavailable",
621
+ unit,
622
+ value: null,
623
+ source,
624
+ reason,
625
+ evidenceRoot,
626
+ };
627
+ }
628
+
629
+ function notApplicableMetric(unit, reason) {
630
+ return {
631
+ status: "not-applicable",
632
+ unit,
633
+ value: null,
634
+ reason,
635
+ };
636
+ }
637
+
638
+ function observedMetric(unit, value, source, evidenceRoot) {
639
+ return {
640
+ status: "observed",
641
+ unit,
642
+ value: Number(value),
643
+ source,
644
+ evidenceRoot,
645
+ };
646
+ }
647
+
648
+ function cacheStatsCount(stats, names) {
649
+ return names.reduce((sum, name) => sum + Number(stats?.[name] || 0), 0);
650
+ }
651
+
652
+ function compilerCacheOutcome(compilerCaches) {
653
+ const logStats = compilerCaches?.ccache?.logStats;
654
+ if (!logStats?.available || !logStats.stats) return "unavailable";
655
+ const hits = cacheStatsCount(logStats.stats, [
656
+ "direct_cache_hit",
657
+ "preprocessed_cache_hit",
658
+ ]);
659
+ const misses = cacheStatsCount(logStats.stats, ["cache_miss"]);
660
+ if (hits > 0 && misses > 0) return "partial";
661
+ if (hits > 0) return "hit";
662
+ if (misses > 0) return "miss";
663
+ return "bypassed";
664
+ }
665
+
666
+ function createStructuredCacheEvidence({
667
+ sourceCheckout,
668
+ compilerCaches,
669
+ platform,
670
+ env = process.env,
671
+ }) {
672
+ const repository = env.GITHUB_REPOSITORY || sourceCheckout?.repository || "unknown/unknown";
673
+ const sourceCommit =
674
+ env.BUILDCHAIN_SOURCE_SHA ||
675
+ sourceCheckout?.source?.sha ||
676
+ sourceCheckout?.verification?.head ||
677
+ "unknown";
678
+ const sourceTree =
679
+ env.BUILDCHAIN_SOURCE_TREE_SHA ||
680
+ sourceCheckout?.source?.treeSha ||
681
+ sourceCheckout?.verification?.tree ||
682
+ "";
683
+ const runtimeCommit = env.BUILDCHAIN_RUNTIME_SHA || "";
684
+ const policyRoot = env.SHIFU_CACHE_PROFILE_DIGEST || "";
685
+ const bindings = {
686
+ sourceCommit,
687
+ ...(sourceTree ? { sourceTree } : {}),
688
+ ...(runtimeCommit ? { runtimeCommit } : {}),
689
+ ...(env.BUILDCHAIN_DEPENDENCY_LOCK_ROOT
690
+ ? { dependencyLockRoot: env.BUILDCHAIN_DEPENDENCY_LOCK_ROOT }
691
+ : {}),
692
+ ...(env.BUILDCHAIN_TOOLCHAIN_ROOT
693
+ ? { toolchainRoot: env.BUILDCHAIN_TOOLCHAIN_ROOT }
694
+ : {}),
695
+ ...(env.BUILDCHAIN_CACHE_POLICY_ROOT
696
+ ? { policyRoot: env.BUILDCHAIN_CACHE_POLICY_ROOT }
697
+ : {}),
698
+ ...(policyRoot ? { cacheProfileRoot: policyRoot } : {}),
699
+ };
700
+ const operations = [];
701
+ if (sourceCheckout) {
702
+ const evidenceRoot = cacheEvidenceDigest(sourceCheckout);
703
+ const cache = sourceCheckout.cache || {};
704
+ const outcome = cache.hit
705
+ ? "hit"
706
+ : cache.attempted === false || sourceCheckout.policy?.mode === "off"
707
+ ? "bypassed"
708
+ : cache.fallbackUsed
709
+ ? "miss"
710
+ : "unavailable";
711
+ operations.push(
712
+ createCacheOperationReceipt({
713
+ operationId: `source-checkout:${platform}`,
714
+ operation: "restore",
715
+ provider: `git-${cache.transport || "unknown"}`,
716
+ producer: "kungfu-systems/buildchain",
717
+ platform,
718
+ cacheKey: sourceCommit,
719
+ cacheRoot:
720
+ sourceCheckout.policy?.referenceRepository?.display ||
721
+ sourceCheckout.policy?.mirror?.display ||
722
+ `transport:${cache.transport || "unknown"}`,
723
+ outcome,
724
+ bindings,
725
+ metrics: {
726
+ lookupDuration:
727
+ cache.attempted === false
728
+ ? notApplicableMetric("ms", "source checkout cache was disabled")
729
+ : observedMetric(
730
+ "ms",
731
+ cache.lookupDurationMs || 0,
732
+ "locked-source-checkout",
733
+ evidenceRoot,
734
+ ),
735
+ restoreDuration: cache.hit
736
+ ? observedMetric(
737
+ "ms",
738
+ cache.restoreDurationMs || 0,
739
+ "locked-source-checkout",
740
+ evidenceRoot,
741
+ )
742
+ : notApplicableMetric(
743
+ "ms",
744
+ "no cache payload was admitted for restore",
745
+ ),
746
+ saveDuration: notApplicableMetric(
747
+ "ms",
748
+ "locked source checkout does not save cache state",
749
+ ),
750
+ restoredBytes:
751
+ cache.restoredBytesStatus === "observed"
752
+ ? observedMetric(
753
+ "bytes",
754
+ cache.restoredBytes || 0,
755
+ cache.restoredBytesMethod || "git-object-store-delta",
756
+ evidenceRoot,
757
+ )
758
+ : unavailableMetric(
759
+ "bytes",
760
+ "checkout provider did not expose restored byte evidence",
761
+ "locked-source-checkout",
762
+ evidenceRoot,
763
+ ),
764
+ writtenBytes: notApplicableMetric(
765
+ "bytes",
766
+ "locked source checkout does not save cache state",
767
+ ),
768
+ savedTime: unavailableMetric(
769
+ "ms",
770
+ "checkout provider did not report a measured cold-path comparison",
771
+ "locked-source-checkout",
772
+ evidenceRoot,
773
+ ),
774
+ },
775
+ evidence: {
776
+ kind: "locked-source-checkout",
777
+ root: evidenceRoot,
778
+ locator: ".buildchain/diagnostics/source-checkout.json",
779
+ },
780
+ }),
781
+ );
782
+ }
783
+ const compilerEvidenceRoot = cacheEvidenceDigest(compilerCaches || {});
784
+ operations.push(
785
+ createCacheOperationReceipt({
786
+ operationId: `compiler-cache:${platform}`,
787
+ operation: "restore",
788
+ provider: compilerCaches?.ccache?.available ? "ccache" : "compiler-cache",
789
+ producer: compilerCaches?.ccache?.available ? "ccache" : "unavailable",
790
+ platform,
791
+ cacheKey: policyRoot || null,
792
+ cacheRoot: policyRoot || null,
793
+ outcome: compilerCacheOutcome(compilerCaches),
794
+ bindings,
795
+ metrics: {
796
+ lookupDuration: unavailableMetric(
797
+ "ms",
798
+ "ccache stats log exposes outcomes but not lookup duration",
799
+ "ccache-stats-log",
800
+ compilerEvidenceRoot,
801
+ ),
802
+ restoreDuration: unavailableMetric(
803
+ "ms",
804
+ "ccache stats log exposes outcomes but not transfer duration",
805
+ "ccache-stats-log",
806
+ compilerEvidenceRoot,
807
+ ),
808
+ saveDuration: unavailableMetric(
809
+ "ms",
810
+ "ccache stats log exposes writes but not save duration",
811
+ "ccache-stats-log",
812
+ compilerEvidenceRoot,
813
+ ),
814
+ restoredBytes: unavailableMetric(
815
+ "bytes",
816
+ "ccache does not expose per-run restored bytes",
817
+ "ccache-stats-log",
818
+ compilerEvidenceRoot,
819
+ ),
820
+ writtenBytes: unavailableMetric(
821
+ "bytes",
822
+ "ccache does not expose per-run written bytes",
823
+ "ccache-stats-log",
824
+ compilerEvidenceRoot,
825
+ ),
826
+ savedTime: unavailableMetric(
827
+ "ms",
828
+ "ccache does not report evidence-backed compile time saved",
829
+ "ccache-stats-log",
830
+ compilerEvidenceRoot,
831
+ ),
832
+ },
833
+ evidence: {
834
+ kind: "compiler-cache-diagnostics",
835
+ root: compilerEvidenceRoot,
836
+ locator: ".buildchain/artifacts/<platform>/diagnostics.json#compilerCaches",
837
+ },
838
+ }),
839
+ );
840
+ return createCacheEvidenceSet({
841
+ repository,
842
+ sourceCommit,
843
+ sourceTree,
844
+ runtimeCommit,
845
+ platform,
846
+ operations,
847
+ });
848
+ }
849
+
594
850
  export function collectCacheDiagnostics({ cwd = process.cwd(), cacheDirs = [], runCommand = defaultDiagnosticCommandRunner } = {}) {
595
851
  const resolvedCwd = path.resolve(cwd);
596
852
  return {
@@ -1095,6 +1351,11 @@ export function createDiagnosticsArtifact({
1095
1351
  const nativeProfile = getNativeDiagnosticsProfile(loadedConfig);
1096
1352
  const native = collectNativeDiagnostics({ cwd: resolvedCwd, profile: nativeProfile });
1097
1353
  const cache = collectCacheDiagnostics({ cwd: resolvedCwd, cacheDirs });
1354
+ const compilerCaches = native.compilerCaches || cache.compilerCaches || {};
1355
+ const platform =
1356
+ links.platformId ||
1357
+ process.env.BUILDCHAIN_PLATFORM_ID ||
1358
+ `${process.env.RUNNER_OS || os.platform()}-${process.env.RUNNER_ARCH || os.arch()}`;
1098
1359
  return {
1099
1360
  schemaVersion: 1,
1100
1361
  contract: BUILDCHAIN_DIAGNOSTICS_CONTRACT,
@@ -1105,7 +1366,12 @@ export function createDiagnosticsArtifact({
1105
1366
  tools: collectToolDiagnostics({ cwd: resolvedCwd }),
1106
1367
  cache,
1107
1368
  native,
1108
- compilerCaches: native.compilerCaches || cache.compilerCaches || {},
1369
+ compilerCaches,
1370
+ cacheEvidence: createStructuredCacheEvidence({
1371
+ sourceCheckout,
1372
+ compilerCaches,
1373
+ platform,
1374
+ }),
1109
1375
  nativeCacheDirs: native.cacheDirs || [],
1110
1376
  git: collectGitDiagnostics({ cwd: resolvedCwd }),
1111
1377
  lifecycleObservability: lifecycleObservability || summarizeLifecycleObservability({ events, logPath }),
@@ -1191,20 +1191,38 @@ export function createGithubRulesetGovernanceRolloutPlan({
1191
1191
  repository,
1192
1192
  targetRef,
1193
1193
  rulesetId,
1194
+ rulesetName,
1194
1195
  inventory,
1195
1196
  rollbackSnapshot,
1196
1197
  desiredProtection,
1197
1198
  } = {}) {
1198
1199
  const fullName = requiredString(repository, "repository");
1199
1200
  const branch = normalizedRef(targetRef);
1200
- const id = Number(rulesetId);
1201
- if (!Number.isInteger(id) || id <= 0) {
1202
- throw new Error("ruleset id must be a positive integer");
1201
+ const creating = rulesetId === null || rulesetId === undefined || rulesetId === "";
1202
+ const id = creating ? null : Number(rulesetId);
1203
+ if (!creating && (!Number.isInteger(id) || id <= 0)) {
1204
+ throw new Error("ruleset id must be a positive integer when supplied");
1203
1205
  }
1204
- if (!inventory || !rollbackSnapshot) {
1205
- throw new Error("read-only inventory and frozen rollback snapshot are required");
1206
+ if (!inventory || (!creating && !rollbackSnapshot)) {
1207
+ throw new Error(
1208
+ "read-only inventory and any existing frozen rollback snapshot are required",
1209
+ );
1206
1210
  }
1207
- const before = normalizeGithubRulesetSnapshot(rollbackSnapshot);
1211
+ const before = creating
1212
+ ? {
1213
+ name: requiredString(rulesetName, "ruleset name"),
1214
+ target: "branch",
1215
+ enforcement: "active",
1216
+ bypass_actors: [],
1217
+ conditions: {
1218
+ ref_name: {
1219
+ include: [`refs/heads/${branch}`],
1220
+ exclude: [],
1221
+ },
1222
+ },
1223
+ rules: [],
1224
+ }
1225
+ : normalizeGithubRulesetSnapshot(rollbackSnapshot);
1208
1226
  const exactInclude = before.conditions?.ref_name?.include || [];
1209
1227
  const exactExclude = before.conditions?.ref_name?.exclude || [];
1210
1228
  if (
@@ -1265,28 +1283,53 @@ export function createGithubRulesetGovernanceRolloutPlan({
1265
1283
  });
1266
1284
  if (pullRequestRules.length === 0) desiredRules.push(desiredPullRequestRule);
1267
1285
  if (statusCheckRules.length === 0) desiredRules.push(desiredStatusCheckRule);
1286
+ if (
1287
+ desiredProtection?.blockDeletions === true &&
1288
+ !desiredRules.some((rule) => rule.type === "deletion")
1289
+ ) {
1290
+ desiredRules.push({ type: "deletion" });
1291
+ }
1292
+ if (
1293
+ desiredProtection?.blockNonFastForward === true &&
1294
+ !desiredRules.some((rule) => rule.type === "non_fast_forward")
1295
+ ) {
1296
+ desiredRules.push({ type: "non_fast_forward" });
1297
+ }
1268
1298
  const desired = {
1269
1299
  ...before,
1300
+ name: rulesetName
1301
+ ? requiredString(rulesetName, "ruleset name")
1302
+ : before.name,
1270
1303
  bypass_actors: providerRulesetBypassActors(
1271
1304
  desiredProtection?.rulesetBypassActors,
1272
1305
  ),
1273
1306
  rules: desiredRules,
1274
1307
  };
1275
- const endpoint = `repos/${fullName}/rulesets/${id}`;
1308
+ const endpoint = creating
1309
+ ? `repos/${fullName}/rulesets`
1310
+ : `repos/${fullName}/rulesets/${id}`;
1276
1311
  const core = {
1277
1312
  schemaVersion: 1,
1278
1313
  contract: GITHUB_GOVERNANCE_RULESET_ROLLOUT_CONTRACT,
1279
1314
  repository: fullName,
1280
1315
  targetRef: branch,
1281
1316
  rulesetId: id,
1317
+ rulesetName: desired.name,
1318
+ action: creating ? "create" : "update",
1282
1319
  inventoryRoot: githubGovernanceDigest(inventory),
1283
- rollbackSnapshotRoot: githubGovernanceDigest(before),
1284
- operations: [{ method: "PUT", endpoint, body: desired }],
1320
+ rollbackSnapshotRoot: creating
1321
+ ? githubGovernanceDigest({ rulesetExists: false, targetRef: branch })
1322
+ : githubGovernanceDigest(before),
1323
+ operations: [
1324
+ { method: creating ? "POST" : "PUT", endpoint, body: desired },
1325
+ ],
1285
1326
  impact: [
1286
1327
  "replace ruleset bypass actors with the exact provider-admitted desired set",
1287
1328
  "require fresh Code Owner review and resolved review threads",
1288
1329
  "bind required status checks and strictness to the authoritative target descriptor",
1289
- "preserve unrelated ruleset rules and exact target conditions",
1330
+ creating
1331
+ ? "create one exact-branch active ruleset because no matching ruleset exists"
1332
+ : "preserve unrelated ruleset rules and exact target conditions",
1290
1333
  ],
1291
1334
  expectedObservation: {
1292
1335
  rulesetRoot: githubGovernanceDigest(desired),
@@ -1296,12 +1339,24 @@ export function createGithubRulesetGovernanceRolloutPlan({
1296
1339
  desiredProtection?.strictRequiredChecks === true,
1297
1340
  requiredApprovals,
1298
1341
  },
1299
- rollback: [{
1300
- method: "PUT",
1301
- endpoint,
1302
- body: before,
1303
- preconditionRoot: githubGovernanceDigest(before),
1304
- }],
1342
+ rollback: creating
1343
+ ? [
1344
+ {
1345
+ method: "DELETE",
1346
+ endpoint: `repos/${fullName}/rulesets/{ruleset_id}`,
1347
+ body: null,
1348
+ preconditionRoot: githubGovernanceDigest(desired),
1349
+ requiresApplyReceipt: true,
1350
+ },
1351
+ ]
1352
+ : [
1353
+ {
1354
+ method: "PUT",
1355
+ endpoint,
1356
+ body: before,
1357
+ preconditionRoot: githubGovernanceDigest(before),
1358
+ },
1359
+ ],
1305
1360
  };
1306
1361
  return { ...core, planRoot: githubGovernanceDigest(core) };
1307
1362
  }
@@ -64,6 +64,16 @@ export {
64
64
  verifyPortableDevCachePlan,
65
65
  } from "./portable-dev-cache.js";
66
66
 
67
+ export {
68
+ BUILDCHAIN_CACHE_EVIDENCE_SET_CONTRACT,
69
+ BUILDCHAIN_CACHE_OPERATION_RECEIPT_CONTRACT,
70
+ cacheEvidenceDigest,
71
+ createCacheEvidenceSet,
72
+ createCacheOperationReceipt,
73
+ verifyCacheEvidenceSet,
74
+ verifyCacheOperationReceipt,
75
+ } from "./cache-evidence.js";
76
+
67
77
  export {
68
78
  explainReleaseLineDryRun,
69
79
  formatReleaseLineDryRun,
@@ -370,6 +380,23 @@ export {
370
380
  testKfdAgentHub,
371
381
  } from "./kfd-agent-hub.js";
372
382
 
383
+ export {
384
+ KFD_PRODUCT_GATE_CONTRACT,
385
+ KFD_PRODUCT_GATE_INPUT_CONTRACT,
386
+ KFD_PRODUCT_GATE_INPUT_SCHEMA,
387
+ KFD_PRODUCT_GATE_INPUT_SCHEMA_ID,
388
+ KFD_SUPPORT_PROJECTION_CONTRACT,
389
+ KFD_SUPPORT_PROJECTION_SCHEMA,
390
+ KFD_SUPPORT_PROJECTION_SCHEMA_ID,
391
+ createKfdSupportProjection,
392
+ evaluateKfdProductGate,
393
+ kfdProductGateDigest,
394
+ kfdProductGates,
395
+ validateKfdProductGateResult,
396
+ validateKfdSupportProjection,
397
+ verifyKfdRecord,
398
+ } from "./kfd-product-gates.js";
399
+
373
400
  export {
374
401
  RELEASE_PASSPORT_CHECK_MANIFEST_CONTRACT,
375
402
  RELEASE_PASSPORT_SCHEMA,