@kungfu-tech/buildchain 4.0.2-alpha.4 → 4.0.2-alpha.41
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 +66 -7
- package/architecture/ci-lane-change-budget.json +366 -0
- package/architecture/internal-capabilities.json +52 -8
- package/architecture/maintainability-debt.json +148 -92
- 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 +143 -35
- 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 +171 -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 +1451 -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 +222 -69
- package/dist/site/capability-registry.json +4 -4
- package/dist/site/controller-registry.json +50 -13
- package/dist/site/kfd-claims.json +2569 -982
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +13 -13
- package/dist/site/node-api-registry.json +88 -83
- package/dist/site/page-registry.json +204 -51
- package/dist/site/public-surface-audit.json +3207 -1219
- package/dist/site/publication-authority-registry.json +1124 -362
- 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 +17 -17
- package/dist/site/workflow-registry.json +5063 -1659
- package/docs/MAP.md +1 -0
- package/docs/auditable-demo.md +1 -1
- package/docs/cli.md +3 -3
- 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 +129 -129
- package/docs/publication-authority.md +2 -2
- 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 +154 -0
- package/docs/workflow-path-migration.md +109 -0
- package/package.json +10 -6
- 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 +42 -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/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 +29 -0
- package/packages/core/release-tail-provider-plane.js +68 -1048
- package/packages/core/v4-canonical-contracts.js +14 -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 +57 -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 +214 -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 +7 -5
- package/scripts/generate-site-bundle.mjs +11 -11
- package/scripts/generate-v4-universal-workflow-facades.mjs +458 -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/release-asset-client.mjs +91 -0
- package/scripts/release-candidate-resolver.mjs +17 -18
- package/scripts/resume-from-candidate-run.mjs +1 -1
- package/scripts/source-verification-evidence.mjs +344 -0
- package/scripts/stable-candidate-qualification.mjs +1 -1
- package/scripts/universal-facade-maintainability.mjs +82 -0
- package/scripts/v4-product-publication-intent.mjs +121 -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 +618 -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,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { V4DomainWasmFault, invokeV4DomainWasm } from "./v4-domain-wasm.js";
|
|
2
2
|
|
|
3
3
|
export const V4_CANONICAL_JSON_CONTRACT = "buildchain-canonical-json/v1";
|
|
4
4
|
export const V4_EVENT_ENVELOPE_CONTRACT = "buildchain-v4-event-envelope/v1";
|
|
@@ -28,6 +28,7 @@ const ROOT_DOMAINS = new Set([
|
|
|
28
28
|
"stage-capsule-quarantine",
|
|
29
29
|
"stage-capsule-resume-observation",
|
|
30
30
|
"stage-capsule-resume-plan",
|
|
31
|
+
"source-verification-evidence",
|
|
31
32
|
"stage-capsule-artifact-manifest",
|
|
32
33
|
"stage-capsule-artifact-content",
|
|
33
34
|
"stage-capsule-fault-campaign",
|
|
@@ -56,6 +57,10 @@ const ROOT_DOMAINS = new Set([
|
|
|
56
57
|
"stable-publication-fence",
|
|
57
58
|
"partial-mutation-recovery-checkpoint",
|
|
58
59
|
"partial-mutation-recovery-plan",
|
|
60
|
+
"v4-product-required-artifacts",
|
|
61
|
+
"v4-product-publication-intent",
|
|
62
|
+
"v4-product-publication-operation",
|
|
63
|
+
"v4-product-publication-plan",
|
|
59
64
|
"tail-reseal-plan",
|
|
60
65
|
"tail-reseal-admission",
|
|
61
66
|
"tail-reseal-artifact-files",
|
|
@@ -106,89 +111,23 @@ function exactKeys(value, keys, path) {
|
|
|
106
111
|
fault("invalid-envelope-shape", path, `${path} keys are not canonical`);
|
|
107
112
|
}
|
|
108
113
|
|
|
109
|
-
function
|
|
110
|
-
if (value === null || typeof value === "boolean") return value;
|
|
111
|
-
if (typeof value === "string") {
|
|
112
|
-
for (let index = 0; index < value.length; index += 1) {
|
|
113
|
-
const code = value.charCodeAt(index);
|
|
114
|
-
if (code >= 0xd800 && code <= 0xdbff) {
|
|
115
|
-
const next = value.charCodeAt(index + 1);
|
|
116
|
-
if (!(next >= 0xdc00 && next <= 0xdfff))
|
|
117
|
-
fault(
|
|
118
|
-
"unsupported-string",
|
|
119
|
-
path,
|
|
120
|
-
`${path} contains an unpaired surrogate`,
|
|
121
|
-
);
|
|
122
|
-
index += 1;
|
|
123
|
-
} else if (code >= 0xdc00 && code <= 0xdfff) {
|
|
124
|
-
fault(
|
|
125
|
-
"unsupported-string",
|
|
126
|
-
path,
|
|
127
|
-
`${path} contains an unpaired surrogate`,
|
|
128
|
-
);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
return value;
|
|
132
|
-
}
|
|
133
|
-
if (typeof value === "number") {
|
|
134
|
-
if (!Number.isSafeInteger(value) || Object.is(value, -0))
|
|
135
|
-
fault(
|
|
136
|
-
"unsupported-number",
|
|
137
|
-
path,
|
|
138
|
-
`${path} must be a safe base-10 integer and must not be negative zero`,
|
|
139
|
-
);
|
|
140
|
-
return value;
|
|
141
|
-
}
|
|
142
|
-
if (!value || typeof value !== "object")
|
|
143
|
-
fault("unsupported-json-value", path, `${path} is not a JSON value`);
|
|
144
|
-
if (active.has(value))
|
|
145
|
-
fault("cyclic-json-value", path, `${path} contains a cycle`);
|
|
146
|
-
active.add(value);
|
|
114
|
+
function wasm(operation, payload) {
|
|
147
115
|
try {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
);
|
|
152
|
-
const prototype = Object.getPrototypeOf(value);
|
|
153
|
-
if (prototype !== Object.prototype && prototype !== null)
|
|
154
|
-
fault("unsupported-json-value", path, `${path} must be a plain object`);
|
|
155
|
-
const result = Object.create(null);
|
|
156
|
-
for (const key of Object.keys(value).sort((left, right) =>
|
|
157
|
-
left < right ? -1 : left > right ? 1 : 0,
|
|
158
|
-
)) {
|
|
159
|
-
if (!ASCII_KEY_PATTERN.test(key))
|
|
160
|
-
fault(
|
|
161
|
-
"unsupported-object-key",
|
|
162
|
-
`${path}/${key}`,
|
|
163
|
-
"object keys must be non-empty printable ASCII",
|
|
164
|
-
);
|
|
165
|
-
result[key] = canonicalize(value[key], `${path}/${key}`, active);
|
|
116
|
+
return invokeV4DomainWasm(operation, payload);
|
|
117
|
+
} catch (error) {
|
|
118
|
+
if (error instanceof V4DomainWasmFault) {
|
|
119
|
+
fault(error.code, error.path, error.message);
|
|
166
120
|
}
|
|
167
|
-
|
|
168
|
-
} finally {
|
|
169
|
-
active.delete(value);
|
|
121
|
+
throw error;
|
|
170
122
|
}
|
|
171
123
|
}
|
|
172
124
|
|
|
173
125
|
export function v4CanonicalBytes(value) {
|
|
174
|
-
return Buffer.from(
|
|
175
|
-
`${JSON.stringify(canonicalize(value, "$", new Set()))}\n`,
|
|
176
|
-
"utf8",
|
|
177
|
-
);
|
|
126
|
+
return Buffer.from(wasm("canonical-json", value).canonicalUtf8, "utf8");
|
|
178
127
|
}
|
|
179
128
|
|
|
180
129
|
export function v4ContentRoot(domain, value) {
|
|
181
|
-
|
|
182
|
-
fault(
|
|
183
|
-
"unsupported-root-domain",
|
|
184
|
-
"$.domain",
|
|
185
|
-
`unsupported root domain: ${domain}`,
|
|
186
|
-
);
|
|
187
|
-
const hash = crypto.createHash("sha256");
|
|
188
|
-
hash.update(domain, "ascii");
|
|
189
|
-
hash.update(Buffer.from([0]));
|
|
190
|
-
hash.update(v4CanonicalBytes(value));
|
|
191
|
-
return `sha256:${hash.digest("hex")}`;
|
|
130
|
+
return wasm("content-root", { domain, value }).root;
|
|
192
131
|
}
|
|
193
132
|
|
|
194
133
|
export function validateV4Root(value, path = "$.root") {
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Generated by scripts/build-v4-domain-wasm.mjs.
|
|
2
|
+
export const V4_DOMAIN_WASM_ABI_VERSION = 1;
|
|
3
|
+
export const V4_DOMAIN_WASM_RUSTC = "rustc 1.96.0 (ac68faa20 2026-05-25)";
|
|
4
|
+
export const V4_DOMAIN_WASM_SOURCE_SHA256 =
|
|
5
|
+
"07d45b2767e22007d3d41fa32c8a2dba28d9c88c11a2b28863e82d54be3a2933";
|
|
6
|
+
export const V4_DOMAIN_WASM_SHA256 =
|
|
7
|
+
"b37c330e9366b7e9cf9dc4b7573b1e9495212dd9520e8b8ec6cdc3fd0ab7cafd";
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
V4_DOMAIN_WASM_ABI_VERSION,
|
|
6
|
+
V4_DOMAIN_WASM_SHA256,
|
|
7
|
+
} from "./v4-domain-wasm-artifact.js";
|
|
8
|
+
|
|
9
|
+
export const V4_DOMAIN_WASM_REQUEST_CONTRACT =
|
|
10
|
+
"kungfu-buildchain-v4-domain-wasm-request/v1";
|
|
11
|
+
export const V4_DOMAIN_WASM_RESPONSE_CONTRACT =
|
|
12
|
+
"kungfu-buildchain-v4-domain-wasm-response/v1";
|
|
13
|
+
|
|
14
|
+
const WASM_URL = new URL("./buildchain-v4-domain.wasm", import.meta.url);
|
|
15
|
+
const REQUIRED_EXPORTS = [
|
|
16
|
+
"memory",
|
|
17
|
+
"buildchain_v4_wasm_abi_version",
|
|
18
|
+
"buildchain_v4_wasm_alloc",
|
|
19
|
+
"buildchain_v4_wasm_dealloc",
|
|
20
|
+
"buildchain_v4_wasm_invoke",
|
|
21
|
+
"buildchain_v4_wasm_response_pointer",
|
|
22
|
+
"buildchain_v4_wasm_response_length",
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
let loaded;
|
|
26
|
+
|
|
27
|
+
export class V4DomainWasmFault extends Error {
|
|
28
|
+
constructor(fault) {
|
|
29
|
+
super(fault?.message || "Rust/WASM domain request failed");
|
|
30
|
+
this.name = "V4DomainWasmFault";
|
|
31
|
+
this.fault = fault;
|
|
32
|
+
this.code = fault?.code || "rust-wasm-domain-failed";
|
|
33
|
+
this.path = fault?.path || "$";
|
|
34
|
+
this.retry = fault?.retry || "stop";
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function failClosed(message, cause) {
|
|
39
|
+
const error = new Error(`Buildchain v4 Rust/WASM authority: ${message}`);
|
|
40
|
+
error.code = "rust-wasm-authority-unavailable";
|
|
41
|
+
error.cause = cause;
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function invalidTransport(code, path, message) {
|
|
46
|
+
throw new V4DomainWasmFault({ code, path, message, retry: "stop" });
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function validateJsonTransport(value, path, active) {
|
|
50
|
+
if (value === null || typeof value === "boolean") return;
|
|
51
|
+
if (typeof value === "string") {
|
|
52
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
53
|
+
const code = value.charCodeAt(index);
|
|
54
|
+
if (code >= 0xd800 && code <= 0xdbff) {
|
|
55
|
+
const next = value.charCodeAt(index + 1);
|
|
56
|
+
if (!(next >= 0xdc00 && next <= 0xdfff)) {
|
|
57
|
+
invalidTransport(
|
|
58
|
+
"unsupported-string",
|
|
59
|
+
path,
|
|
60
|
+
`${path} contains an unpaired surrogate`,
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
index += 1;
|
|
64
|
+
} else if (code >= 0xdc00 && code <= 0xdfff) {
|
|
65
|
+
invalidTransport(
|
|
66
|
+
"unsupported-string",
|
|
67
|
+
path,
|
|
68
|
+
`${path} contains an unpaired surrogate`,
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (typeof value === "number") {
|
|
75
|
+
if (!Number.isSafeInteger(value) || Object.is(value, -0)) {
|
|
76
|
+
invalidTransport(
|
|
77
|
+
"unsupported-number",
|
|
78
|
+
path,
|
|
79
|
+
`${path} must be a safe base-10 integer and must not be negative zero`,
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (!value || typeof value !== "object") {
|
|
85
|
+
invalidTransport(
|
|
86
|
+
"unsupported-json-value",
|
|
87
|
+
path,
|
|
88
|
+
`${path} is not a JSON value`,
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
if (active.has(value)) {
|
|
92
|
+
invalidTransport("cyclic-json-value", path, `${path} contains a cycle`);
|
|
93
|
+
}
|
|
94
|
+
active.add(value);
|
|
95
|
+
try {
|
|
96
|
+
if (Array.isArray(value)) {
|
|
97
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
98
|
+
validateJsonTransport(value[index], `${path}/${index}`, active);
|
|
99
|
+
}
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
const prototype = Object.getPrototypeOf(value);
|
|
103
|
+
if (prototype !== Object.prototype && prototype !== null) {
|
|
104
|
+
invalidTransport(
|
|
105
|
+
"unsupported-json-value",
|
|
106
|
+
path,
|
|
107
|
+
`${path} must be a plain object`,
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
for (const key of Object.keys(value)) {
|
|
111
|
+
if (!/^[\x20-\x7e]+$/u.test(key)) {
|
|
112
|
+
invalidTransport(
|
|
113
|
+
"unsupported-object-key",
|
|
114
|
+
`${path}/${key}`,
|
|
115
|
+
"object keys must be non-empty printable ASCII",
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
validateJsonTransport(value[key], `${path}/${key}`, active);
|
|
119
|
+
}
|
|
120
|
+
} finally {
|
|
121
|
+
active.delete(value);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function loadAuthority() {
|
|
126
|
+
if (loaded) return loaded;
|
|
127
|
+
let bytes;
|
|
128
|
+
try {
|
|
129
|
+
bytes = fs.readFileSync(WASM_URL);
|
|
130
|
+
} catch (error) {
|
|
131
|
+
failClosed(`cannot read ${WASM_URL.pathname}`, error);
|
|
132
|
+
}
|
|
133
|
+
const observedSha256 = createHash("sha256").update(bytes).digest("hex");
|
|
134
|
+
if (observedSha256 !== V4_DOMAIN_WASM_SHA256) {
|
|
135
|
+
failClosed(
|
|
136
|
+
`artifact digest mismatch (expected ${V4_DOMAIN_WASM_SHA256}, observed ${observedSha256})`,
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
let instance;
|
|
140
|
+
try {
|
|
141
|
+
instance = new WebAssembly.Instance(new WebAssembly.Module(bytes), {});
|
|
142
|
+
} catch (error) {
|
|
143
|
+
failClosed("artifact compilation or instantiation failed", error);
|
|
144
|
+
}
|
|
145
|
+
const missing = REQUIRED_EXPORTS.filter(
|
|
146
|
+
(name) => instance.exports[name] === undefined,
|
|
147
|
+
);
|
|
148
|
+
if (missing.length > 0) {
|
|
149
|
+
failClosed(`artifact is missing exports: ${missing.join(", ")}`);
|
|
150
|
+
}
|
|
151
|
+
const abiVersion = instance.exports.buildchain_v4_wasm_abi_version();
|
|
152
|
+
if (abiVersion !== V4_DOMAIN_WASM_ABI_VERSION) {
|
|
153
|
+
failClosed(
|
|
154
|
+
`ABI mismatch (expected ${V4_DOMAIN_WASM_ABI_VERSION}, observed ${abiVersion})`,
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
loaded = instance.exports;
|
|
158
|
+
return loaded;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export function invokeV4DomainWasm(operation, payload) {
|
|
162
|
+
if (
|
|
163
|
+
["canonical-json", "content-root", "release-tail-root"].includes(operation)
|
|
164
|
+
) {
|
|
165
|
+
validateJsonTransport(payload, "$/payload", new Set());
|
|
166
|
+
}
|
|
167
|
+
const authority = loadAuthority();
|
|
168
|
+
const input = new TextEncoder().encode(
|
|
169
|
+
JSON.stringify({
|
|
170
|
+
schema: V4_DOMAIN_WASM_REQUEST_CONTRACT,
|
|
171
|
+
operation,
|
|
172
|
+
payload,
|
|
173
|
+
}),
|
|
174
|
+
);
|
|
175
|
+
const inputPointer = authority.buildchain_v4_wasm_alloc(input.byteLength);
|
|
176
|
+
try {
|
|
177
|
+
new Uint8Array(authority.memory.buffer, inputPointer, input.byteLength).set(
|
|
178
|
+
input,
|
|
179
|
+
);
|
|
180
|
+
try {
|
|
181
|
+
authority.buildchain_v4_wasm_invoke(inputPointer, input.byteLength);
|
|
182
|
+
} catch (error) {
|
|
183
|
+
failClosed(`operation '${operation}' trapped`, error);
|
|
184
|
+
}
|
|
185
|
+
const responsePointer = authority.buildchain_v4_wasm_response_pointer();
|
|
186
|
+
const responseLength = authority.buildchain_v4_wasm_response_length();
|
|
187
|
+
let response;
|
|
188
|
+
try {
|
|
189
|
+
const responseBytes = new Uint8Array(
|
|
190
|
+
authority.memory.buffer,
|
|
191
|
+
responsePointer,
|
|
192
|
+
responseLength,
|
|
193
|
+
);
|
|
194
|
+
response = JSON.parse(new TextDecoder().decode(responseBytes));
|
|
195
|
+
} catch (error) {
|
|
196
|
+
failClosed(
|
|
197
|
+
`operation '${operation}' returned an invalid response`,
|
|
198
|
+
error,
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
if (
|
|
202
|
+
response?.schema !== V4_DOMAIN_WASM_RESPONSE_CONTRACT ||
|
|
203
|
+
typeof response.ok !== "boolean"
|
|
204
|
+
) {
|
|
205
|
+
failClosed(`operation '${operation}' returned an unsupported response`);
|
|
206
|
+
}
|
|
207
|
+
if (!response.ok) throw new V4DomainWasmFault(response.fault);
|
|
208
|
+
return response.value;
|
|
209
|
+
} finally {
|
|
210
|
+
authority.buildchain_v4_wasm_dealloc(inputPointer, input.byteLength);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export function v4DomainWasmInfo() {
|
|
215
|
+
return invokeV4DomainWasm("abi-info", {});
|
|
216
|
+
}
|
|
@@ -10,7 +10,7 @@ export const V4_FLOATING_CONSUMER_CERTIFICATION =
|
|
|
10
10
|
const SHA256_ROOT = /^sha256:[0-9a-f]{64}$/u;
|
|
11
11
|
const ALPHA_RECOVERY_BOOTSTRAP = Object.freeze({
|
|
12
12
|
repository: "kungfu-systems/buildchain",
|
|
13
|
-
sourcePath: ".github/workflows/
|
|
13
|
+
sourcePath: ".github/workflows/self-ops-promotion-recovery.yml",
|
|
14
14
|
workflow: ".github/workflows/.release-candidate-promote.yml",
|
|
15
15
|
selector: "alpha/v4/v4.0",
|
|
16
16
|
});
|
|
@@ -28,7 +28,7 @@ const BUILDCHAIN_REPOSITORY = "kungfu-systems/buildchain";
|
|
|
28
28
|
const CHANNELS = Object.freeze({ v4: "stable", "v4-alpha": "alpha" });
|
|
29
29
|
const ALPHA_RECOVERY_BOOTSTRAP = Object.freeze({
|
|
30
30
|
selector: "alpha/v4/v4.0",
|
|
31
|
-
sourcePath: ".github/workflows/
|
|
31
|
+
sourcePath: ".github/workflows/self-ops-promotion-recovery.yml",
|
|
32
32
|
workflow: ".github/workflows/.release-candidate-promote.yml",
|
|
33
33
|
});
|
|
34
34
|
const DEFAULT_STABLE_LOCK_PATH = ".buildchain/contract-lock.json";
|