@kungfu-tech/buildchain 4.0.2-alpha.5 → 4.0.2-alpha.50
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/AGENTS.md +10 -1
- package/CONTRIBUTING.md +24 -0
- package/README.md +2 -2
- package/actions/promote-buildchain-ref/README.md +1 -1
- package/actions/v4-release-candidate-promote/README.md +28 -0
- package/architecture/agent-change-map.md +70 -9
- package/architecture/ci-lane-change-budget.json +384 -0
- package/architecture/internal-capabilities.json +56 -9
- package/architecture/maintainability-debt.json +162 -107
- package/architecture/maintainability-policy.json +34 -30
- package/architecture/release-tail-contract-inventory.json +6 -6
- package/architecture/v4-architecture-constitution.md +23 -20
- package/architecture/v4-cross-platform-adopter-qualification.json +1 -1
- package/architecture/v4-delivery-authority-parity.json +2 -2
- package/architecture/v4-delivery-warrant-shadow-bootstrap-plan.json +1 -1
- package/architecture/v4-floating-consumer-policy.json +2 -2
- package/architecture/v4-next-development-parity.json +5 -5
- package/architecture/v4-partial-mutation-recovery-qualification.json +4 -1
- package/architecture/v4-platform-stage-checkpoints.json +1 -1
- package/architecture/v4-provider-operation-journal-contract.json +5 -2
- package/architecture/v4-publication-facade-patches.json +64 -0
- package/architecture/v4-release-activation-shadow-domain.json +5 -2
- package/architecture/v4-release-topology.json +198 -38
- package/architecture/v4-rust-wasm-production-authority.json +58 -0
- package/architecture/v4-stable-publication-fence.json +5 -2
- package/architecture/v4-stage-capsule-qualification.json +2 -2
- package/architecture/v4-tail-reseal-parity.json +8 -6
- package/architecture/v4-universal-workflow-bootstrap.json +176 -0
- package/architecture/v4-universal-workflow-fault-campaign.json +72 -0
- package/architecture/v4-universal-workflow-train-admission.json +40 -0
- package/architecture/workflow-taxonomy.json +1462 -0
- package/bin/buildchain.mjs +7 -7
- package/contracts/buildchain-v2-residuals-v1.json +57 -48
- package/contracts/dev-delivery-authority-v2.schema.json +16 -2
- package/contracts/fixtures/v4-tail-reseal-v1/valid.json +1 -1
- package/contracts/v4-canonical-contracts-v1.schema.json +1 -0
- package/dist/site/buildchain-contract.json +93 -48
- package/dist/site/buildchain-site.json +276 -72
- package/dist/site/capability-registry.json +5 -5
- package/dist/site/controller-registry.json +50 -13
- package/dist/site/kfd-claims.json +2610 -983
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +14 -14
- package/dist/site/node-api-registry.json +273 -127
- package/dist/site/page-registry.json +257 -53
- package/dist/site/public-surface-audit.json +3239 -1232
- package/dist/site/publication-authority-registry.json +1135 -363
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/release-provenance.json +2 -1
- package/dist/site/schemas/dev-delivery-authority-v2.schema.json +16 -2
- package/dist/site/site-manifest.json +18 -18
- package/dist/site/workflow-registry.json +5097 -1659
- package/docs/MAP.md +2 -0
- package/docs/auditable-demo.md +1 -1
- package/docs/cli.md +21 -8
- package/docs/dev-delivery-warrant.md +1 -1
- package/docs/engineering-housekeeper.md +3 -3
- package/docs/kfd-support.md +26 -2
- package/docs/next-development-transition.md +2 -2
- package/docs/node-api-reference.md +216 -205
- package/docs/oci-publication.md +160 -0
- package/docs/publication-authority.md +2 -2
- package/docs/publish-transaction.md +36 -3
- package/docs/release-candidate.md +3 -3
- package/docs/release-flow.md +67 -19
- package/docs/release-governance.md +8 -8
- package/docs/release-passport.md +27 -2
- package/docs/reusable-build-surface.md +16 -0
- package/docs/v4-adopter-delivery.md +2 -2
- package/docs/v4-production-release.md +71 -8
- package/docs/v4-rust-wasm-production-authority.md +58 -0
- package/docs/v4-stage-capsule.md +2 -2
- package/docs/v4-tail-reseal.md +1 -1
- package/docs/workflow-catalog.md +155 -0
- package/docs/workflow-path-migration.md +109 -0
- package/package.json +12 -7
- package/packages/core/artifact-verification-envelope.js +5 -5
- package/packages/core/buildchain-contract.js +1 -1
- package/packages/core/buildchain-kfd-claims.js +2 -2
- package/packages/core/buildchain-publication-authority.js +43 -26
- package/packages/core/buildchain-v4-domain.wasm +0 -0
- package/packages/core/ci-lane-change-budget.js +14 -1
- package/packages/core/controller-evidence.js +4 -1
- package/packages/core/dev-delivery-candidate-identity.js +40 -6
- package/packages/core/dev-delivery-warrant-state.js +3 -4
- package/packages/core/dev-delivery-warrant.js +12 -2
- package/packages/core/github-governance-authority.js +4 -4
- package/packages/core/kfd-adopter-manifest.js +46 -47
- package/packages/core/next-development-projection.js +2 -2
- package/packages/core/next-development-transition.js +5 -6
- package/packages/core/oci-compose-qualification.js +140 -0
- package/packages/core/oci-publication-bundle.js +281 -0
- package/packages/core/oci-publication-graph.js +206 -0
- package/packages/core/paper-agent-entry.js +30 -4
- package/packages/core/paper-fleet.js +1 -1
- package/packages/core/paper-runtime-channels.js +348 -0
- package/packages/core/paper-scaffold-content.js +10 -0
- package/packages/core/paper.js +37 -71
- package/packages/core/publication-sealed-bundle.js +78 -13
- package/packages/core/release-line-dry-run.js +1 -1
- package/packages/core/release-passport-contract.js +5 -5
- package/packages/core/release-passport.js +5 -4
- package/packages/core/release-tail-product-capabilities.js +38 -0
- package/packages/core/release-tail-provider-plane.js +68 -1048
- package/packages/core/v4-canonical-contracts.js +15 -75
- package/packages/core/v4-domain-wasm-artifact.js +7 -0
- package/packages/core/v4-domain-wasm.js +216 -0
- package/packages/core/v4-floating-consumer-evidence.js +1 -1
- package/packages/core/v4-floating-consumer-policy.js +1 -1
- package/packages/core/v4-partial-mutation-recovery-qualification.js +9 -386
- package/packages/core/v4-product-publication.js +59 -0
- package/packages/core/v4-protected-publication-source.js +19 -21
- package/packages/core/v4-provider-operation-journal.js +18 -487
- package/packages/core/v4-provider-readback-idempotency.js +12 -97
- package/packages/core/v4-release-activation-shadow.js +13 -500
- package/packages/core/v4-release-invocation.js +28 -389
- package/packages/core/v4-stable-publication-fence.js +13 -342
- package/packages/core/v4-universal-workflow-bootstrap.js +586 -0
- package/scripts/binary-publication-evidence.mjs +135 -0
- package/scripts/build-contract-core.mjs +1 -14
- package/scripts/build-v4-domain-wasm.mjs +189 -0
- package/scripts/check-action-bundles.mjs +12 -2
- package/scripts/check-ci-lane-change-budget.mjs +4 -1
- package/scripts/check-core-mechanism-inventory.mjs +4 -3
- package/scripts/check-inventory.mjs +35 -44
- package/scripts/check-maintainability.mjs +16 -113
- package/scripts/check-v4-floating-consumer-policy-contract.mjs +2 -2
- package/scripts/check-v4-public-dogfood-contract.mjs +22 -9
- package/scripts/check-v4-release-topology.mjs +236 -50
- package/scripts/check-v4-runtime-semantic-closure.mjs +4 -1
- package/scripts/check-v4-universal-workflow-bootstrap.mjs +266 -0
- package/scripts/check-workflow-taxonomy.mjs +6 -0
- package/scripts/copy-v4-domain-wasm.mjs +14 -0
- package/scripts/dev-delivery-authority-command-adapters.mjs +1 -1
- package/scripts/dev-delivery-authority.mjs +8 -8
- package/scripts/dev-delivery-source-proof-reuse.mjs +2 -1
- package/scripts/dev-delivery-warrant-options.mjs +14 -9
- package/scripts/dev-delivery-warrant-store.mjs +73 -7
- package/scripts/dev-delivery-warrant-transition.mjs +109 -0
- package/scripts/dev-delivery-warrant.mjs +76 -99
- package/scripts/dev-pr-auto-merge.mjs +15 -15
- package/scripts/generate-channel-build-workflow.mjs +7 -2
- package/scripts/generate-channel-promotion-workflow.mjs +10 -25
- package/scripts/generate-site-bundle.mjs +11 -11
- package/scripts/generate-v4-universal-workflow-facades.mjs +497 -0
- package/scripts/generate-workflow-taxonomy.mjs +25 -0
- package/scripts/github-output.mjs +31 -0
- package/scripts/maintainability-metrics.mjs +16 -5
- package/scripts/maintainability-public-surface.mjs +115 -0
- package/scripts/next-development-review.mjs +307 -0
- package/scripts/oci-compose-preview.mjs +250 -0
- package/scripts/paper-work-fleet-cli.mjs +2 -0
- package/scripts/publication-candidate-kind.mjs +93 -0
- package/scripts/publication-candidate-sealer.mjs +16 -1
- package/scripts/release-asset-client.mjs +91 -0
- package/scripts/release-candidate-resolver.mjs +23 -35
- package/scripts/resume-from-candidate-run.mjs +11 -18
- package/scripts/site-capability-metadata.mjs +1 -0
- package/scripts/source-verification-evidence.mjs +344 -0
- package/scripts/stable-candidate-qualification.mjs +1 -1
- package/scripts/universal-facade-maintainability.mjs +91 -0
- package/scripts/v4-product-publication-intent.mjs +129 -0
- package/scripts/v4-publication-settlement.mjs +211 -0
- package/scripts/v4-universal-workflow-backflow.mjs +212 -0
- package/scripts/v4-universal-workflow-engine.mjs +620 -0
- package/scripts/v4-universal-workflow-self-dogfood.mjs +205 -0
- package/scripts/verify-version-state-delta.mjs +173 -0
- package/scripts/workflow-taxonomy.mjs +507 -0
- package/templates/native-dev-delivery.yml +4 -7
- package/templates/universal-buildchain-bootstrap-recovery.yml +282 -0
- package/templates/universal-buildchain-bootstrap.yml +28 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import crypto from "node:crypto";
|
|
2
|
+
import { execFileSync } from "node:child_process";
|
|
2
3
|
import fs from "node:fs";
|
|
3
4
|
import path from "node:path";
|
|
4
5
|
|
|
@@ -19,7 +20,10 @@ function requiredString(value, label) {
|
|
|
19
20
|
|
|
20
21
|
function safeRelativePath(value, label) {
|
|
21
22
|
const normalized = requiredString(value, label).replaceAll("\\", "/");
|
|
22
|
-
if (
|
|
23
|
+
if (
|
|
24
|
+
normalized.startsWith("/") ||
|
|
25
|
+
normalized.split("/").some((part) => part === ".." || part === "")
|
|
26
|
+
) {
|
|
23
27
|
throw new Error(`${label} must be a safe relative path`);
|
|
24
28
|
}
|
|
25
29
|
return normalized;
|
|
@@ -41,7 +45,8 @@ function sha256File(filePath) {
|
|
|
41
45
|
const chunk = Buffer.allocUnsafe(8 * 1024 * 1024);
|
|
42
46
|
try {
|
|
43
47
|
let bytesRead = 0;
|
|
44
|
-
while ((bytesRead = fs.readSync(descriptor, chunk, 0, chunk.length, null)) > 0)
|
|
48
|
+
while ((bytesRead = fs.readSync(descriptor, chunk, 0, chunk.length, null)) > 0)
|
|
49
|
+
hash.update(chunk.subarray(0, bytesRead));
|
|
45
50
|
} finally {
|
|
46
51
|
fs.closeSync(descriptor);
|
|
47
52
|
}
|
|
@@ -60,8 +65,16 @@ function normalizeFile(entry, label) {
|
|
|
60
65
|
};
|
|
61
66
|
}
|
|
62
67
|
|
|
68
|
+
function fileInventory(files, label) {
|
|
69
|
+
return (files || []).map((entry, index) => normalizeFile(entry, `${label}[${index}]`))
|
|
70
|
+
.sort((left, right) => left.path.localeCompare(right.path));
|
|
71
|
+
}
|
|
72
|
+
|
|
63
73
|
function candidatePayload(candidate) {
|
|
64
|
-
if (
|
|
74
|
+
if (
|
|
75
|
+
candidate?.contract !== PUBLICATION_ARTIFACT_CANDIDATE_CONTRACT ||
|
|
76
|
+
Number(candidate?.schemaVersion) !== 1
|
|
77
|
+
) {
|
|
65
78
|
throw new Error("publication artifact candidate contract mismatch");
|
|
66
79
|
}
|
|
67
80
|
const { candidateDigest: _candidateDigest, ...payload } = candidate;
|
|
@@ -91,9 +104,7 @@ export function createPublicationSealedBundle({
|
|
|
91
104
|
githubReleaseRequired = true,
|
|
92
105
|
} = {}) {
|
|
93
106
|
const { digest } = candidatePayload(candidate);
|
|
94
|
-
const files = (candidate.files
|
|
95
|
-
.map((entry, index) => normalizeFile(entry, `candidate.files[${index}]`))
|
|
96
|
-
.sort((left, right) => left.path.localeCompare(right.path));
|
|
107
|
+
const files = fileInventory(candidate.files, "candidate.files");
|
|
97
108
|
if (new Set(files.map((entry) => entry.path)).size !== files.length) {
|
|
98
109
|
throw new Error("publication sealed bundle candidate paths must be unique");
|
|
99
110
|
}
|
|
@@ -119,6 +130,7 @@ export function createPublicationSealedBundle({
|
|
|
119
130
|
sha256: npmTarball.sha256,
|
|
120
131
|
integrity: requiredString(npmIntegrity, "npmIntegrity"),
|
|
121
132
|
},
|
|
133
|
+
...(candidate.npmPackages ? { npmPackages: candidate.npmPackages } : {}),
|
|
122
134
|
releaseAssets,
|
|
123
135
|
completion: {
|
|
124
136
|
githubReleaseRequired: Boolean(githubReleaseRequired),
|
|
@@ -130,8 +142,56 @@ export function createPublicationSealedBundle({
|
|
|
130
142
|
};
|
|
131
143
|
}
|
|
132
144
|
|
|
145
|
+
function verifyNpmPackageSet(manifest, files, resolvedRoot) {
|
|
146
|
+
const npmPackages = manifest.npmPackages;
|
|
147
|
+
if (JSON.stringify(npmPackages) !== JSON.stringify(manifest.candidate.npmPackages)) {
|
|
148
|
+
throw new Error("publication sealed bundle npm package inventory differs from candidate");
|
|
149
|
+
}
|
|
150
|
+
if (npmPackages) {
|
|
151
|
+
if (
|
|
152
|
+
!Array.isArray(npmPackages) ||
|
|
153
|
+
npmPackages.length < 2 ||
|
|
154
|
+
new Set(npmPackages.map((entry) => entry.name)).size !== npmPackages.length ||
|
|
155
|
+
new Set(npmPackages.map((entry) => entry.path)).size !== npmPackages.length
|
|
156
|
+
) {
|
|
157
|
+
throw new Error("publication sealed bundle npm package inventory must be unique");
|
|
158
|
+
}
|
|
159
|
+
for (const entry of npmPackages) {
|
|
160
|
+
const file = selectFile(files, entry.path, "npmPackages.path");
|
|
161
|
+
const absolutePath = path.resolve(resolvedRoot, file.path);
|
|
162
|
+
const metadata = JSON.parse(
|
|
163
|
+
execFileSync("tar", ["-xOf", path.basename(absolutePath), "package/package.json"], {
|
|
164
|
+
cwd: path.dirname(absolutePath),
|
|
165
|
+
encoding: "utf8",
|
|
166
|
+
}),
|
|
167
|
+
);
|
|
168
|
+
const integrity = `sha512-${crypto.createHash("sha512").update(fs.readFileSync(absolutePath)).digest("base64")}`;
|
|
169
|
+
if (
|
|
170
|
+
entry.name !== metadata.name ||
|
|
171
|
+
entry.version !== metadata.version ||
|
|
172
|
+
entry.size !== file.size ||
|
|
173
|
+
entry.sha256 !== file.sha256 ||
|
|
174
|
+
entry.integrity !== integrity
|
|
175
|
+
) {
|
|
176
|
+
throw new Error("publication sealed bundle npm package identity or integrity mismatch");
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
const main = npmPackages.filter((entry) => entry.role === "main");
|
|
180
|
+
if (
|
|
181
|
+
main.length !== 1 ||
|
|
182
|
+
Object.keys(manifest.npm).some((key) => main[0][key] !== manifest.npm[key])
|
|
183
|
+
) {
|
|
184
|
+
throw new Error("publication sealed bundle npm main package mismatch");
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return npmPackages;
|
|
188
|
+
}
|
|
189
|
+
|
|
133
190
|
export function verifyPublicationSealedBundle({ bundleRoot, manifest } = {}) {
|
|
134
|
-
if (
|
|
191
|
+
if (
|
|
192
|
+
manifest?.contract !== PUBLICATION_SEALED_BUNDLE_CONTRACT ||
|
|
193
|
+
Number(manifest?.schemaVersion) !== 1
|
|
194
|
+
) {
|
|
135
195
|
throw new Error("publication sealed bundle contract mismatch");
|
|
136
196
|
}
|
|
137
197
|
const resolvedRoot = path.resolve(requiredString(bundleRoot, "bundleRoot"));
|
|
@@ -139,12 +199,8 @@ export function verifyPublicationSealedBundle({ bundleRoot, manifest } = {}) {
|
|
|
139
199
|
if (normalizeSha256(manifest.root, "manifest.root") !== digest) {
|
|
140
200
|
throw new Error("publication sealed bundle root mismatch");
|
|
141
201
|
}
|
|
142
|
-
const files = (manifest.files
|
|
143
|
-
|
|
144
|
-
.sort((left, right) => left.path.localeCompare(right.path));
|
|
145
|
-
const candidateFiles = (manifest.candidate.files || [])
|
|
146
|
-
.map((entry, index) => normalizeFile(entry, `candidate.files[${index}]`))
|
|
147
|
-
.sort((left, right) => left.path.localeCompare(right.path));
|
|
202
|
+
const files = fileInventory(manifest.files, "manifest.files");
|
|
203
|
+
const candidateFiles = fileInventory(manifest.candidate.files, "candidate.files");
|
|
148
204
|
if (JSON.stringify(files) !== JSON.stringify(candidateFiles)) {
|
|
149
205
|
throw new Error("publication sealed bundle file inventory differs from candidate");
|
|
150
206
|
}
|
|
@@ -169,6 +225,7 @@ export function verifyPublicationSealedBundle({ bundleRoot, manifest } = {}) {
|
|
|
169
225
|
) {
|
|
170
226
|
throw new Error("publication sealed bundle npm tarball inventory mismatch");
|
|
171
227
|
}
|
|
228
|
+
const npmPackages = verifyNpmPackageSet(manifest, files, resolvedRoot);
|
|
172
229
|
const releaseAssets = (manifest.releaseAssets || []).map((entry, index) => {
|
|
173
230
|
const selected = selectFile(files, entry.path, `manifest.releaseAssets[${index}].path`);
|
|
174
231
|
const normalized = normalizeFile(entry, `manifest.releaseAssets[${index}]`);
|
|
@@ -194,6 +251,14 @@ export function verifyPublicationSealedBundle({ bundleRoot, manifest } = {}) {
|
|
|
194
251
|
...entry,
|
|
195
252
|
absolutePath: path.resolve(resolvedRoot, entry.path),
|
|
196
253
|
})),
|
|
254
|
+
...(npmPackages
|
|
255
|
+
? {
|
|
256
|
+
npmPackages: npmPackages.map((entry) => ({
|
|
257
|
+
...entry,
|
|
258
|
+
absolutePath: path.resolve(resolvedRoot, entry.path),
|
|
259
|
+
})),
|
|
260
|
+
}
|
|
261
|
+
: {}),
|
|
197
262
|
manifest,
|
|
198
263
|
};
|
|
199
264
|
}
|
|
@@ -201,7 +201,7 @@ function explainReleaseLineDryRun({
|
|
|
201
201
|
);
|
|
202
202
|
plan.branchUpdates.push(
|
|
203
203
|
{ ref: targetRef, action: "would move to alpha version-state commit" },
|
|
204
|
-
{ ref: `dev/v${rule.major}/v${rule.major}.${rule.minor}`, action: "would align dev with the published alpha state" },
|
|
204
|
+
{ ref: `dev/v${rule.major}/v${rule.major}.${rule.minor}`, action: rule.major === 4 ? "would prepare the next alpha version on dev through a separate protected PR after publication" : "would align dev with the published alpha state" },
|
|
205
205
|
);
|
|
206
206
|
plan.versionState.targetVersions = [exactAlpha.replace(/^next v?/, "").replace(/^v/, "")];
|
|
207
207
|
plan.notes.push("Alpha promotion opens or advances the test channel; it does not move production refs.");
|
|
@@ -405,7 +405,7 @@ export function prepareReleasePassportKfdSections({ kfd1, kfd2Claims, kfd3, kfdA
|
|
|
405
405
|
};
|
|
406
406
|
}
|
|
407
407
|
|
|
408
|
-
export function collectKfdAdopterReleaseEvidence({ manifest, gateResults = [], comparisonMatrix, sourceSha = "", checkedAt } = {}) {
|
|
408
|
+
export function collectKfdAdopterReleaseEvidence({ manifest, gateResults = [], comparisonMatrix, expectedAdopterId = "kungfu-systems/buildchain", expectedSourceRepository = "", sourceSha = "", checkedAt } = {}) {
|
|
409
409
|
if (!manifest) {
|
|
410
410
|
if (comparisonMatrix || gateResults.length > 0) {
|
|
411
411
|
throw new Error("KFD support and product-gate inputs require --kfd-adopter-manifest-json; --kfd-support-matrix-json is comparison-only");
|
|
@@ -414,7 +414,7 @@ export function collectKfdAdopterReleaseEvidence({ manifest, gateResults = [], c
|
|
|
414
414
|
}
|
|
415
415
|
const manifestGate = createKfdAdopterManifestGate({
|
|
416
416
|
manifest, packageArtifactRoot: installedKfdPackageArtifactRoot(), gateResults,
|
|
417
|
-
expectedSourceSha: sourceSha, checkedAt,
|
|
417
|
+
expectedAdopterId, expectedSourceRepository, expectedSourceSha: sourceSha, checkedAt,
|
|
418
418
|
});
|
|
419
419
|
const legacyProjection = createKfdLegacySupportMatrixProjection({ manifest, manifestGate });
|
|
420
420
|
if (comparisonMatrix) {
|
|
@@ -425,18 +425,18 @@ export function collectKfdAdopterReleaseEvidence({ manifest, gateResults = [], c
|
|
|
425
425
|
}
|
|
426
426
|
return {
|
|
427
427
|
manifest, manifestGate, legacyProjection,
|
|
428
|
-
binding: createKfdAdopterReleaseBinding({ manifest, manifestGate, legacyProjection, expectedSourceSha: sourceSha }),
|
|
428
|
+
binding: createKfdAdopterReleaseBinding({ manifest, manifestGate, legacyProjection, expectedAdopterId, expectedSourceRepository, expectedSourceSha: sourceSha }),
|
|
429
429
|
};
|
|
430
430
|
}
|
|
431
431
|
|
|
432
|
-
export function validateKfdAdopterReleaseEvidence({ binding, artifactBinding, manifest, manifestGate, legacyProjection, passportLegacyProjection, expectedSourceSha = "" } = {}) {
|
|
432
|
+
export function validateKfdAdopterReleaseEvidence({ binding, artifactBinding, manifest, manifestGate, legacyProjection, passportLegacyProjection, expectedAdopterId = "kungfu-systems/buildchain", expectedSourceRepository = "", expectedSourceSha = "" } = {}) {
|
|
433
433
|
if (!binding) {
|
|
434
434
|
return passportLegacyProjection
|
|
435
435
|
? [{ code: "kfdSupport.authority", message: "legacy KFD support projection requires the standard adopter manifest binding" }]
|
|
436
436
|
: [];
|
|
437
437
|
}
|
|
438
438
|
const issues = validateKfdAdopterReleaseBinding(binding, {
|
|
439
|
-
manifest, manifestGate, legacyProjection, expectedSourceSha,
|
|
439
|
+
manifest, manifestGate, legacyProjection, expectedAdopterId, expectedSourceRepository, expectedSourceSha,
|
|
440
440
|
}).issues.map((entry) => ({ code: `kfdAdopter.${entry.path || entry.code}`, message: entry.message, details: entry }));
|
|
441
441
|
if (!artifactBinding || passportStableJson(artifactBinding) !== passportStableJson(binding)) {
|
|
442
442
|
issues.push({ code: "kfdAdopter.artifactEvidence", message: "release passport and artifact evidence must bind the same exact KFD adopter closure" });
|
|
@@ -1431,7 +1431,7 @@ export function createReleasePassport(options = {}) {
|
|
|
1431
1431
|
};
|
|
1432
1432
|
}
|
|
1433
1433
|
|
|
1434
|
-
function collectKfdAdopterReleaseInputs({ cwd, manifestJson, supportMatrixJson, productGateJsons, sourceSha, checkedAt }) {
|
|
1434
|
+
function collectKfdAdopterReleaseInputs({ cwd, manifestJson, supportMatrixJson, productGateJsons, repository, sourceSha, checkedAt }) {
|
|
1435
1435
|
const manifestMeta = parseJsonInputWithMeta(manifestJson, undefined, { cwd, label: "kfdAdopterManifestJson" });
|
|
1436
1436
|
const supportMatrixMeta = parseJsonInputWithMeta(supportMatrixJson, undefined, { cwd, label: "kfdSupportMatrixJson" });
|
|
1437
1437
|
const productGateMetas = (productGateJsons || [])
|
|
@@ -1442,7 +1442,7 @@ function collectKfdAdopterReleaseInputs({ cwd, manifestJson, supportMatrixJson,
|
|
|
1442
1442
|
manifest: manifestMeta.value,
|
|
1443
1443
|
gateResults: productGateMetas.map((meta) => meta.value),
|
|
1444
1444
|
comparisonMatrix: supportMatrixMeta.value,
|
|
1445
|
-
sourceSha,
|
|
1445
|
+
expectedAdopterId: repository || "kungfu-systems/buildchain", expectedSourceRepository: repository, sourceSha,
|
|
1446
1446
|
checkedAt,
|
|
1447
1447
|
});
|
|
1448
1448
|
}
|
|
@@ -1620,7 +1620,7 @@ export function collectGitHubReleasePassport({
|
|
|
1620
1620
|
const productMechanism = defaultProductMechanism({ repository, productName });
|
|
1621
1621
|
const kfdAdopterEvidence = collectKfdAdopterReleaseInputs({
|
|
1622
1622
|
cwd, manifestJson: kfdAdopterManifestJson, supportMatrixJson: kfdSupportMatrixJson,
|
|
1623
|
-
productGateJsons: kfdProductGateJsons, sourceSha, checkedAt: resolvedCheckedAt,
|
|
1623
|
+
productGateJsons: kfdProductGateJsons, repository, sourceSha, checkedAt: resolvedCheckedAt,
|
|
1624
1624
|
});
|
|
1625
1625
|
const {
|
|
1626
1626
|
manifest: kfdAdopterManifest,
|
|
@@ -2060,7 +2060,8 @@ function validateReleaseEvidenceContracts({
|
|
|
2060
2060
|
manifestGate: kfdAdopterManifestGate,
|
|
2061
2061
|
legacyProjection: kfdSupportEvidence,
|
|
2062
2062
|
passportLegacyProjection: passport?.kfdSupport,
|
|
2063
|
-
|
|
2063
|
+
expectedAdopterId: optionalString(passport?.product?.repository) || "kungfu-systems/buildchain",
|
|
2064
|
+
expectedSourceRepository: optionalString(passport?.product?.repository), expectedSourceSha: optionalString(passport?.release?.sourceSha),
|
|
2064
2065
|
})) {
|
|
2065
2066
|
issues.push(issue("error", entry.code, entry.message, entry.details));
|
|
2066
2067
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export const RELEASE_TAIL_PRODUCT_CAPABILITIES = Object.freeze([
|
|
2
|
+
Object.freeze({
|
|
3
|
+
id: "product.version-state.materialize",
|
|
4
|
+
executor: "provider-adapter",
|
|
5
|
+
adapter: "github-version-state",
|
|
6
|
+
effectKind: "product-version-state-materialization",
|
|
7
|
+
observationKind: "product-version-state-readback",
|
|
8
|
+
receiptKind: "product-version-state",
|
|
9
|
+
transactionState: "preparing",
|
|
10
|
+
}),
|
|
11
|
+
Object.freeze({
|
|
12
|
+
id: "product.package.publish",
|
|
13
|
+
executor: "provider-adapter",
|
|
14
|
+
adapter: "npm-trusted-publishing",
|
|
15
|
+
effectKind: "product-package-publication",
|
|
16
|
+
observationKind: "product-package-readback",
|
|
17
|
+
receiptKind: "product-package-publication",
|
|
18
|
+
transactionState: "publishing",
|
|
19
|
+
}),
|
|
20
|
+
Object.freeze({
|
|
21
|
+
id: "product.oci.publish",
|
|
22
|
+
executor: "provider-adapter",
|
|
23
|
+
adapter: "oci-image-family",
|
|
24
|
+
effectKind: "oci-family-publication",
|
|
25
|
+
observationKind: "oci-family-readback",
|
|
26
|
+
receiptKind: "oci-family-publication",
|
|
27
|
+
transactionState: "publishing",
|
|
28
|
+
}),
|
|
29
|
+
Object.freeze({
|
|
30
|
+
id: "product.release-refs.converge",
|
|
31
|
+
executor: "provider-adapter",
|
|
32
|
+
adapter: "github-release-refs",
|
|
33
|
+
effectKind: "product-release-ref-convergence",
|
|
34
|
+
observationKind: "product-release-ref-readback",
|
|
35
|
+
receiptKind: "product-release-ref-convergence",
|
|
36
|
+
transactionState: "committing",
|
|
37
|
+
}),
|
|
38
|
+
]);
|