@kungfu-tech/buildchain 4.0.1-alpha.4 → 4.0.1-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/actions/release-tail/README.md +8 -0
- package/architecture/decisions/0002-next-development-transition.md +101 -0
- package/architecture/internal-capabilities.json +117 -8
- package/architecture/maintainability-policy.json +38 -20
- package/architecture/release-tail-contract-inventory.json +5 -2
- package/architecture/v3-core-mechanism-inventory.json +89 -0
- package/architecture/v4-adopter-delivery-parity.json +32 -5
- package/architecture/v4-capability-state-machine-manifest.json +73 -0
- package/architecture/v4-compatibility-facts-parity.json +77 -0
- package/architecture/v4-next-development-parity.json +192 -0
- package/architecture/v4-publication-rehearsal-parity.json +84 -0
- package/architecture/v4-release-train-parity.json +1 -0
- package/architecture/v4-tail-reseal-parity.json +150 -0
- package/bin/buildchain.mjs +23 -2
- package/bin/internal/adopter-delivery-cli.mjs +70 -0
- package/bin/internal/command-registry.mjs +3 -0
- package/bin/internal/compatibility-facts-cli.mjs +101 -0
- package/contracts/fixtures/next-development-transition-v1/anchored-manual-waiting.json +47 -0
- package/contracts/fixtures/next-development-transition-v1/semver-auto-planned.json +47 -0
- package/contracts/fixtures/next-development-transition-v1/version-model-cases.json +40 -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-compatibility-facts-v1/shared.json +1129 -0
- package/contracts/fixtures/v4-floating-consumer-policy-v1/cases.json +7 -1
- 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 +229 -0
- package/contracts/next-development-request-v1.schema.json +66 -0
- package/contracts/next-development-transition-v1.schema.json +292 -0
- package/contracts/v4-adopter-delivery-v1.schema.json +81 -0
- package/contracts/v4-compatibility-facts-v1.schema.json +230 -0
- package/contracts/v4-publication-rehearsal-capsule-v1.schema.json +233 -0
- package/contracts/v4-tail-reseal-v1.schema.json +276 -0
- package/dist/site/agent-index.json +4 -0
- package/dist/site/artifact-schemas.json +8 -0
- package/dist/site/buildchain-contract.json +1393 -28
- package/dist/site/buildchain-site.json +462 -27
- package/dist/site/capability-registry.json +17 -14
- package/dist/site/cli-registry.json +159 -1
- package/dist/site/kfd-claims.json +429 -15
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +52 -6
- package/dist/site/node-api-registry.json +13972 -9697
- package/dist/site/page-registry.json +428 -17
- package/dist/site/public-surface-audit.json +429 -11
- package/dist/site/publication-authority-registry.json +22 -4
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/release-provenance.json +21 -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-compatibility-facts-v1.schema.json +230 -0
- package/dist/site/schemas/v4-publication-rehearsal-capsule-v1.schema.json +233 -0
- package/dist/site/site-manifest.json +34 -10
- package/dist/site/workflow-registry.json +121 -8
- package/docs/MAP.md +7 -2
- package/docs/cli-reference.md +193 -0
- package/docs/cli.md +8 -0
- package/docs/dev-alpha-candidate-patrol.md +8 -0
- package/docs/next-development-transition.md +118 -0
- package/docs/node-api-reference.md +448 -168
- package/docs/release-tail-provider-plane.md +30 -0
- package/docs/v4-adopter-delivery.md +133 -0
- package/docs/v4-compatibility-facts.md +91 -0
- package/docs/v4-publication-rehearsal.md +130 -0
- package/docs/v4-tail-reseal.md +73 -0
- package/docs/versioning.md +4 -3
- package/package.json +29 -6
- package/packages/core/adopter-delivery-passport.js +259 -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 +3 -0
- package/packages/core/buildchain-compatibility-authority.js +336 -0
- package/packages/core/buildchain-compatibility-fact.js +394 -0
- package/packages/core/buildchain-compatibility-facts.json +217 -0
- package/packages/core/buildchain-compatibility-proof.js +566 -0
- package/packages/core/buildchain-config.js +84 -0
- package/packages/core/buildchain-contract.js +93 -141
- 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/channel-candidate.js +8 -0
- package/packages/core/channel-promotion-baseline.js +55 -0
- package/packages/core/dev-alpha-candidate-selection.js +10 -2
- package/packages/core/dev-delivery-execution-transfer.js +21 -1
- package/packages/core/dev-delivery-process-boundary.js +19 -6
- package/packages/core/dev-delivery-provider-heartbeat.js +18 -6
- package/packages/core/kungfu-temporal-fact.js +557 -0
- package/packages/core/legacy-kfd-adopter-driver.js +167 -0
- package/packages/core/next-development-candidate-reservation.js +186 -0
- package/packages/core/next-development-controller.js +728 -0
- package/packages/core/next-development-projection.js +287 -0
- package/packages/core/next-development-transition.js +738 -0
- package/packages/core/paper-agent-entry.js +11 -5
- package/packages/core/paper.js +16 -5
- package/packages/core/published-delivery-authority.js +266 -0
- package/packages/core/release-passport.js +26 -8
- package/packages/core/v4-adopter-delivery-parity.js +3 -3
- package/packages/core/v4-adopter-delivery.js +359 -0
- package/packages/core/v4-canonical-contracts.js +5 -0
- package/packages/core/v4-floating-consumer-policy.js +29 -9
- 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/v4-tail-reseal-contract.js +26 -0
- package/packages/core/v4-tail-reseal-github.js +178 -0
- package/packages/core/v4-tail-reseal-receipt.js +225 -0
- package/packages/core/v4-tail-reseal.js +594 -0
- package/scripts/buildchain-cli-help.mjs +30 -0
- package/scripts/check-inventory.mjs +14 -3
- package/scripts/dev-alpha-candidate-patrol.mjs +22 -1
- package/scripts/dev-delivery-source-proof-replay.mjs +153 -0
- package/scripts/dev-delivery-source-proof-reuse.mjs +13 -97
- package/scripts/generate-next-development-guidance.mjs +49 -0
- package/scripts/generate-release-candidate-passport.mjs +152 -0
- package/scripts/generate-site-bundle.mjs +46 -3
- package/scripts/init-repo.mjs +22 -4
- package/scripts/next-development-self-dogfood-harness.mjs +460 -0
- package/scripts/next-development-self-dogfood.mjs +597 -0
- package/scripts/next-development-transition.mjs +47 -0
- package/scripts/release-tail.mjs +51 -3
- package/scripts/resume-from-candidate-run.mjs +545 -15
- package/scripts/site-capability-metadata.mjs +28 -0
- package/scripts/v4-consumer-policy.mjs +1 -5
- package/scripts/v4-publication-rehearsal-fixture.mjs +144 -0
- package/scripts/v4-tail-reseal-macos-rehearsal.mjs +134 -0
- package/scripts/v4-tail-reseal.mjs +416 -0
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
stableJson,
|
|
13
13
|
workCheck,
|
|
14
14
|
} from "./paper-repository.js";
|
|
15
|
+
import { mergeNextDevelopmentAgentInstructions } from "./next-development-projection.js";
|
|
15
16
|
|
|
16
17
|
export const PAPER_AGENT_ENTRY_CONTRACT = "kungfu-buildchain-paper-agent-entry";
|
|
17
18
|
export const PAPER_AGENT_ENTRY_SCHEMA_VERSION = 1;
|
|
@@ -167,9 +168,11 @@ export function paperAgentEntryFiles({
|
|
|
167
168
|
[PAPER_PATHS.agentEntry, jsonText(entry)],
|
|
168
169
|
[
|
|
169
170
|
PAPER_PATHS.agentInstructions,
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
171
|
+
mergeNextDevelopmentAgentInstructions(
|
|
172
|
+
mergePaperAgentEntryInstructions(currentAgents, {
|
|
173
|
+
developmentRef: resolvedDevelopmentRef,
|
|
174
|
+
}),
|
|
175
|
+
),
|
|
173
176
|
],
|
|
174
177
|
]);
|
|
175
178
|
}
|
|
@@ -205,8 +208,11 @@ function ciContext({ env, developmentRef }) {
|
|
|
205
208
|
sourceBranch.startsWith(versionStatePrefix) &&
|
|
206
209
|
/^[0-9a-f]{12}$/i.test(sourceBranch.slice(versionStatePrefix.length));
|
|
207
210
|
const branchOk = pullRequest
|
|
208
|
-
? (PAPER_WORK_BRANCH_PATTERN.test(sourceBranch) &&
|
|
209
|
-
|
|
211
|
+
? (PAPER_WORK_BRANCH_PATTERN.test(sourceBranch) &&
|
|
212
|
+
targetBranch === developmentRef) ||
|
|
213
|
+
(channelIndex > 0 &&
|
|
214
|
+
sourceBranch === channelBranches[channelIndex - 1]) ||
|
|
215
|
+
generatedVersionState
|
|
210
216
|
: channelBranches.includes(refName);
|
|
211
217
|
return {
|
|
212
218
|
mode: "ci",
|
package/packages/core/paper.js
CHANGED
|
@@ -46,6 +46,11 @@ import {
|
|
|
46
46
|
scaffoldReadme,
|
|
47
47
|
} from "./paper-scaffold-content.js";
|
|
48
48
|
import { executePaperNpmBootstrap as executePaperNpmBootstrapOperation } from "./paper-npm-bootstrap.js";
|
|
49
|
+
import {
|
|
50
|
+
appendNextDevelopmentToml,
|
|
51
|
+
nextDevelopmentWorkflowHeader,
|
|
52
|
+
projectNextDevelopmentToml,
|
|
53
|
+
} from "./next-development-projection.js";
|
|
49
54
|
|
|
50
55
|
export { PAPER_PATHS, resolvePaperRepository } from "./paper-repository.js";
|
|
51
56
|
export {
|
|
@@ -350,7 +355,7 @@ immutable_base_url = ${tomlString(joinUrl(siteBaseUrl, "archive").replace(/\/$/,
|
|
|
350
355
|
registry_path = ".buildchain/publication/publication-registry.json"
|
|
351
356
|
`
|
|
352
357
|
: "";
|
|
353
|
-
return `schema = 1
|
|
358
|
+
return appendNextDevelopmentToml(`schema = 1
|
|
354
359
|
|
|
355
360
|
[project]
|
|
356
361
|
type = "publication-artifact"
|
|
@@ -384,14 +389,14 @@ command = "make pdf"
|
|
|
384
389
|
|
|
385
390
|
[lifecycle.verify]
|
|
386
391
|
command = "make check"
|
|
387
|
-
|
|
392
|
+
`);
|
|
388
393
|
}
|
|
389
394
|
|
|
390
395
|
function scaffoldBuildWorkflow(
|
|
391
396
|
buildchainSha,
|
|
392
397
|
{ artifactName = "paper-publication" } = {},
|
|
393
398
|
) {
|
|
394
|
-
return
|
|
399
|
+
return `${nextDevelopmentWorkflowHeader()}name: Build
|
|
395
400
|
|
|
396
401
|
on:
|
|
397
402
|
workflow_dispatch:
|
|
@@ -419,7 +424,7 @@ jobs:
|
|
|
419
424
|
}
|
|
420
425
|
|
|
421
426
|
function scaffoldVerifyWorkflow(buildchainSha) {
|
|
422
|
-
return
|
|
427
|
+
return `${nextDevelopmentWorkflowHeader()}name: Verify
|
|
423
428
|
|
|
424
429
|
on:
|
|
425
430
|
pull_request:
|
|
@@ -450,7 +455,7 @@ function scaffoldReleaseWorkflow(
|
|
|
450
455
|
const passportInput = releasePassportProductName
|
|
451
456
|
? ` release-passport-product-name: ${JSON.stringify(releasePassportProductName)}\n`
|
|
452
457
|
: "";
|
|
453
|
-
return
|
|
458
|
+
return `${nextDevelopmentWorkflowHeader()}name: Paper Release
|
|
454
459
|
|
|
455
460
|
on:
|
|
456
461
|
workflow_dispatch:
|
|
@@ -997,6 +1002,12 @@ function migrationFiles({
|
|
|
997
1002
|
runtimeIdentity.version,
|
|
998
1003
|
);
|
|
999
1004
|
const files = new Map([
|
|
1005
|
+
[
|
|
1006
|
+
PAPER_PATHS.config,
|
|
1007
|
+
projectNextDevelopmentToml(
|
|
1008
|
+
fs.readFileSync(path.resolve(cwd, PAPER_PATHS.config), "utf8"),
|
|
1009
|
+
),
|
|
1010
|
+
],
|
|
1000
1011
|
[PAPER_PATHS.contractLock, contractLockText],
|
|
1001
1012
|
[PAPER_PATHS.versionPin, `${runtimeIdentity.version}\n`],
|
|
1002
1013
|
[PAPER_PATHS.buildWorkflow, buildWorkflow],
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { createReadStream } from "node:fs";
|
|
3
|
+
import {
|
|
4
|
+
copyFile,
|
|
5
|
+
mkdir,
|
|
6
|
+
mkdtemp,
|
|
7
|
+
readFile,
|
|
8
|
+
realpath,
|
|
9
|
+
rm,
|
|
10
|
+
} from "node:fs/promises";
|
|
11
|
+
import { tmpdir } from "node:os";
|
|
12
|
+
import path from "node:path";
|
|
13
|
+
import { promisify } from "node:util";
|
|
14
|
+
import { pathToFileURL } from "node:url";
|
|
15
|
+
import { execFile } from "node:child_process";
|
|
16
|
+
|
|
17
|
+
import { adopterDeliveryGateDigest } from "./adopter-delivery-gate.js";
|
|
18
|
+
|
|
19
|
+
export const PUBLISHED_DELIVERY_AUTHORITY_CONTRACT =
|
|
20
|
+
"kungfu-buildchain-published-delivery-authority/v1";
|
|
21
|
+
|
|
22
|
+
const execFileAsync = promisify(execFile);
|
|
23
|
+
const ROOT_PATTERN = /^sha256:[0-9a-f]{64}$/;
|
|
24
|
+
const PACKAGES = [
|
|
25
|
+
{
|
|
26
|
+
key: "buildchain",
|
|
27
|
+
name: "@kungfu-tech/buildchain",
|
|
28
|
+
packageRoot: "archive",
|
|
29
|
+
modules: {
|
|
30
|
+
adopterDeliveryGate: "packages/core/adopter-delivery-gate.js",
|
|
31
|
+
bootstrap: "packages/core/buildchain-delivery-bootstrap.js",
|
|
32
|
+
infrastructure: "packages/core/buildchain-delivery-infrastructure.js",
|
|
33
|
+
kfdCategoryDriver: "packages/core/kfd-adopter-category-driver.js",
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
key: "kfd",
|
|
38
|
+
name: "@kungfu-tech/kfd",
|
|
39
|
+
packageRoot: "profiles/adopter-conformance/adopters/kfd/manifest.json",
|
|
40
|
+
modules: {},
|
|
41
|
+
},
|
|
42
|
+
];
|
|
43
|
+
|
|
44
|
+
async function sha256File(file) {
|
|
45
|
+
const hash = createHash("sha256");
|
|
46
|
+
for await (const chunk of createReadStream(file)) hash.update(chunk);
|
|
47
|
+
return `sha256:${hash.digest("hex")}`;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function exactDeclaration(value, expectedName, label) {
|
|
51
|
+
if (
|
|
52
|
+
value?.name !== expectedName ||
|
|
53
|
+
typeof value.version !== "string" ||
|
|
54
|
+
value.version.length === 0 ||
|
|
55
|
+
typeof value.archivePath !== "string" ||
|
|
56
|
+
value.archivePath.length === 0 ||
|
|
57
|
+
!ROOT_PATTERN.test(value.archiveRoot ?? "") ||
|
|
58
|
+
!ROOT_PATTERN.test(value.artifactRoot ?? "")
|
|
59
|
+
) {
|
|
60
|
+
throw new TypeError(`${label} package declaration is incomplete`);
|
|
61
|
+
}
|
|
62
|
+
return structuredClone(value);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function safeArchiveEntries(listing, verboseListing, label) {
|
|
66
|
+
const entries = listing.split("\n").filter(Boolean);
|
|
67
|
+
const types = verboseListing.split("\n").filter(Boolean);
|
|
68
|
+
if (entries.length === 0 || entries.length !== types.length) {
|
|
69
|
+
throw new Error(`${label} archive listing is incomplete`);
|
|
70
|
+
}
|
|
71
|
+
for (let index = 0; index < entries.length; index += 1) {
|
|
72
|
+
const entry = entries[index];
|
|
73
|
+
const parts = entry.split("/");
|
|
74
|
+
if (
|
|
75
|
+
parts[0] !== "package" ||
|
|
76
|
+
parts.some((part, partIndex) =>
|
|
77
|
+
partIndex === parts.length - 1 && part === ""
|
|
78
|
+
? false
|
|
79
|
+
: part === "" || part === "." || part === "..",
|
|
80
|
+
)
|
|
81
|
+
) {
|
|
82
|
+
throw new Error(`${label} archive contains an unsafe path`);
|
|
83
|
+
}
|
|
84
|
+
if (!["-", "d"].includes(types[index][0])) {
|
|
85
|
+
throw new Error(`${label} archive contains a non-file entry`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async function extractPackage(declaration, destination, definition, label) {
|
|
91
|
+
const archivePath = path.resolve(declaration.archivePath);
|
|
92
|
+
const observedRoot = await sha256File(archivePath);
|
|
93
|
+
if (observedRoot !== declaration.archiveRoot) {
|
|
94
|
+
throw new Error(`${label} archive bytes do not match archiveRoot`);
|
|
95
|
+
}
|
|
96
|
+
await mkdir(destination, { recursive: true });
|
|
97
|
+
const stagedArchiveName = `.buildchain-${definition.key}-authority.tgz`;
|
|
98
|
+
const stagedArchivePath = path.join(
|
|
99
|
+
path.dirname(destination),
|
|
100
|
+
stagedArchiveName,
|
|
101
|
+
);
|
|
102
|
+
const stagedArchiveFile = `../${stagedArchiveName}`;
|
|
103
|
+
await copyFile(archivePath, stagedArchivePath);
|
|
104
|
+
try {
|
|
105
|
+
if ((await sha256File(stagedArchivePath)) !== declaration.archiveRoot) {
|
|
106
|
+
throw new Error(`${label} staged archive bytes do not match archiveRoot`);
|
|
107
|
+
}
|
|
108
|
+
const [{ stdout: listing }, { stdout: verboseListing }] = await Promise.all(
|
|
109
|
+
[
|
|
110
|
+
execFileAsync("tar", ["-tzf", stagedArchiveFile], {
|
|
111
|
+
cwd: destination,
|
|
112
|
+
maxBuffer: 16 * 1024 * 1024,
|
|
113
|
+
}),
|
|
114
|
+
execFileAsync("tar", ["-tvzf", stagedArchiveFile], {
|
|
115
|
+
cwd: destination,
|
|
116
|
+
maxBuffer: 16 * 1024 * 1024,
|
|
117
|
+
}),
|
|
118
|
+
],
|
|
119
|
+
);
|
|
120
|
+
safeArchiveEntries(listing, verboseListing, label);
|
|
121
|
+
await execFileAsync(
|
|
122
|
+
"tar",
|
|
123
|
+
["-xzf", stagedArchiveFile, "--strip-components", "1"],
|
|
124
|
+
{ cwd: destination, maxBuffer: 16 * 1024 * 1024 },
|
|
125
|
+
);
|
|
126
|
+
} finally {
|
|
127
|
+
await rm(stagedArchivePath, { force: true });
|
|
128
|
+
}
|
|
129
|
+
const packageJsonPath = path.join(destination, "package.json");
|
|
130
|
+
const packageJson = JSON.parse(await readFile(packageJsonPath, "utf8"));
|
|
131
|
+
if (
|
|
132
|
+
packageJson.name !== declaration.name ||
|
|
133
|
+
packageJson.version !== declaration.version
|
|
134
|
+
) {
|
|
135
|
+
throw new Error(`${label} extracted package identity does not match`);
|
|
136
|
+
}
|
|
137
|
+
if (definition.packageRoot === "archive") {
|
|
138
|
+
if (declaration.artifactRoot !== declaration.archiveRoot) {
|
|
139
|
+
throw new Error(`${label} package artifactRoot must match archiveRoot`);
|
|
140
|
+
}
|
|
141
|
+
} else {
|
|
142
|
+
const packageManifest = JSON.parse(
|
|
143
|
+
await readFile(path.join(destination, definition.packageRoot), "utf8"),
|
|
144
|
+
);
|
|
145
|
+
const packageCut = packageManifest?.kfdCut?.package;
|
|
146
|
+
if (
|
|
147
|
+
packageCut?.name !== declaration.name ||
|
|
148
|
+
packageCut?.version !== declaration.version ||
|
|
149
|
+
packageCut?.artifactRoot !== declaration.artifactRoot
|
|
150
|
+
) {
|
|
151
|
+
throw new Error(`${label} semantic package identity does not match`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
const destinationRoot = await realpath(destination);
|
|
155
|
+
if (!destinationRoot.endsWith(path.join(...declaration.name.split("/")))) {
|
|
156
|
+
throw new Error(`${label} extraction escaped its package coordinate`);
|
|
157
|
+
}
|
|
158
|
+
return {
|
|
159
|
+
name: declaration.name,
|
|
160
|
+
version: declaration.version,
|
|
161
|
+
archiveRoot: declaration.archiveRoot,
|
|
162
|
+
artifactRoot: declaration.artifactRoot,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
async function importAuthorityRuntime(buildchainRoot) {
|
|
167
|
+
const definition = PACKAGES[0];
|
|
168
|
+
const imported = {};
|
|
169
|
+
for (const [key, relativePath] of Object.entries(definition.modules)) {
|
|
170
|
+
imported[key] = await import(
|
|
171
|
+
pathToFileURL(path.join(buildchainRoot, relativePath)).href
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
const runtime = {
|
|
175
|
+
createAdopterDeliveryGate:
|
|
176
|
+
imported.adopterDeliveryGate.createAdopterDeliveryGate,
|
|
177
|
+
createPackageArtifactProfile:
|
|
178
|
+
imported.adopterDeliveryGate.createPackageArtifactProfile,
|
|
179
|
+
qualifyBuildchainDeliveryInfrastructureBootstrap:
|
|
180
|
+
imported.bootstrap.qualifyBuildchainDeliveryInfrastructureBootstrap,
|
|
181
|
+
createBuildchainDeliveryInfrastructureInstanceManifest:
|
|
182
|
+
imported.infrastructure
|
|
183
|
+
.createBuildchainDeliveryInfrastructureInstanceManifest,
|
|
184
|
+
verifyBuildchainDeliveryInfrastructureInstance:
|
|
185
|
+
imported.infrastructure.verifyBuildchainDeliveryInfrastructureInstance,
|
|
186
|
+
createKfdAdopterCategoryProtocolDriver:
|
|
187
|
+
imported.kfdCategoryDriver.createKfdAdopterCategoryProtocolDriver,
|
|
188
|
+
};
|
|
189
|
+
for (const [name, implementation] of Object.entries(runtime)) {
|
|
190
|
+
if (typeof implementation !== "function") {
|
|
191
|
+
throw new Error(`published Buildchain authority is missing ${name}`);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return runtime;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export async function loadPublishedBuildchainDeliveryAuthority({
|
|
198
|
+
buildchain,
|
|
199
|
+
kfd,
|
|
200
|
+
} = {}) {
|
|
201
|
+
const declarations = {
|
|
202
|
+
buildchain: exactDeclaration(
|
|
203
|
+
buildchain,
|
|
204
|
+
"@kungfu-tech/buildchain",
|
|
205
|
+
"Buildchain authority",
|
|
206
|
+
),
|
|
207
|
+
kfd: exactDeclaration(kfd, "@kungfu-tech/kfd", "KFD authority"),
|
|
208
|
+
};
|
|
209
|
+
const temporaryRoot = await mkdtemp(
|
|
210
|
+
path.join(tmpdir(), "buildchain-published-delivery-authority-"),
|
|
211
|
+
);
|
|
212
|
+
let retained = false;
|
|
213
|
+
try {
|
|
214
|
+
const identities = {};
|
|
215
|
+
for (const definition of PACKAGES) {
|
|
216
|
+
identities[definition.key] = await extractPackage(
|
|
217
|
+
declarations[definition.key],
|
|
218
|
+
path.join(temporaryRoot, "node_modules", ...definition.name.split("/")),
|
|
219
|
+
definition,
|
|
220
|
+
`${definition.key} authority`,
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
const authorityRuntime = await importAuthorityRuntime(
|
|
224
|
+
path.join(temporaryRoot, "node_modules", ...PACKAGES[0].name.split("/")),
|
|
225
|
+
);
|
|
226
|
+
const authority = {
|
|
227
|
+
schemaVersion: 1,
|
|
228
|
+
contract: PUBLISHED_DELIVERY_AUTHORITY_CONTRACT,
|
|
229
|
+
packages: identities,
|
|
230
|
+
moduleCoordinates: structuredClone(PACKAGES[0].modules),
|
|
231
|
+
qualifying: false,
|
|
232
|
+
selfCertified: false,
|
|
233
|
+
releaseAuthorized: false,
|
|
234
|
+
finalAuthority:
|
|
235
|
+
"caller-bound-public-npm-archive-bytes-and-package-identity",
|
|
236
|
+
};
|
|
237
|
+
authority.authorityRoot = adopterDeliveryGateDigest(authority);
|
|
238
|
+
retained = true;
|
|
239
|
+
return {
|
|
240
|
+
...authority,
|
|
241
|
+
authorityRuntime,
|
|
242
|
+
temporaryRoot,
|
|
243
|
+
async dispose() {
|
|
244
|
+
await rm(temporaryRoot, { recursive: true, force: true });
|
|
245
|
+
},
|
|
246
|
+
};
|
|
247
|
+
} finally {
|
|
248
|
+
if (!retained) await rm(temporaryRoot, { recursive: true, force: true });
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
export async function withPublishedBuildchainDeliveryAuthority(
|
|
253
|
+
declarations,
|
|
254
|
+
operation,
|
|
255
|
+
) {
|
|
256
|
+
if (typeof operation !== "function") {
|
|
257
|
+
throw new TypeError("published authority operation must be a function");
|
|
258
|
+
}
|
|
259
|
+
const authority =
|
|
260
|
+
await loadPublishedBuildchainDeliveryAuthority(declarations);
|
|
261
|
+
try {
|
|
262
|
+
return await operation(authority);
|
|
263
|
+
} finally {
|
|
264
|
+
await authority.dispose();
|
|
265
|
+
}
|
|
266
|
+
}
|
|
@@ -439,11 +439,17 @@ function mergeAuthoritativePassportBase(passport, basePassport = undefined, { re
|
|
|
439
439
|
kfd3: basePassport.evidence?.kfd3 || passport.evidence?.kfd3 || "",
|
|
440
440
|
},
|
|
441
441
|
};
|
|
442
|
-
for (const key of [
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
442
|
+
for (const key of [
|
|
443
|
+
"versionImpact",
|
|
444
|
+
"surfaceImpacts",
|
|
445
|
+
"promotionRouting",
|
|
446
|
+
"v4ConsumerPolicy",
|
|
447
|
+
"v4RuntimeResume",
|
|
448
|
+
"transaction",
|
|
449
|
+
"trustedPublishing",
|
|
450
|
+
"distTagPromotion",
|
|
451
|
+
])
|
|
452
|
+
if (basePassport[key] !== undefined) merged[key] = basePassport[key];
|
|
447
453
|
if (basePassport.controllerReceipts !== undefined) {
|
|
448
454
|
merged.controllerReceipts = basePassport.controllerReceipts;
|
|
449
455
|
}
|
|
@@ -1162,6 +1168,18 @@ function normalizeV4RuntimeResumeEvidence(value, expected = {}) {
|
|
|
1162
1168
|
};
|
|
1163
1169
|
}
|
|
1164
1170
|
|
|
1171
|
+
function v4RuntimeResumeSourceSha(release, fallback = "") {
|
|
1172
|
+
const builtSourceSha = releaseField(
|
|
1173
|
+
release || {},
|
|
1174
|
+
"builtSourceSha",
|
|
1175
|
+
"built_source_sha",
|
|
1176
|
+
);
|
|
1177
|
+
return release?.treeEquivalent === true && builtSourceSha
|
|
1178
|
+
? builtSourceSha
|
|
1179
|
+
: fallback;
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
|
|
1165
1183
|
function prepareBuildEvidence({
|
|
1166
1184
|
buildSummary,
|
|
1167
1185
|
buildFacts,
|
|
@@ -1317,7 +1335,7 @@ export function createReleasePassport(options = {}) {
|
|
|
1317
1335
|
const { promotion, buildEvidence } = preparePromotionBuild(options);
|
|
1318
1336
|
const normalizedV4RuntimeResume = normalizeV4RuntimeResumeEvidence(v4RuntimeResumeEvidence, {
|
|
1319
1337
|
repository,
|
|
1320
|
-
sourceSha,
|
|
1338
|
+
sourceSha: v4RuntimeResumeSourceSha(release, sourceSha),
|
|
1321
1339
|
resumeRuntimeSha: promotion.routing?.runtime?.resolvedSha || "",
|
|
1322
1340
|
consumerPolicyReceiptRoot: promotion.consumerPolicy?.certification?.receiptRoot || "",
|
|
1323
1341
|
});
|
|
@@ -2302,7 +2320,7 @@ function validateV4RuntimeResumePassportSection({ passport, issues }) {
|
|
|
2302
2320
|
receipt: evidence.authorization,
|
|
2303
2321
|
receiptRoot: evidence.authorizationRoot,
|
|
2304
2322
|
repository: passport?.product?.repository || "",
|
|
2305
|
-
sourceSha: passport?.release?.sourceSha || "",
|
|
2323
|
+
sourceSha: v4RuntimeResumeSourceSha(passport?.release, passport?.release?.sourceSha || ""),
|
|
2306
2324
|
runtimeSha: passport?.promotionRouting?.runtime?.resolvedSha || "",
|
|
2307
2325
|
consumerPolicyReceiptRoot,
|
|
2308
2326
|
});
|
|
@@ -2313,7 +2331,7 @@ function validateV4RuntimeResumePassportSection({ passport, issues }) {
|
|
|
2313
2331
|
lineage: evidence.lineage,
|
|
2314
2332
|
lineageRoot: evidence.lineageRoot,
|
|
2315
2333
|
repository: passport?.product?.repository || "",
|
|
2316
|
-
sourceSha: passport?.release?.sourceSha || "",
|
|
2334
|
+
sourceSha: v4RuntimeResumeSourceSha(passport?.release, passport?.release?.sourceSha || ""),
|
|
2317
2335
|
resumeRuntimeSha: passport?.promotionRouting?.runtime?.resolvedSha || "",
|
|
2318
2336
|
consumerPolicyReceiptRoot,
|
|
2319
2337
|
});
|
|
@@ -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) {
|