@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.
Files changed (57) hide show
  1. package/architecture/agent-change-map.md +6 -1
  2. package/architecture/internal-capabilities.json +5 -2
  3. package/architecture/maintainability-debt.json +91 -59
  4. package/architecture/maintainability-policy.json +22 -23
  5. package/architecture/v4-architecture-constitution.md +23 -20
  6. package/architecture/v4-partial-mutation-recovery-qualification.json +4 -1
  7. package/architecture/v4-provider-operation-journal-contract.json +5 -2
  8. package/architecture/v4-release-activation-shadow-domain.json +5 -2
  9. package/architecture/v4-release-topology.json +17 -2
  10. package/architecture/v4-rust-wasm-production-authority.json +57 -0
  11. package/architecture/v4-stable-publication-fence.json +5 -2
  12. package/bin/buildchain.mjs +7 -7
  13. package/contracts/dev-delivery-authority-v2.schema.json +16 -2
  14. package/dist/site/buildchain-contract.json +6 -6
  15. package/dist/site/buildchain-site.json +44 -8
  16. package/dist/site/capability-registry.json +1 -1
  17. package/dist/site/kfd-claims.json +17 -5
  18. package/dist/site/kfd-upstream-aggregate.json +1 -1
  19. package/dist/site/manual-registry.json +1 -1
  20. package/dist/site/node-api-registry.json +32 -32
  21. package/dist/site/page-registry.json +39 -3
  22. package/dist/site/public-surface-audit.json +7 -3
  23. package/dist/site/publication-registry.json +4 -4
  24. package/dist/site/schemas/dev-delivery-authority-v2.schema.json +16 -2
  25. package/dist/site/site-manifest.json +5 -5
  26. package/dist/site/workflow-registry.json +4 -4
  27. package/docs/node-api-reference.md +64 -64
  28. package/docs/v4-rust-wasm-production-authority.md +58 -0
  29. package/package.json +5 -3
  30. package/packages/core/buildchain-v4-domain.wasm +0 -0
  31. package/packages/core/dev-delivery-candidate-identity.js +26 -10
  32. package/packages/core/dev-delivery-warrant-state.js +3 -4
  33. package/packages/core/dev-delivery-warrant.js +12 -2
  34. package/packages/core/release-tail-provider-plane.js +68 -1048
  35. package/packages/core/v4-canonical-contracts.js +9 -75
  36. package/packages/core/v4-domain-wasm-artifact.js +7 -0
  37. package/packages/core/v4-domain-wasm.js +216 -0
  38. package/packages/core/v4-partial-mutation-recovery-qualification.js +9 -386
  39. package/packages/core/v4-product-publication.js +18 -384
  40. package/packages/core/v4-provider-operation-journal.js +18 -487
  41. package/packages/core/v4-provider-readback-idempotency.js +12 -97
  42. package/packages/core/v4-release-activation-shadow.js +13 -500
  43. package/packages/core/v4-release-invocation.js +28 -389
  44. package/packages/core/v4-stable-publication-fence.js +13 -342
  45. package/scripts/build-contract-core.mjs +1 -14
  46. package/scripts/build-v4-domain-wasm.mjs +189 -0
  47. package/scripts/check-action-bundles.mjs +12 -2
  48. package/scripts/check-v4-release-topology.mjs +50 -25
  49. package/scripts/copy-v4-domain-wasm.mjs +14 -0
  50. package/scripts/dev-delivery-authority-command-adapters.mjs +1 -1
  51. package/scripts/dev-delivery-authority.mjs +8 -8
  52. package/scripts/dev-delivery-source-proof-reuse.mjs +2 -1
  53. package/scripts/dev-delivery-warrant-options.mjs +14 -9
  54. package/scripts/dev-delivery-warrant.mjs +7 -2
  55. package/scripts/generate-v4-universal-workflow-facades.mjs +8 -3
  56. package/scripts/github-output.mjs +31 -0
  57. 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
- const block = jobBlock(source, job.id);
187
- const uses = job.uses || null;
188
- return {
189
- id: job.id,
190
- kind: uses ? "reusable-call" : "runner",
191
- uses,
192
- permissions: {
193
- contents: permission(block, "contents"),
194
- idToken: permission(block, "id-token"),
195
- },
196
- carriers: {
197
- artifactDownload: /uses:\s+actions\/download-artifact@/u.test(block),
198
- artifactUpload: /uses:\s+actions\/upload-artifact@/u.test(block),
199
- jobOutput: /GITHUB_OUTPUT/u.test(block),
200
- },
201
- mutationSignals: [
202
- /contents:\s*write/u.test(block) && "contents-write",
203
- /id-token:\s*write/u.test(block) && "oidc-write",
204
- /(?:promote-buildchain-ref|v4-release-candidate-promote)/u.test(
205
- block,
206
- ) && "promotion-runtime",
207
- /(?:git push|npm publish|gh release (?:create|upload))/u.test(block) &&
208
- "direct-publication-command",
209
- ].filter(Boolean),
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
- assignmentRoot: flag(
279
+ sourceRoot: flag(
280
280
  rest,
281
- "assignment-root",
282
- environment.BUILDCHAIN_DEV_DELIVERY_ASSIGNMENT_ROOT,
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
- expectedSourceHead: flag(
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
- "observed-source-head",
90
- environment.BUILDCHAIN_DEV_DELIVERY_OBSERVED_SOURCE_HEAD,
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
- assignmentRoot: exactRoot(options.assignmentRoot, "assignmentRoot"),
210
- initiativeRoot: exactRoot(options.initiativeRoot, "initiativeRoot"),
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
- function isChannelGeneratedFacade(relative) {
95
- return (contract.migration.channelGeneratedFacades || []).includes(relative);
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 (!isChannelGeneratedFacade(relative)) {
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
- assignment-root:
42
- description: "Native Assignment root"
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.assignment-root }}
121
- initiative-root: ${{ github.event.client_payload.candidate.initiativeRoot || inputs.initiative-root }}
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 }}