@kungfu-tech/buildchain 4.0.1-alpha.5 → 4.0.1-alpha.55
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/README.md +9 -6
- package/actions/release-tail/README.md +8 -0
- package/actions/v4-release-candidate-promote/README.md +3 -0
- package/architecture/agent-change-map.md +1015 -0
- package/architecture/ci-lane-change-budget.json +256 -0
- package/architecture/decisions/0004-v4-declarative-release-tail.md +47 -0
- package/architecture/internal-capabilities.json +220 -15
- package/architecture/maintainability-debt.json +3229 -0
- package/architecture/maintainability-policy.json +489 -132
- package/architecture/release-tail-contract-inventory.json +5 -2
- package/architecture/v3-core-mechanism-inventory.json +4 -3
- package/architecture/v3-v4-capability-closure.md +59 -0
- package/architecture/v3-v4-live-capability-inventory.json +102404 -0
- package/architecture/v4-adopter-delivery-parity.json +32 -5
- package/architecture/v4-cross-platform-adopter-qualification.json +52 -0
- package/architecture/v4-delivery-warrant-shadow-fixtures.json +3 -3
- package/architecture/v4-floating-consumer-policy.json +6 -0
- package/architecture/v4-publication-rehearsal-parity.json +84 -0
- package/architecture/v4-runtime-semantic-closure.json +710 -0
- package/bin/buildchain.mjs +7 -1
- package/bin/internal/adopter-delivery-cli.mjs +70 -0
- package/bin/internal/command-registry.mjs +1 -0
- package/bin/internal/trust-release-release-handlers.mjs +5 -0
- package/contracts/fixtures/v4-adopter-delivery-v1/archive-template.json +19 -0
- package/contracts/fixtures/v4-adopter-delivery-v1/bootstrap-positive.json +93 -0
- package/contracts/fixtures/v4-adopter-delivery-v1/gate-positive.json +29 -0
- package/contracts/fixtures/v4-adopter-delivery-v1/gate-unknown-selector.json +26 -0
- package/contracts/fixtures/v4-adopter-delivery-v1/offline-vectors.json +50 -0
- package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/artifacts/product.bin +1 -0
- package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/config/buildchain.toml +5 -0
- package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/documents/release-activation.json +1 -0
- package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/documents/signed-channel.json +1 -0
- package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/evidence/qualification.json +1 -0
- package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/manifests/candidate.json +5 -0
- package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/manifests/release-passport.json +1 -0
- package/contracts/fixtures/v4-publication-rehearsal-v1/capsule.json +707 -0
- package/contracts/fixtures/v4-publication-rehearsal-v1/offline-vectors.json +27 -0
- package/contracts/fixtures/v4-tail-reseal-v1/valid.json +1 -1
- package/contracts/v4-adopter-delivery-v1.schema.json +81 -0
- package/contracts/v4-floating-consumer-policy-receipt-v1.schema.json +4 -2
- package/contracts/v4-publication-qualification-v1.schema.json +51 -0
- package/contracts/v4-publication-rehearsal-capsule-v1.schema.json +233 -0
- package/dist/site/agent-index.json +4 -0
- package/dist/site/artifact-schemas.json +8 -0
- package/dist/site/buildchain-contract.json +125 -34
- package/dist/site/buildchain-site.json +308 -33
- package/dist/site/capability-registry.json +13 -12
- package/dist/site/cli-registry.json +57 -2
- package/dist/site/controller-registry.json +41 -5
- package/dist/site/kfd-claims.json +438 -24
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +22 -7
- package/dist/site/node-api-registry.json +12843 -9314
- package/dist/site/page-registry.json +288 -21
- package/dist/site/public-surface-audit.json +281 -21
- package/dist/site/publication-authority-registry.json +66 -8
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/release-provenance.json +20 -0
- package/dist/site/schemas/release-tail-capabilities-v1.schema.json +199 -0
- package/dist/site/schemas/v4-adopter-delivery-v1.schema.json +81 -0
- package/dist/site/schemas/v4-publication-qualification-v1.schema.json +51 -0
- package/dist/site/schemas/v4-publication-rehearsal-capsule-v1.schema.json +233 -0
- package/dist/site/site-manifest.json +19 -11
- package/dist/site/workflow-registry.json +195 -17
- package/docs/MAP.md +4 -2
- package/docs/cli-reference.md +70 -2
- package/docs/cli.md +8 -0
- package/docs/dev-delivery-warrant.md +34 -10
- package/docs/node-api-reference.md +524 -279
- package/docs/publish-transaction.md +11 -4
- package/docs/release-candidate.md +7 -0
- package/docs/release-tail-provider-plane.md +30 -0
- package/docs/v4-adopter-delivery.md +152 -0
- package/docs/v4-declarative-release-tail-migration.md +43 -0
- package/docs/v4-publication-rehearsal.md +130 -0
- package/package.json +24 -4
- package/packages/core/adopter-delivery-passport.js +295 -0
- package/packages/core/adopter-delivery-vectors.js +158 -0
- package/packages/core/adopter-delivery-vectors.json +77 -0
- package/packages/core/buildchain-agent-manuals.js +1 -0
- package/packages/core/buildchain-config.js +84 -0
- package/packages/core/buildchain-contract.js +31 -1
- package/packages/core/buildchain-delivery-bootstrap.js +240 -0
- package/packages/core/buildchain-delivery-infrastructure.js +164 -0
- package/packages/core/buildchain-delivery-self-dogfood.js +395 -0
- package/packages/core/buildchain-publication-authority.js +2 -0
- package/packages/core/ci-lane-change-budget.js +247 -0
- package/packages/core/dev-delivery-native-proof.js +43 -27
- package/packages/core/dev-delivery-warrant-settlement.js +239 -3
- package/packages/core/dev-delivery-warrant-state.js +46 -10
- package/packages/core/dev-delivery-warrant.js +29 -7
- package/packages/core/github-governance-authority.js +5 -4
- package/packages/core/index.js +6 -0
- package/packages/core/legacy-kfd-adopter-driver.js +167 -0
- package/packages/core/paper-scaffold-content.js +401 -0
- package/packages/core/paper.js +12 -378
- package/packages/core/publication-control-plane-audit.js +135 -111
- package/packages/core/publication-rehearsal-projection.js +104 -0
- package/packages/core/publication-rehearsal-runtime.js +190 -0
- package/packages/core/published-delivery-authority.js +266 -0
- package/packages/core/release-candidate-recovery.js +71 -15
- package/packages/core/release-candidate.js +2 -2
- package/packages/core/release-passport.js +95 -170
- package/packages/core/v4-adopter-delivery-parity.js +3 -3
- package/packages/core/v4-adopter-delivery.js +359 -0
- package/packages/core/v4-cross-platform-adopter-qualification.js +343 -0
- package/packages/core/v4-delivery-warrant-read-candidate.js +10 -3
- package/packages/core/v4-floating-consumer-evidence.js +18 -4
- package/packages/core/v4-floating-consumer-policy.js +139 -35
- package/packages/core/v4-floating-consumer-release-passport.js +154 -8
- package/packages/core/v4-publication-qualification.js +222 -0
- package/packages/core/v4-publication-rehearsal-capsule.js +468 -0
- package/packages/core/v4-publication-rehearsal-provider-bindings.js +212 -0
- package/packages/core/v4-publication-rehearsal.js +481 -0
- package/packages/core/workflow-yaml-contract.js +24 -2
- package/scripts/artifact-signing-controller-core.mjs +1 -1
- package/scripts/audit-publication-control-plane.mjs +17 -17
- package/scripts/buildchain-cli-help.mjs +13 -0
- package/scripts/check-ci-lane-change-budget.mjs +100 -0
- package/scripts/check-internal-architecture.mjs +23 -3
- package/scripts/check-inventory.mjs +24 -6
- package/scripts/check-maintainability.mjs +145 -4
- package/scripts/check-project-cut-merge-queue-admission.mjs +87 -0
- package/scripts/check-v3-v4-capability-inventory.mjs +574 -0
- package/scripts/check-v4-floating-consumer-policy-contract.mjs +30 -4
- package/scripts/check-v4-runtime-semantic-closure.mjs +266 -0
- package/scripts/dev-delivery-source-proof-replay.mjs +153 -0
- package/scripts/dev-delivery-source-proof-reuse.mjs +13 -97
- package/scripts/dev-delivery-warrant-options.mjs +27 -11
- package/scripts/dev-delivery-warrant-store.mjs +10 -6
- package/scripts/dev-delivery-warrant.mjs +50 -6
- package/scripts/dev-pr-auto-merge.mjs +25 -11
- package/scripts/dev-pr-delivery-warrant.mjs +45 -0
- package/scripts/dev-pr-prequeue-guard.mjs +0 -18
- package/scripts/dev-qualification-patrol.mjs +9 -9
- package/scripts/dispatch-artifact-signing-authority.mjs +1 -1
- package/scripts/generate-agent-change-map.mjs +118 -0
- package/scripts/generate-channel-promotion-workflow.mjs +2 -2
- package/scripts/generate-release-candidate-passport.mjs +177 -0
- package/scripts/generate-site-bundle.mjs +36 -0
- package/scripts/maintainability-domain-metrics.mjs +237 -0
- package/scripts/maintainability-governance.mjs +473 -0
- package/scripts/maintainability-metrics.mjs +28 -6
- package/scripts/project-cut-merge-queue-admission.mjs +394 -0
- package/scripts/promotion-channel-router.mjs +4 -4
- package/scripts/promotion-routing-evidence.mjs +35 -6
- package/scripts/release-candidate-anchor-provenance.mjs +99 -0
- package/scripts/release-candidate-resolver.mjs +44 -0
- package/scripts/release-line-policy.mjs +25 -15
- package/scripts/release-tail.mjs +68 -3
- package/scripts/resume-from-candidate-run.mjs +595 -65
- package/scripts/run-lifecycle-core.mjs +341 -376
- package/scripts/site-capability-metadata.mjs +21 -0
- package/scripts/stable-candidate-qualification.mjs +9 -10
- package/scripts/v3-v4-capability-catalog.mjs +439 -0
- package/scripts/v4-consumer-policy.mjs +4 -0
- package/scripts/v4-cross-platform-adopter-qualification.mjs +228 -0
- package/scripts/v4-declarative-promotion-admission.mjs +42 -0
- package/scripts/v4-publication-rehearsal-fixture.mjs +144 -0
|
@@ -35,9 +35,13 @@ import {
|
|
|
35
35
|
} from "./github-artifact-attestation.js";
|
|
36
36
|
import { verifyV4FloatingConsumerPolicyCertification } from "./v4-floating-consumer-evidence.js";
|
|
37
37
|
import {
|
|
38
|
+
normalizePromotionEvidence,
|
|
39
|
+
normalizePromotionRouting,
|
|
40
|
+
normalizeV4RuntimeResumeEvidence,
|
|
38
41
|
isV4PromotionRouting,
|
|
39
42
|
releasePassportCertificationVerificationOptions,
|
|
40
43
|
requireV4ConsumerPolicyCertification,
|
|
44
|
+
resolveV4ConsumerPolicyCertificationIdentity,
|
|
41
45
|
} from "./v4-floating-consumer-release-passport.js";
|
|
42
46
|
import {
|
|
43
47
|
verifyV4RuntimeAuthorizationReceipt,
|
|
@@ -400,13 +404,6 @@ function parseJsonInputWithMeta(value, fallback = undefined, { cwd = process.cwd
|
|
|
400
404
|
};
|
|
401
405
|
}
|
|
402
406
|
|
|
403
|
-
function parseV4ConsumerPolicyCertification(input, cwd) {
|
|
404
|
-
return parseJsonInputWithMeta(input, undefined, {
|
|
405
|
-
cwd,
|
|
406
|
-
label: "v4ConsumerPolicyCertificationJson",
|
|
407
|
-
});
|
|
408
|
-
}
|
|
409
|
-
|
|
410
407
|
function mergeAuthoritativePassportBase(passport, basePassport = undefined, { requireKfd = false } = {}) {
|
|
411
408
|
if (!basePassport) {
|
|
412
409
|
if (requireKfd) {
|
|
@@ -439,11 +436,17 @@ function mergeAuthoritativePassportBase(passport, basePassport = undefined, { re
|
|
|
439
436
|
kfd3: basePassport.evidence?.kfd3 || passport.evidence?.kfd3 || "",
|
|
440
437
|
},
|
|
441
438
|
};
|
|
442
|
-
for (const key of [
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
439
|
+
for (const key of [
|
|
440
|
+
"versionImpact",
|
|
441
|
+
"surfaceImpacts",
|
|
442
|
+
"promotionRouting",
|
|
443
|
+
"v4ConsumerPolicy",
|
|
444
|
+
"v4RuntimeResume",
|
|
445
|
+
"transaction",
|
|
446
|
+
"trustedPublishing",
|
|
447
|
+
"distTagPromotion",
|
|
448
|
+
])
|
|
449
|
+
if (basePassport[key] !== undefined) merged[key] = basePassport[key];
|
|
447
450
|
if (basePassport.controllerReceipts !== undefined) {
|
|
448
451
|
merged.controllerReceipts = basePassport.controllerReceipts;
|
|
449
452
|
}
|
|
@@ -1065,103 +1068,6 @@ function normalizeTransaction(value = undefined) {
|
|
|
1065
1068
|
};
|
|
1066
1069
|
}
|
|
1067
1070
|
|
|
1068
|
-
function normalizePromotionRouting(value = undefined) {
|
|
1069
|
-
if (value === undefined) return undefined;
|
|
1070
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
1071
|
-
throw new Error("release.promotionRouting must be a JSON object");
|
|
1072
|
-
}
|
|
1073
|
-
if (value.contract !== "buildchain.promotion-routing/v1") {
|
|
1074
|
-
throw new Error("release.promotionRouting contract must be buildchain.promotion-routing/v1");
|
|
1075
|
-
}
|
|
1076
|
-
for (const [label, field] of [
|
|
1077
|
-
["router.ref", value.router?.ref],
|
|
1078
|
-
["router.sha", value.router?.sha],
|
|
1079
|
-
["shell.ref", value.shell?.ref],
|
|
1080
|
-
["shell.sha", value.shell?.sha],
|
|
1081
|
-
["runtime.requestedRef", value.runtime?.requestedRef],
|
|
1082
|
-
["runtime.resolvedSha", value.runtime?.resolvedSha],
|
|
1083
|
-
["contractLock.path", value.contractLock?.path],
|
|
1084
|
-
["contractLock.digest", value.contractLock?.digest],
|
|
1085
|
-
["publication.channel", value.publication?.channel],
|
|
1086
|
-
["publication.targetRef", value.publication?.targetRef],
|
|
1087
|
-
]) {
|
|
1088
|
-
if (!String(field || "").trim()) throw new Error(`release.promotionRouting.${label} is required`);
|
|
1089
|
-
}
|
|
1090
|
-
for (const [label, sha] of [
|
|
1091
|
-
["router.sha", value.router.sha],
|
|
1092
|
-
["shell.sha", value.shell.sha],
|
|
1093
|
-
["runtime.resolvedSha", value.runtime.resolvedSha],
|
|
1094
|
-
]) {
|
|
1095
|
-
if (!/^[0-9a-f]{40}$/i.test(String(sha))) {
|
|
1096
|
-
throw new Error(`release.promotionRouting.${label} must be a 40-character Git SHA`);
|
|
1097
|
-
}
|
|
1098
|
-
}
|
|
1099
|
-
if (!/^sha256:[0-9a-f]{64}$/i.test(String(value.contractLock.digest))) {
|
|
1100
|
-
throw new Error("release.promotionRouting.contractLock.digest must be a sha256 digest");
|
|
1101
|
-
}
|
|
1102
|
-
return JSON.parse(JSON.stringify(value));
|
|
1103
|
-
}
|
|
1104
|
-
|
|
1105
|
-
function normalizePromotionEvidence({
|
|
1106
|
-
release = {},
|
|
1107
|
-
v4ConsumerPolicyCertification: certification,
|
|
1108
|
-
v4ConsumerPolicyCertificationRoot: certificationRoot,
|
|
1109
|
-
repository,
|
|
1110
|
-
sourceSha,
|
|
1111
|
-
cwd,
|
|
1112
|
-
}) {
|
|
1113
|
-
const routing = normalizePromotionRouting(release.promotionRouting);
|
|
1114
|
-
return {
|
|
1115
|
-
routing,
|
|
1116
|
-
consumerPolicy: requireV4ConsumerPolicyCertification({
|
|
1117
|
-
value: certification,
|
|
1118
|
-
repository,
|
|
1119
|
-
sourceSha,
|
|
1120
|
-
routing,
|
|
1121
|
-
cwd,
|
|
1122
|
-
certificationRoot,
|
|
1123
|
-
}),
|
|
1124
|
-
};
|
|
1125
|
-
}
|
|
1126
|
-
|
|
1127
|
-
function normalizeV4RuntimeResumeEvidence(value, expected = {}) {
|
|
1128
|
-
if (value === undefined || value === null || value === "") return undefined;
|
|
1129
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
1130
|
-
throw new Error("v4RuntimeResumeEvidence must be a JSON object");
|
|
1131
|
-
}
|
|
1132
|
-
const authorizationVerification = verifyV4RuntimeAuthorizationReceipt({
|
|
1133
|
-
receipt: value.authorization,
|
|
1134
|
-
receiptRoot: value.authorizationRoot,
|
|
1135
|
-
repository: expected.repository,
|
|
1136
|
-
sourceSha: expected.sourceSha,
|
|
1137
|
-
runtimeSha: expected.resumeRuntimeSha,
|
|
1138
|
-
consumerPolicyReceiptRoot: expected.consumerPolicyReceiptRoot,
|
|
1139
|
-
});
|
|
1140
|
-
if (!authorizationVerification.ok) {
|
|
1141
|
-
throw new Error(`v4 runtime authorization invalid: ${authorizationVerification.failures.join(", ")}`);
|
|
1142
|
-
}
|
|
1143
|
-
const lineageVerification = verifyV4RuntimeResumeLineage({
|
|
1144
|
-
lineage: value.lineage,
|
|
1145
|
-
lineageRoot: value.lineageRoot,
|
|
1146
|
-
repository: expected.repository,
|
|
1147
|
-
sourceSha: expected.sourceSha,
|
|
1148
|
-
resumeRuntimeSha: expected.resumeRuntimeSha,
|
|
1149
|
-
consumerPolicyReceiptRoot: expected.consumerPolicyReceiptRoot,
|
|
1150
|
-
});
|
|
1151
|
-
if (!lineageVerification.ok) {
|
|
1152
|
-
throw new Error(`v4 runtime resume lineage invalid: ${lineageVerification.failures.join(", ")}`);
|
|
1153
|
-
}
|
|
1154
|
-
if (value.lineage?.authorizationRoot !== value.authorizationRoot) {
|
|
1155
|
-
throw new Error("v4 runtime resume lineage authorization root mismatch");
|
|
1156
|
-
}
|
|
1157
|
-
return {
|
|
1158
|
-
authorizationRoot: value.authorizationRoot,
|
|
1159
|
-
authorization: structuredClone(value.authorization),
|
|
1160
|
-
lineageRoot: value.lineageRoot,
|
|
1161
|
-
lineage: structuredClone(value.lineage),
|
|
1162
|
-
};
|
|
1163
|
-
}
|
|
1164
|
-
|
|
1165
1071
|
function prepareBuildEvidence({
|
|
1166
1072
|
buildSummary,
|
|
1167
1073
|
buildFacts,
|
|
@@ -1235,6 +1141,8 @@ function releaseField(release, camelKey, snakeKey, ...fallbacks) {
|
|
|
1235
1141
|
return optionalString(firstTruthy(release[camelKey], release[snakeKey], ...fallbacks));
|
|
1236
1142
|
}
|
|
1237
1143
|
|
|
1144
|
+
export { releasePassportKfdAdopterSourceSha } from "./adopter-delivery-passport.js";
|
|
1145
|
+
|
|
1238
1146
|
function optionalSections(entries) {
|
|
1239
1147
|
return Object.fromEntries(entries.filter(([, value]) => value && (!Array.isArray(value) || value.length > 0)));
|
|
1240
1148
|
}
|
|
@@ -1317,7 +1225,7 @@ export function createReleasePassport(options = {}) {
|
|
|
1317
1225
|
const { promotion, buildEvidence } = preparePromotionBuild(options);
|
|
1318
1226
|
const normalizedV4RuntimeResume = normalizeV4RuntimeResumeEvidence(v4RuntimeResumeEvidence, {
|
|
1319
1227
|
repository,
|
|
1320
|
-
sourceSha,
|
|
1228
|
+
sourceSha: v4RuntimeResumeSourceSha(release, sourceSha),
|
|
1321
1229
|
resumeRuntimeSha: promotion.routing?.runtime?.resolvedSha || "",
|
|
1322
1230
|
consumerPolicyReceiptRoot: promotion.consumerPolicy?.certification?.receiptRoot || "",
|
|
1323
1231
|
});
|
|
@@ -1862,7 +1770,6 @@ export function collectGitHubReleasePassport({
|
|
|
1862
1770
|
function issue(level, code, message, details = {}) {
|
|
1863
1771
|
return { level, code, message, details };
|
|
1864
1772
|
}
|
|
1865
|
-
|
|
1866
1773
|
function validateContract(value, expectedContract, label, issues) {
|
|
1867
1774
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
1868
1775
|
issues.push(issue("error", `${label}.object`, `${label} must be a JSON object`));
|
|
@@ -2270,65 +2177,6 @@ function validateReleaseEvidenceAttachments({
|
|
|
2270
2177
|
return { evidenceArtifacts, releaseEvidence };
|
|
2271
2178
|
}
|
|
2272
2179
|
|
|
2273
|
-
function validateV4ConsumerPolicyPassportSection({ passport, issues }) {
|
|
2274
|
-
const routing = passport?.promotionRouting;
|
|
2275
|
-
const evidence = passport?.v4ConsumerPolicy;
|
|
2276
|
-
if (isV4PromotionRouting(routing) && !evidence) {
|
|
2277
|
-
issues.push(issue(
|
|
2278
|
-
"error",
|
|
2279
|
-
"v4ConsumerPolicy.missing",
|
|
2280
|
-
"Buildchain v4 Release Passport requires an external floating consumer policy certification",
|
|
2281
|
-
));
|
|
2282
|
-
return;
|
|
2283
|
-
}
|
|
2284
|
-
if (!evidence) return;
|
|
2285
|
-
const verification = verifyV4FloatingConsumerPolicyCertification(
|
|
2286
|
-
releasePassportCertificationVerificationOptions({
|
|
2287
|
-
evidence,
|
|
2288
|
-
passport,
|
|
2289
|
-
routing,
|
|
2290
|
-
}),
|
|
2291
|
-
);
|
|
2292
|
-
for (const failure of verification.failures) {
|
|
2293
|
-
issues.push(issue("error", `v4ConsumerPolicy.${failure.code}`, failure.message));
|
|
2294
|
-
}
|
|
2295
|
-
}
|
|
2296
|
-
|
|
2297
|
-
function validateV4RuntimeResumePassportSection({ passport, issues }) {
|
|
2298
|
-
const evidence = passport?.v4RuntimeResume;
|
|
2299
|
-
if (!evidence) return;
|
|
2300
|
-
const consumerPolicyReceiptRoot = passport?.v4ConsumerPolicy?.certification?.receiptRoot || "";
|
|
2301
|
-
const authorization = verifyV4RuntimeAuthorizationReceipt({
|
|
2302
|
-
receipt: evidence.authorization,
|
|
2303
|
-
receiptRoot: evidence.authorizationRoot,
|
|
2304
|
-
repository: passport?.product?.repository || "",
|
|
2305
|
-
sourceSha: passport?.release?.sourceSha || "",
|
|
2306
|
-
runtimeSha: passport?.promotionRouting?.runtime?.resolvedSha || "",
|
|
2307
|
-
consumerPolicyReceiptRoot,
|
|
2308
|
-
});
|
|
2309
|
-
for (const failure of authorization.failures) {
|
|
2310
|
-
issues.push(issue("error", `v4RuntimeResume.authorization.${failure}`, failure));
|
|
2311
|
-
}
|
|
2312
|
-
const lineage = verifyV4RuntimeResumeLineage({
|
|
2313
|
-
lineage: evidence.lineage,
|
|
2314
|
-
lineageRoot: evidence.lineageRoot,
|
|
2315
|
-
repository: passport?.product?.repository || "",
|
|
2316
|
-
sourceSha: passport?.release?.sourceSha || "",
|
|
2317
|
-
resumeRuntimeSha: passport?.promotionRouting?.runtime?.resolvedSha || "",
|
|
2318
|
-
consumerPolicyReceiptRoot,
|
|
2319
|
-
});
|
|
2320
|
-
for (const failure of lineage.failures) {
|
|
2321
|
-
issues.push(issue("error", `v4RuntimeResume.lineage.${failure}`, failure));
|
|
2322
|
-
}
|
|
2323
|
-
if (evidence.lineage?.authorizationRoot !== evidence.authorizationRoot) {
|
|
2324
|
-
issues.push(issue(
|
|
2325
|
-
"error",
|
|
2326
|
-
"v4RuntimeResume.authorization-root-mismatch",
|
|
2327
|
-
"runtime resume lineage must bind the embedded authorization receipt root",
|
|
2328
|
-
));
|
|
2329
|
-
}
|
|
2330
|
-
}
|
|
2331
|
-
|
|
2332
2180
|
function validatePublishEvidenceSection({ passport, publishEvidence, normalizedPublishEvidence, issues }) {
|
|
2333
2181
|
const publishEvidenceSupplied =
|
|
2334
2182
|
Boolean(passport?.evidence?.publishEvidence) ||
|
|
@@ -2956,3 +2804,80 @@ export function makeReleasePassportFixtureAssets(dir) {
|
|
|
2956
2804
|
export function validateKnownReleasePassportContracts() {
|
|
2957
2805
|
return [...CONTRACTS];
|
|
2958
2806
|
}
|
|
2807
|
+
function parseV4ConsumerPolicyCertification(input, cwd) {
|
|
2808
|
+
return parseJsonInputWithMeta(input, undefined, {
|
|
2809
|
+
cwd,
|
|
2810
|
+
label: "v4ConsumerPolicyCertificationJson",
|
|
2811
|
+
});
|
|
2812
|
+
}
|
|
2813
|
+
|
|
2814
|
+
function v4RuntimeResumeSourceSha(release, fallback = "") {
|
|
2815
|
+
const builtSourceSha = releaseField(
|
|
2816
|
+
release || {},
|
|
2817
|
+
"builtSourceSha",
|
|
2818
|
+
"built_source_sha",
|
|
2819
|
+
);
|
|
2820
|
+
return release?.treeEquivalent === true && builtSourceSha
|
|
2821
|
+
? builtSourceSha
|
|
2822
|
+
: fallback;
|
|
2823
|
+
}
|
|
2824
|
+
|
|
2825
|
+
|
|
2826
|
+
function validateV4ConsumerPolicyPassportSection({ passport, issues }) {
|
|
2827
|
+
const routing = passport?.promotionRouting;
|
|
2828
|
+
const evidence = passport?.v4ConsumerPolicy;
|
|
2829
|
+
if (isV4PromotionRouting(routing) && !evidence) {
|
|
2830
|
+
issues.push(issue(
|
|
2831
|
+
"error",
|
|
2832
|
+
"v4ConsumerPolicy.missing",
|
|
2833
|
+
"Buildchain v4 Release Passport requires an external floating consumer policy certification",
|
|
2834
|
+
));
|
|
2835
|
+
return;
|
|
2836
|
+
}
|
|
2837
|
+
if (!evidence) return;
|
|
2838
|
+
const verification = verifyV4FloatingConsumerPolicyCertification(
|
|
2839
|
+
releasePassportCertificationVerificationOptions({
|
|
2840
|
+
evidence,
|
|
2841
|
+
passport,
|
|
2842
|
+
routing,
|
|
2843
|
+
}),
|
|
2844
|
+
);
|
|
2845
|
+
for (const failure of verification.failures) {
|
|
2846
|
+
issues.push(issue("error", `v4ConsumerPolicy.${failure.code}`, failure.message));
|
|
2847
|
+
}
|
|
2848
|
+
}
|
|
2849
|
+
|
|
2850
|
+
function validateV4RuntimeResumePassportSection({ passport, issues }) {
|
|
2851
|
+
const evidence = passport?.v4RuntimeResume;
|
|
2852
|
+
if (!evidence) return;
|
|
2853
|
+
const consumerPolicyReceiptRoot = passport?.v4ConsumerPolicy?.certification?.receiptRoot || "";
|
|
2854
|
+
const authorization = verifyV4RuntimeAuthorizationReceipt({
|
|
2855
|
+
receipt: evidence.authorization,
|
|
2856
|
+
receiptRoot: evidence.authorizationRoot,
|
|
2857
|
+
repository: passport?.product?.repository || "",
|
|
2858
|
+
sourceSha: v4RuntimeResumeSourceSha(passport?.release, passport?.release?.sourceSha || ""),
|
|
2859
|
+
runtimeSha: passport?.promotionRouting?.runtime?.resolvedSha || "",
|
|
2860
|
+
consumerPolicyReceiptRoot,
|
|
2861
|
+
});
|
|
2862
|
+
for (const failure of authorization.failures) {
|
|
2863
|
+
issues.push(issue("error", `v4RuntimeResume.authorization.${failure}`, failure));
|
|
2864
|
+
}
|
|
2865
|
+
const lineage = verifyV4RuntimeResumeLineage({
|
|
2866
|
+
lineage: evidence.lineage,
|
|
2867
|
+
lineageRoot: evidence.lineageRoot,
|
|
2868
|
+
repository: passport?.product?.repository || "",
|
|
2869
|
+
sourceSha: v4RuntimeResumeSourceSha(passport?.release, passport?.release?.sourceSha || ""),
|
|
2870
|
+
resumeRuntimeSha: passport?.promotionRouting?.runtime?.resolvedSha || "",
|
|
2871
|
+
consumerPolicyReceiptRoot,
|
|
2872
|
+
});
|
|
2873
|
+
for (const failure of lineage.failures) {
|
|
2874
|
+
issues.push(issue("error", `v4RuntimeResume.lineage.${failure}`, failure));
|
|
2875
|
+
}
|
|
2876
|
+
if (evidence.lineage?.authorizationRoot !== evidence.authorizationRoot) {
|
|
2877
|
+
issues.push(issue(
|
|
2878
|
+
"error",
|
|
2879
|
+
"v4RuntimeResume.authorization-root-mismatch",
|
|
2880
|
+
"runtime resume lineage must bind the embedded authorization receipt root",
|
|
2881
|
+
));
|
|
2882
|
+
}
|
|
2883
|
+
}
|
|
@@ -31,10 +31,10 @@ const root = path.resolve(
|
|
|
31
31
|
);
|
|
32
32
|
|
|
33
33
|
export const V4_ADOPTER_DELIVERY_PARITY_SOURCE = Object.freeze({
|
|
34
|
-
v3Commit: "
|
|
34
|
+
v3Commit: "6b96bdad8d9f8ccf9275f27d9370a226a9c78465",
|
|
35
35
|
vectorSuiteRoot:
|
|
36
|
-
"sha256:
|
|
37
|
-
kfdPackage: "@kungfu-tech/kfd@1.0.0-alpha.
|
|
36
|
+
"sha256:c978707556406ffda4ef4192032332c01c2da1cebb6ad8c4f0edfc65d5cef0c7",
|
|
37
|
+
kfdPackage: "@kungfu-tech/kfd@1.0.0-alpha.65",
|
|
38
38
|
});
|
|
39
39
|
|
|
40
40
|
function clone(value) {
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
import {
|
|
2
|
+
adopterDeliveryGateDigest,
|
|
3
|
+
createAdopterDeliveryGate,
|
|
4
|
+
createGitCommitArtifactProfile,
|
|
5
|
+
createPackageArtifactProfile,
|
|
6
|
+
defineAdopterProtocolDriver,
|
|
7
|
+
ADOPTER_PROTOCOL_DRIVER_INTERFACE,
|
|
8
|
+
} from "./adopter-delivery-gate.js";
|
|
9
|
+
import { qualifyBuildchainDeliveryInfrastructureBootstrap } from "./buildchain-delivery-bootstrap.js";
|
|
10
|
+
import { createKfdAdopterCategoryProtocolDriver } from "./kfd-adopter-category-driver.js";
|
|
11
|
+
import { createLegacyKfdAdopterProtocolDriver } from "./legacy-kfd-adopter-driver.js";
|
|
12
|
+
import { loadPublishedBuildchainDeliveryAuthority } from "./published-delivery-authority.js";
|
|
13
|
+
|
|
14
|
+
export const V4_ADOPTER_DELIVERY_CONTRACT =
|
|
15
|
+
"kungfu-buildchain-v4-adopter-delivery/v1";
|
|
16
|
+
export const V4_ADOPTER_DELIVERY_READBACK_CONTRACT =
|
|
17
|
+
"kungfu-buildchain-v4-adopter-delivery-readback/v1";
|
|
18
|
+
export const V4_ADOPTER_DELIVERY_BOOTSTRAP_LINEAGE_CONTRACT =
|
|
19
|
+
"kungfu-buildchain-v4-adopter-delivery-bootstrap-lineage/v1";
|
|
20
|
+
export const V4_ADOPTER_DELIVERY_SOURCE = Object.freeze({
|
|
21
|
+
branch: "dev/v3/v3.0",
|
|
22
|
+
commit: "6b96bdad8d9f8ccf9275f27d9370a226a9c78465",
|
|
23
|
+
vectorSuiteRoot:
|
|
24
|
+
"sha256:c978707556406ffda4ef4192032332c01c2da1cebb6ad8c4f0edfc65d5cef0c7",
|
|
25
|
+
kfdPackage: "@kungfu-tech/kfd@1.0.0-alpha.65",
|
|
26
|
+
targetBranch: "dev/v4/v4.0",
|
|
27
|
+
initialTargetBase: "e5611377efc03178f8687d99968cfdfa3ce2825b",
|
|
28
|
+
targetBase: "e0342713c7447960c13bd73377282b2e93f4853d",
|
|
29
|
+
});
|
|
30
|
+
export const V4_ADOPTER_DELIVERY_ARCHIVE_AUTHORITY = Object.freeze({
|
|
31
|
+
buildchain: Object.freeze({
|
|
32
|
+
name: "@kungfu-tech/buildchain",
|
|
33
|
+
version: "3.0.9-alpha.16",
|
|
34
|
+
archiveRoot:
|
|
35
|
+
"sha256:3f425e2c77d11f0bee8eb9aa2448566bca7a9d14672a7e528ced3e505b3f14a3",
|
|
36
|
+
artifactRoot:
|
|
37
|
+
"sha256:3f425e2c77d11f0bee8eb9aa2448566bca7a9d14672a7e528ced3e505b3f14a3",
|
|
38
|
+
}),
|
|
39
|
+
kfd: Object.freeze({
|
|
40
|
+
name: "@kungfu-tech/kfd",
|
|
41
|
+
version: "1.0.0-alpha.65",
|
|
42
|
+
archiveRoot:
|
|
43
|
+
"sha256:c4dbd3f954910236d7f0823ea6887f4151e43b871df526ccdd599123421bced2",
|
|
44
|
+
artifactRoot:
|
|
45
|
+
"sha256:c0781bcaf191a58561ae32ee2fbedabbb48ed50b5725c356fbd83704089637f8",
|
|
46
|
+
}),
|
|
47
|
+
authorityRoot:
|
|
48
|
+
"sha256:9ba0cc6042b189ce749d01003617b57bcd03ea6ecf40e96d19e8ecbbfa347134",
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
const ROOT = /^sha256:[0-9a-f]{64}$/u;
|
|
52
|
+
const SHA = /^[0-9a-f]{40}$/u;
|
|
53
|
+
const BUILTIN_DRIVER_SELECTORS = Object.freeze({
|
|
54
|
+
"json-assertion": "buildchain.adopter/json-assertion@1.0.0",
|
|
55
|
+
"kfd-category": "kfd.adopter-category/instance-manifest@1.0.0",
|
|
56
|
+
"legacy-kfd": "buildchain.kfd-adopter/legacy-support-matrix@1.0.0",
|
|
57
|
+
});
|
|
58
|
+
const BUILTIN_PROFILE_SELECTORS = Object.freeze({
|
|
59
|
+
"git-commit": "buildchain.artifact/git-commit@1.0.0",
|
|
60
|
+
package: "buildchain.artifact/package@1.0.0",
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
function exactKeys(value, keys, label) {
|
|
64
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
65
|
+
throw new TypeError(`${label} must be an object`);
|
|
66
|
+
}
|
|
67
|
+
const actual = Object.keys(value).sort();
|
|
68
|
+
const expected = [...keys].sort();
|
|
69
|
+
if (
|
|
70
|
+
actual.length !== expected.length ||
|
|
71
|
+
actual.some((entry, index) => entry !== expected[index])
|
|
72
|
+
) {
|
|
73
|
+
throw new TypeError(`${label} has an unsupported field set`);
|
|
74
|
+
}
|
|
75
|
+
return structuredClone(value);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function definitionKey(value) {
|
|
79
|
+
return `${value.id}@${value.version}`;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function resolveSelector(selector, table, definitions, label) {
|
|
83
|
+
const expected = table[selector];
|
|
84
|
+
if (!expected) throw new RangeError(`unknown ${label} selector: ${selector}`);
|
|
85
|
+
const selected = definitions.find(
|
|
86
|
+
(entry) => definitionKey(entry) === expected,
|
|
87
|
+
);
|
|
88
|
+
if (!selected)
|
|
89
|
+
throw new Error(
|
|
90
|
+
`${label} selector is not backed by an exact implementation`,
|
|
91
|
+
);
|
|
92
|
+
return selected;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function createJsonAssertionAdopterProtocolDriver() {
|
|
96
|
+
return defineAdopterProtocolDriver({
|
|
97
|
+
interface: ADOPTER_PROTOCOL_DRIVER_INTERFACE,
|
|
98
|
+
id: "buildchain.adopter/json-assertion",
|
|
99
|
+
version: "1.0.0",
|
|
100
|
+
verify({ request }) {
|
|
101
|
+
const declaration = request.declaration;
|
|
102
|
+
const exact =
|
|
103
|
+
declaration &&
|
|
104
|
+
typeof declaration === "object" &&
|
|
105
|
+
!Array.isArray(declaration) &&
|
|
106
|
+
Object.keys(declaration).length === 1 &&
|
|
107
|
+
typeof declaration.valid === "boolean";
|
|
108
|
+
const valid = exact && declaration.valid === true;
|
|
109
|
+
const issues = valid
|
|
110
|
+
? []
|
|
111
|
+
: [
|
|
112
|
+
{
|
|
113
|
+
code: "delivery-json-assertion-rejected",
|
|
114
|
+
path: "/declaration",
|
|
115
|
+
message:
|
|
116
|
+
"JSON assertion declarations must contain only valid: true.",
|
|
117
|
+
},
|
|
118
|
+
];
|
|
119
|
+
const report = {
|
|
120
|
+
schemaVersion: 1,
|
|
121
|
+
contract: "kungfu-buildchain-json-assertion-driver-report/v1",
|
|
122
|
+
valid,
|
|
123
|
+
declaration: structuredClone(declaration),
|
|
124
|
+
qualifying: false,
|
|
125
|
+
selfCertified: false,
|
|
126
|
+
releaseAuthorized: false,
|
|
127
|
+
};
|
|
128
|
+
return {
|
|
129
|
+
valid,
|
|
130
|
+
report,
|
|
131
|
+
reportRoot: adopterDeliveryGateDigest(report),
|
|
132
|
+
issues,
|
|
133
|
+
};
|
|
134
|
+
},
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export function createV4AdopterDeliveryRuntime({
|
|
139
|
+
drivers = [],
|
|
140
|
+
artifactProfiles = [],
|
|
141
|
+
} = {}) {
|
|
142
|
+
const allDrivers = [
|
|
143
|
+
createJsonAssertionAdopterProtocolDriver(),
|
|
144
|
+
createKfdAdopterCategoryProtocolDriver(),
|
|
145
|
+
createLegacyKfdAdopterProtocolDriver(),
|
|
146
|
+
...drivers,
|
|
147
|
+
];
|
|
148
|
+
const allProfiles = [
|
|
149
|
+
createGitCommitArtifactProfile(),
|
|
150
|
+
createPackageArtifactProfile(),
|
|
151
|
+
...artifactProfiles,
|
|
152
|
+
];
|
|
153
|
+
return Object.freeze({
|
|
154
|
+
drivers: Object.freeze(allDrivers),
|
|
155
|
+
artifactProfiles: Object.freeze(allProfiles),
|
|
156
|
+
evaluate({
|
|
157
|
+
request,
|
|
158
|
+
context = {},
|
|
159
|
+
driverSelector,
|
|
160
|
+
artifactProfileSelector,
|
|
161
|
+
} = {}) {
|
|
162
|
+
const driver = resolveSelector(
|
|
163
|
+
driverSelector,
|
|
164
|
+
BUILTIN_DRIVER_SELECTORS,
|
|
165
|
+
allDrivers,
|
|
166
|
+
"driver",
|
|
167
|
+
);
|
|
168
|
+
const profile = resolveSelector(
|
|
169
|
+
artifactProfileSelector,
|
|
170
|
+
BUILTIN_PROFILE_SELECTORS,
|
|
171
|
+
allProfiles,
|
|
172
|
+
"artifact profile",
|
|
173
|
+
);
|
|
174
|
+
if (definitionKey(driver) !== definitionKey(request?.protocol ?? {})) {
|
|
175
|
+
throw new Error(
|
|
176
|
+
"driver selector does not match the exact request protocol",
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
if (
|
|
180
|
+
definitionKey(profile) !== definitionKey(request?.artifactProfile ?? {})
|
|
181
|
+
) {
|
|
182
|
+
throw new Error(
|
|
183
|
+
"artifact profile selector does not match the exact request profile",
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
return createAdopterDeliveryGate({
|
|
187
|
+
drivers: [driver],
|
|
188
|
+
artifactProfiles: [profile],
|
|
189
|
+
}).evaluate(structuredClone(request), structuredClone(context));
|
|
190
|
+
},
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export function runV4AdopterDeliveryGate(input, options = {}) {
|
|
195
|
+
const normalized = exactKeys(
|
|
196
|
+
input,
|
|
197
|
+
[
|
|
198
|
+
"schemaVersion",
|
|
199
|
+
"contract",
|
|
200
|
+
"driverSelector",
|
|
201
|
+
"artifactProfileSelector",
|
|
202
|
+
"request",
|
|
203
|
+
"context",
|
|
204
|
+
],
|
|
205
|
+
"v4 adopter delivery input",
|
|
206
|
+
);
|
|
207
|
+
if (
|
|
208
|
+
normalized.schemaVersion !== 1 ||
|
|
209
|
+
normalized.contract !== V4_ADOPTER_DELIVERY_CONTRACT
|
|
210
|
+
) {
|
|
211
|
+
throw new Error("v4 adopter delivery contract or version is unsupported");
|
|
212
|
+
}
|
|
213
|
+
const gateResult =
|
|
214
|
+
createV4AdopterDeliveryRuntime(options).evaluate(normalized);
|
|
215
|
+
const result = {
|
|
216
|
+
schemaVersion: 1,
|
|
217
|
+
contract: V4_ADOPTER_DELIVERY_READBACK_CONTRACT,
|
|
218
|
+
sourceAuthority: structuredClone(V4_ADOPTER_DELIVERY_SOURCE),
|
|
219
|
+
selection: {
|
|
220
|
+
driver: normalized.driverSelector,
|
|
221
|
+
artifactProfile: normalized.artifactProfileSelector,
|
|
222
|
+
},
|
|
223
|
+
gateResult,
|
|
224
|
+
qualifying: false,
|
|
225
|
+
selfCertified: false,
|
|
226
|
+
releaseAuthorized: false,
|
|
227
|
+
finalAuthority: "selected-public-driver-plus-exact-consumer-readback",
|
|
228
|
+
};
|
|
229
|
+
result.deliveryRoot = adopterDeliveryGateDigest(result);
|
|
230
|
+
return result;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
export function verifyV4AdopterDeliveryReadback(
|
|
234
|
+
{ input, readback } = {},
|
|
235
|
+
options = {},
|
|
236
|
+
) {
|
|
237
|
+
if (!readback || !ROOT.test(readback.deliveryRoot ?? "")) {
|
|
238
|
+
throw new Error("exact adopter delivery readback is required");
|
|
239
|
+
}
|
|
240
|
+
const observed = runV4AdopterDeliveryGate(input, options);
|
|
241
|
+
if (
|
|
242
|
+
observed.deliveryRoot !== readback.deliveryRoot ||
|
|
243
|
+
adopterDeliveryGateDigest(observed) !== adopterDeliveryGateDigest(readback)
|
|
244
|
+
) {
|
|
245
|
+
throw new Error(
|
|
246
|
+
"adopter delivery readback does not match exact recomputation",
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
return observed;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
export function qualifyV4AdopterDeliveryBootstrap({ input, lineage } = {}) {
|
|
253
|
+
const normalizedLineage = exactKeys(
|
|
254
|
+
lineage,
|
|
255
|
+
[
|
|
256
|
+
"schemaVersion",
|
|
257
|
+
"contract",
|
|
258
|
+
"sourceAuthorityCommit",
|
|
259
|
+
"targetBaseCommit",
|
|
260
|
+
"authorityArchiveRoot",
|
|
261
|
+
],
|
|
262
|
+
"bootstrap lineage",
|
|
263
|
+
);
|
|
264
|
+
if (
|
|
265
|
+
normalizedLineage.schemaVersion !== 1 ||
|
|
266
|
+
normalizedLineage.contract !==
|
|
267
|
+
V4_ADOPTER_DELIVERY_BOOTSTRAP_LINEAGE_CONTRACT ||
|
|
268
|
+
normalizedLineage.sourceAuthorityCommit !==
|
|
269
|
+
V4_ADOPTER_DELIVERY_SOURCE.commit ||
|
|
270
|
+
normalizedLineage.targetBaseCommit !==
|
|
271
|
+
V4_ADOPTER_DELIVERY_SOURCE.targetBase ||
|
|
272
|
+
!SHA.test(normalizedLineage.sourceAuthorityCommit) ||
|
|
273
|
+
!SHA.test(normalizedLineage.targetBaseCommit) ||
|
|
274
|
+
!ROOT.test(normalizedLineage.authorityArchiveRoot ?? "") ||
|
|
275
|
+
normalizedLineage.authorityArchiveRoot !== input?.authority?.packageRoot
|
|
276
|
+
) {
|
|
277
|
+
throw new Error(
|
|
278
|
+
"bootstrap lineage does not bind the exact v3 authority and v4 base",
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
const bootstrap = qualifyBuildchainDeliveryInfrastructureBootstrap(input);
|
|
282
|
+
const result = {
|
|
283
|
+
schemaVersion: 1,
|
|
284
|
+
contract: "kungfu-buildchain-v4-adopter-delivery-bootstrap/v1",
|
|
285
|
+
sourceAuthority: structuredClone(V4_ADOPTER_DELIVERY_SOURCE),
|
|
286
|
+
lineage: normalizedLineage,
|
|
287
|
+
bootstrap,
|
|
288
|
+
qualifying: false,
|
|
289
|
+
selfCertified: false,
|
|
290
|
+
releaseAuthorized: false,
|
|
291
|
+
};
|
|
292
|
+
result.resultRoot = adopterDeliveryGateDigest(result);
|
|
293
|
+
return result;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
export async function loadV4PublishedAdopterDeliveryAuthority({
|
|
297
|
+
packages,
|
|
298
|
+
expectedAuthorityRoot,
|
|
299
|
+
} = {}) {
|
|
300
|
+
const request = assertV4PublishedAdopterDeliveryRequest({
|
|
301
|
+
packages,
|
|
302
|
+
expectedAuthorityRoot,
|
|
303
|
+
});
|
|
304
|
+
const authority = await loadPublishedBuildchainDeliveryAuthority(
|
|
305
|
+
request.packages,
|
|
306
|
+
);
|
|
307
|
+
if (authority.authorityRoot !== expectedAuthorityRoot) {
|
|
308
|
+
await authority.dispose();
|
|
309
|
+
throw new Error("published archive authority readback root does not match");
|
|
310
|
+
}
|
|
311
|
+
return authority;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
export function assertV4PublishedAdopterDeliveryRequest({
|
|
315
|
+
packages,
|
|
316
|
+
expectedAuthorityRoot,
|
|
317
|
+
} = {}) {
|
|
318
|
+
if (
|
|
319
|
+
!ROOT.test(expectedAuthorityRoot ?? "") ||
|
|
320
|
+
expectedAuthorityRoot !==
|
|
321
|
+
V4_ADOPTER_DELIVERY_ARCHIVE_AUTHORITY.authorityRoot
|
|
322
|
+
) {
|
|
323
|
+
throw new Error(
|
|
324
|
+
"exact published archive authority readback root is required",
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
const normalizedPackages = exactKeys(
|
|
328
|
+
packages,
|
|
329
|
+
["buildchain", "kfd"],
|
|
330
|
+
"published archive packages",
|
|
331
|
+
);
|
|
332
|
+
for (const key of ["buildchain", "kfd"]) {
|
|
333
|
+
const declaration = exactKeys(
|
|
334
|
+
normalizedPackages[key],
|
|
335
|
+
["name", "version", "archivePath", "archiveRoot", "artifactRoot"],
|
|
336
|
+
`${key} archive identity`,
|
|
337
|
+
);
|
|
338
|
+
const expected = V4_ADOPTER_DELIVERY_ARCHIVE_AUTHORITY[key];
|
|
339
|
+
if (
|
|
340
|
+
typeof declaration.archivePath !== "string" ||
|
|
341
|
+
declaration.archivePath.length === 0 ||
|
|
342
|
+
declaration.name !== expected.name ||
|
|
343
|
+
declaration.version !== expected.version ||
|
|
344
|
+
declaration.archiveRoot !== expected.archiveRoot ||
|
|
345
|
+
declaration.artifactRoot !== expected.artifactRoot
|
|
346
|
+
) {
|
|
347
|
+
throw new Error(`${key} archive identity is not the exact v3 authority`);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
return {
|
|
351
|
+
packages: normalizedPackages,
|
|
352
|
+
expectedAuthorityRoot,
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
export const V4_ADOPTER_DELIVERY_SELECTORS = Object.freeze({
|
|
357
|
+
drivers: BUILTIN_DRIVER_SELECTORS,
|
|
358
|
+
artifactProfiles: BUILTIN_PROFILE_SELECTORS,
|
|
359
|
+
});
|