@kungfu-tech/buildchain 4.0.2-alpha.29 → 4.0.2-alpha.32
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/architecture/agent-change-map.md +6 -1
- package/architecture/internal-capabilities.json +5 -2
- package/architecture/maintainability-debt.json +91 -59
- package/architecture/maintainability-policy.json +22 -23
- package/architecture/v4-architecture-constitution.md +23 -20
- package/architecture/v4-partial-mutation-recovery-qualification.json +4 -1
- package/architecture/v4-provider-operation-journal-contract.json +5 -2
- package/architecture/v4-release-activation-shadow-domain.json +5 -2
- package/architecture/v4-release-topology.json +17 -2
- package/architecture/v4-rust-wasm-production-authority.json +57 -0
- package/architecture/v4-stable-publication-fence.json +5 -2
- package/bin/buildchain.mjs +7 -7
- package/contracts/dev-delivery-authority-v2.schema.json +16 -2
- package/dist/site/buildchain-contract.json +6 -6
- package/dist/site/buildchain-site.json +44 -8
- package/dist/site/capability-registry.json +1 -1
- package/dist/site/kfd-claims.json +17 -5
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +1 -1
- package/dist/site/node-api-registry.json +32 -32
- package/dist/site/page-registry.json +39 -3
- package/dist/site/public-surface-audit.json +7 -3
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/schemas/dev-delivery-authority-v2.schema.json +16 -2
- package/dist/site/site-manifest.json +5 -5
- package/dist/site/workflow-registry.json +4 -4
- package/docs/node-api-reference.md +64 -64
- package/docs/v4-rust-wasm-production-authority.md +58 -0
- package/package.json +5 -3
- package/packages/core/buildchain-v4-domain.wasm +0 -0
- package/packages/core/dev-delivery-candidate-identity.js +26 -10
- package/packages/core/dev-delivery-warrant-state.js +3 -4
- package/packages/core/dev-delivery-warrant.js +12 -2
- package/packages/core/release-tail-provider-plane.js +68 -1048
- package/packages/core/v4-canonical-contracts.js +9 -75
- package/packages/core/v4-domain-wasm-artifact.js +7 -0
- package/packages/core/v4-domain-wasm.js +216 -0
- package/packages/core/v4-partial-mutation-recovery-qualification.js +9 -386
- package/packages/core/v4-product-publication.js +18 -384
- 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/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-v4-release-topology.mjs +50 -25
- 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.mjs +7 -2
- package/scripts/generate-v4-universal-workflow-facades.mjs +8 -3
- package/scripts/github-output.mjs +31 -0
- package/templates/native-dev-delivery.yml +4 -7
|
@@ -83,6 +83,13 @@ function rootedPathSet(paths) {
|
|
|
83
83
|
.digest("hex")}`;
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
+
function fileSha256(relative) {
|
|
87
|
+
return `sha256:${crypto
|
|
88
|
+
.createHash("sha256")
|
|
89
|
+
.update(fs.readFileSync(path.join(root, relative)))
|
|
90
|
+
.digest("hex")}`;
|
|
91
|
+
}
|
|
92
|
+
|
|
86
93
|
function productionFiles(relative, extensions) {
|
|
87
94
|
const absolute = path.join(root, relative);
|
|
88
95
|
if (!fs.existsSync(absolute)) return [];
|
|
@@ -128,6 +135,12 @@ export function discoverV4ReleaseAuthorityClosure() {
|
|
|
128
135
|
/(?:createV4ReleaseReceipt|release-receipt\.json|V4_RELEASE_RECEIPT_CONTRACT)/u,
|
|
129
136
|
);
|
|
130
137
|
const privilegedModules = discoverStaticModuleClosure(PRIVILEGED_ENTRYPOINTS);
|
|
138
|
+
const rustWasmArtifact = "packages/core/buildchain-v4-domain.wasm";
|
|
139
|
+
const rustWasmDistributions = [
|
|
140
|
+
"actions/promote-buildchain-ref/dist/buildchain-v4-domain.wasm",
|
|
141
|
+
"actions/release-tail/dist/buildchain-v4-domain.wasm",
|
|
142
|
+
"actions/v4-release-candidate-promote/dist/buildchain-v4-domain.wasm",
|
|
143
|
+
];
|
|
131
144
|
const legacyEngineModules = productionFiles(
|
|
132
145
|
"actions/promote-buildchain-ref",
|
|
133
146
|
[".js", ".mjs", ".cjs"],
|
|
@@ -153,6 +166,17 @@ export function discoverV4ReleaseAuthorityClosure() {
|
|
|
153
166
|
modules: privilegedModules,
|
|
154
167
|
root: rootedPathSet(privilegedModules),
|
|
155
168
|
},
|
|
169
|
+
rustWasmAuthority: {
|
|
170
|
+
loader: "packages/core/v4-domain-wasm.js",
|
|
171
|
+
metadata: "packages/core/v4-domain-wasm-artifact.js",
|
|
172
|
+
artifact: rustWasmArtifact,
|
|
173
|
+
artifactRoot: fileSha256(rustWasmArtifact),
|
|
174
|
+
distributedArtifacts: rustWasmDistributions,
|
|
175
|
+
byteIdenticalDistributions: rustWasmDistributions.every(
|
|
176
|
+
(relative) => fileSha256(relative) === fileSha256(rustWasmArtifact),
|
|
177
|
+
),
|
|
178
|
+
fallbackWriterCount: 0,
|
|
179
|
+
},
|
|
156
180
|
legacyEngineModules,
|
|
157
181
|
};
|
|
158
182
|
}
|
|
@@ -183,31 +207,32 @@ function workflowSnapshot(relative) {
|
|
|
183
207
|
const jobs = document.jobs
|
|
184
208
|
.filter((job) => job.id !== "universal-bootstrap")
|
|
185
209
|
.map((job) => {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
210
|
+
const block = jobBlock(source, job.id);
|
|
211
|
+
const uses = job.uses || null;
|
|
212
|
+
return {
|
|
213
|
+
id: job.id,
|
|
214
|
+
kind: uses ? "reusable-call" : "runner",
|
|
215
|
+
uses,
|
|
216
|
+
permissions: {
|
|
217
|
+
contents: permission(block, "contents"),
|
|
218
|
+
idToken: permission(block, "id-token"),
|
|
219
|
+
},
|
|
220
|
+
carriers: {
|
|
221
|
+
artifactDownload: /uses:\s+actions\/download-artifact@/u.test(block),
|
|
222
|
+
artifactUpload: /uses:\s+actions\/upload-artifact@/u.test(block),
|
|
223
|
+
jobOutput: /GITHUB_OUTPUT/u.test(block),
|
|
224
|
+
},
|
|
225
|
+
mutationSignals: [
|
|
226
|
+
/contents:\s*write/u.test(block) && "contents-write",
|
|
227
|
+
/id-token:\s*write/u.test(block) && "oidc-write",
|
|
228
|
+
/(?:promote-buildchain-ref|v4-release-candidate-promote)/u.test(
|
|
229
|
+
block,
|
|
230
|
+
) && "promotion-runtime",
|
|
231
|
+
/(?:git push|npm publish|gh release (?:create|upload))/u.test(
|
|
232
|
+
block,
|
|
233
|
+
) && "direct-publication-command",
|
|
234
|
+
].filter(Boolean),
|
|
235
|
+
};
|
|
211
236
|
});
|
|
212
237
|
return {
|
|
213
238
|
path: relative,
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
|
|
5
|
+
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
6
|
+
const destination = path.resolve(process.argv[2] || "");
|
|
7
|
+
if (!process.argv[2] || path.basename(destination) !== "dist") {
|
|
8
|
+
throw new Error("usage: copy-v4-domain-wasm.mjs ACTION_DIST_DIRECTORY");
|
|
9
|
+
}
|
|
10
|
+
fs.mkdirSync(destination, { recursive: true });
|
|
11
|
+
fs.copyFileSync(
|
|
12
|
+
path.join(root, "packages", "core", "buildchain-v4-domain.wasm"),
|
|
13
|
+
path.join(destination, "buildchain-v4-domain.wasm"),
|
|
14
|
+
);
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
1
|
import path from "node:path";
|
|
3
2
|
import {
|
|
4
3
|
acquireDevDeliveryLandingWarrant,
|
|
@@ -66,6 +65,7 @@ function submitCandidate(state, options) {
|
|
|
66
65
|
{
|
|
67
66
|
pullRequestNumber: options.pullRequestNumber,
|
|
68
67
|
sourceHead: options.sourceHead,
|
|
68
|
+
sourceRoot: options.sourceRoot,
|
|
69
69
|
assignmentRoot: options.assignmentRoot,
|
|
70
70
|
initiativeRoot: options.initiativeRoot,
|
|
71
71
|
sourceIdentityRoot: options.sourceIdentityRoot,
|
|
@@ -276,16 +276,16 @@ export function devDeliveryAuthorityCliOptions(
|
|
|
276
276
|
"source-head",
|
|
277
277
|
environment.BUILDCHAIN_DEV_DELIVERY_SOURCE_HEAD,
|
|
278
278
|
),
|
|
279
|
-
|
|
279
|
+
sourceRoot: flag(
|
|
280
280
|
rest,
|
|
281
|
-
"
|
|
282
|
-
environment.
|
|
283
|
-
|
|
284
|
-
initiativeRoot: flag(
|
|
285
|
-
rest,
|
|
286
|
-
"initiative-root",
|
|
287
|
-
environment.BUILDCHAIN_DEV_DELIVERY_INITIATIVE_ROOT,
|
|
281
|
+
"source-root",
|
|
282
|
+
environment.BUILDCHAIN_WORK_SOURCE_ROOT ||
|
|
283
|
+
environment.BUILDCHAIN_DEV_DELIVERY_SOURCE_ROOT,
|
|
288
284
|
),
|
|
285
|
+
// Retired roots remain readable in persisted historical candidates.
|
|
286
|
+
// New authority submissions accept only the Work sourceRoot above.
|
|
287
|
+
// Retired CLI flags are intentionally ignored by this parser.
|
|
288
|
+
// This prevents producers from reconstructing obsolete identities.
|
|
289
289
|
sourceIdentityRoot: flag(
|
|
290
290
|
rest,
|
|
291
291
|
"source-identity-root",
|
|
@@ -479,6 +479,7 @@ function cliInput(args) {
|
|
|
479
479
|
export function sourceProofReuseCli(args = process.argv.slice(2)) {
|
|
480
480
|
const [command = "", ...rest] = args;
|
|
481
481
|
const input = cliInput(rest);
|
|
482
|
+
if (command === "predicates") return sourceQualificationPredicates(input);
|
|
482
483
|
if (command === "seal") {
|
|
483
484
|
const proof = sealSourceQualificationProof(input);
|
|
484
485
|
writeJson(input.outputPath, proof);
|
|
@@ -527,7 +528,7 @@ export function sourceProofReuseCli(args = process.argv.slice(2)) {
|
|
|
527
528
|
return decision;
|
|
528
529
|
}
|
|
529
530
|
throw new Error(
|
|
530
|
-
"usage: dev-delivery-source-proof-reuse.mjs <seal|verify> [options]",
|
|
531
|
+
"usage: dev-delivery-source-proof-reuse.mjs <predicates|seal|verify> [options]",
|
|
531
532
|
);
|
|
532
533
|
}
|
|
533
534
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
1
2
|
export function flag(args, name, fallback = "") {
|
|
2
3
|
const index = args.indexOf(`--${name}`);
|
|
3
4
|
return index === -1 ? fallback : args[index + 1] || "";
|
|
4
5
|
}
|
|
5
|
-
|
|
6
6
|
export function hasFlag(args, name) {
|
|
7
7
|
return args.includes(`--${name}`);
|
|
8
8
|
}
|
|
@@ -79,16 +79,16 @@ export function devDeliveryCliOptions(args = [], environment = process.env) {
|
|
|
79
79
|
"source-head",
|
|
80
80
|
environment.BUILDCHAIN_DEV_DELIVERY_SOURCE_HEAD,
|
|
81
81
|
),
|
|
82
|
-
|
|
83
|
-
rest,
|
|
84
|
-
"expected-source-head",
|
|
85
|
-
environment.BUILDCHAIN_DEV_DELIVERY_EXPECTED_SOURCE_HEAD,
|
|
86
|
-
),
|
|
87
|
-
observedSourceHead: flag(
|
|
82
|
+
sourceRoot: flag(
|
|
88
83
|
rest,
|
|
89
|
-
"
|
|
90
|
-
environment.
|
|
84
|
+
"source-root",
|
|
85
|
+
environment.BUILDCHAIN_WORK_SOURCE_ROOT ||
|
|
86
|
+
environment.BUILDCHAIN_DEV_DELIVERY_SOURCE_ROOT ||
|
|
87
|
+
sourceRootFromGitHubEvent(environment),
|
|
91
88
|
),
|
|
89
|
+
// prettier-ignore
|
|
90
|
+
...{ expectedSourceHead: flag(rest, "expected-source-head", environment.BUILDCHAIN_DEV_DELIVERY_EXPECTED_SOURCE_HEAD), observedSourceHead: flag(rest, "observed-source-head", environment.BUILDCHAIN_DEV_DELIVERY_OBSERVED_SOURCE_HEAD) },
|
|
91
|
+
|
|
92
92
|
assignmentRoot: flag(
|
|
93
93
|
rest,
|
|
94
94
|
"assignment-root",
|
|
@@ -291,3 +291,8 @@ export function devDeliveryCliOptions(args = [], environment = process.env) {
|
|
|
291
291
|
json: hasFlag(rest, "json"),
|
|
292
292
|
};
|
|
293
293
|
}
|
|
294
|
+
|
|
295
|
+
// prettier-ignore
|
|
296
|
+
function sourceRootFromGitHubEvent(environment) {
|
|
297
|
+
try { const event = JSON.parse(fs.readFileSync(environment.GITHUB_EVENT_PATH, "utf8")); return event.client_payload?.candidate?.sourceRoot || JSON.parse(event.inputs?.["native-roots-json"] || "{}").sourceRoot || ""; } catch { return ""; }
|
|
298
|
+
}
|
|
@@ -206,8 +206,13 @@ function transitionFor(command, queue, options) {
|
|
|
206
206
|
"pullRequestNumber",
|
|
207
207
|
),
|
|
208
208
|
sourceHead: exactSha(options.sourceHead, "sourceHead"),
|
|
209
|
-
|
|
210
|
-
|
|
209
|
+
...(options.sourceRoot ? { sourceRoot: options.sourceRoot } : {}),
|
|
210
|
+
...(options.assignmentRoot
|
|
211
|
+
? { assignmentRoot: options.assignmentRoot }
|
|
212
|
+
: {}),
|
|
213
|
+
...(options.initiativeRoot
|
|
214
|
+
? { initiativeRoot: options.initiativeRoot }
|
|
215
|
+
: {}),
|
|
211
216
|
sourceIdentityRoot: exactRoot(
|
|
212
217
|
options.sourceIdentityRoot,
|
|
213
218
|
"sourceIdentityRoot",
|
|
@@ -91,8 +91,13 @@ function frozenFacadeSource(relative) {
|
|
|
91
91
|
});
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
|
|
95
|
-
|
|
94
|
+
const mutableFacades = new Set([
|
|
95
|
+
...(contract.migration.channelGeneratedFacades || []),
|
|
96
|
+
".github/workflows/dev-pr-auto-merge.yml",
|
|
97
|
+
]);
|
|
98
|
+
|
|
99
|
+
function isMutableFacade(relative) {
|
|
100
|
+
return mutableFacades.has(relative);
|
|
96
101
|
}
|
|
97
102
|
|
|
98
103
|
function addUniversalInput(source, relative) {
|
|
@@ -200,7 +205,7 @@ function verify(source, relative) {
|
|
|
200
205
|
if (!block.includes("inputs.universal-request-json == ''"))
|
|
201
206
|
fail(`${relative}#${header[1]} can overlap universal execution`);
|
|
202
207
|
}
|
|
203
|
-
if (!
|
|
208
|
+
if (!isMutableFacade(relative)) {
|
|
204
209
|
const expected = migrateV4UniversalWorkflowFacade(
|
|
205
210
|
frozenFacadeSource(relative),
|
|
206
211
|
relative,
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
|
|
4
|
+
function githubOutputRecord(key, value) {
|
|
5
|
+
const normalized = String(value ?? "");
|
|
6
|
+
if (!/[\r\n]/u.test(normalized)) return `${key}=${normalized}\n`;
|
|
7
|
+
const valueLines = normalized.split(/\r\n|\r|\n/u);
|
|
8
|
+
let delimiter = `BUILDCHAIN_OUTPUT_${crypto
|
|
9
|
+
.createHash("sha256")
|
|
10
|
+
.update(`${key}\0${normalized}`)
|
|
11
|
+
.digest("hex")}`;
|
|
12
|
+
while (valueLines.includes(delimiter)) delimiter += "_";
|
|
13
|
+
const separator = normalized.endsWith("\n") ? "" : "\n";
|
|
14
|
+
return `${key}<<${delimiter}\n${normalized}${separator}${delimiter}\n`;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function writeGitHubOutputs(outputs) {
|
|
18
|
+
const outputPath = process.env.GITHUB_OUTPUT;
|
|
19
|
+
if (!outputPath) {
|
|
20
|
+
for (const [key, value] of Object.entries(outputs)) {
|
|
21
|
+
console.log(`${key}=${value}`);
|
|
22
|
+
}
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
fs.appendFileSync(
|
|
26
|
+
outputPath,
|
|
27
|
+
Object.entries(outputs)
|
|
28
|
+
.map(([key, value]) => githubOutputRecord(key, value))
|
|
29
|
+
.join(""),
|
|
30
|
+
);
|
|
31
|
+
}
|
|
@@ -38,11 +38,8 @@ on:
|
|
|
38
38
|
source-patch-root:
|
|
39
39
|
description: "Semantic patch root"
|
|
40
40
|
required: true
|
|
41
|
-
|
|
42
|
-
description: "
|
|
43
|
-
required: true
|
|
44
|
-
initiative-root:
|
|
45
|
-
description: "Parent Initiative root"
|
|
41
|
+
native-roots-json:
|
|
42
|
+
description: "Machine-supplied Work sourceRoot or historical root pair"
|
|
46
43
|
required: true
|
|
47
44
|
plan-root:
|
|
48
45
|
description: "Native qualification plan root"
|
|
@@ -117,8 +114,8 @@ jobs:
|
|
|
117
114
|
delivery-warrant-mode: required
|
|
118
115
|
handoff-workflow-id: native-dev-delivery.yml
|
|
119
116
|
source-workflow-id: ${{ inputs.source-workflow-id || '' }}
|
|
120
|
-
assignment-root: ${{ github.event.client_payload.candidate.assignmentRoot || inputs.
|
|
121
|
-
initiative-root: ${{ github.event.client_payload.candidate.initiativeRoot || inputs.
|
|
117
|
+
assignment-root: ${{ github.event.client_payload.candidate.assignmentRoot || fromJSON(inputs.native-roots-json || '{}').assignmentRoot || '' }}
|
|
118
|
+
initiative-root: ${{ github.event.client_payload.candidate.initiativeRoot || fromJSON(inputs.native-roots-json || '{}').initiativeRoot || '' }}
|
|
122
119
|
source-identity-root: ${{ github.event.client_payload.candidate.sourceIdentityRoot || inputs.source-identity-root }}
|
|
123
120
|
source-patch-root: ${{ github.event.client_payload.candidate.sourcePatchRoot || inputs.source-patch-root }}
|
|
124
121
|
plan-root: ${{ github.event.client_payload.candidate.planRoot || inputs.plan-root }}
|