@kungfu-tech/buildchain 4.0.2-alpha.8 → 4.0.2
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 +64 -7
- package/architecture/ci-lane-change-budget.json +366 -0
- package/architecture/internal-capabilities.json +53 -8
- package/architecture/maintainability-debt.json +147 -93
- package/architecture/maintainability-policy.json +32 -28
- 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 +74 -39
- 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 +2585 -1000
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +13 -13
- package/dist/site/node-api-registry.json +120 -115
- package/dist/site/page-registry.json +204 -51
- package/dist/site/public-surface-audit.json +3205 -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 +5061 -1659
- package/docs/MAP.md +1 -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 +190 -190
- 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/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/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-provider-plane.js +68 -1048
- package/packages/core/v4-canonical-contracts.js +10 -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 +19 -349
- 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 +90 -33
- 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/paper-work-fleet-cli.mjs +2 -0
- package/scripts/release-asset-client.mjs +91 -0
- package/scripts/release-candidate-resolver.mjs +9 -9
- 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 +13 -6
- 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",
|
|
@@ -110,89 +111,23 @@ function exactKeys(value, keys, path) {
|
|
|
110
111
|
fault("invalid-envelope-shape", path, `${path} keys are not canonical`);
|
|
111
112
|
}
|
|
112
113
|
|
|
113
|
-
function
|
|
114
|
-
if (value === null || typeof value === "boolean") return value;
|
|
115
|
-
if (typeof value === "string") {
|
|
116
|
-
for (let index = 0; index < value.length; index += 1) {
|
|
117
|
-
const code = value.charCodeAt(index);
|
|
118
|
-
if (code >= 0xd800 && code <= 0xdbff) {
|
|
119
|
-
const next = value.charCodeAt(index + 1);
|
|
120
|
-
if (!(next >= 0xdc00 && next <= 0xdfff))
|
|
121
|
-
fault(
|
|
122
|
-
"unsupported-string",
|
|
123
|
-
path,
|
|
124
|
-
`${path} contains an unpaired surrogate`,
|
|
125
|
-
);
|
|
126
|
-
index += 1;
|
|
127
|
-
} else if (code >= 0xdc00 && code <= 0xdfff) {
|
|
128
|
-
fault(
|
|
129
|
-
"unsupported-string",
|
|
130
|
-
path,
|
|
131
|
-
`${path} contains an unpaired surrogate`,
|
|
132
|
-
);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
return value;
|
|
136
|
-
}
|
|
137
|
-
if (typeof value === "number") {
|
|
138
|
-
if (!Number.isSafeInteger(value) || Object.is(value, -0))
|
|
139
|
-
fault(
|
|
140
|
-
"unsupported-number",
|
|
141
|
-
path,
|
|
142
|
-
`${path} must be a safe base-10 integer and must not be negative zero`,
|
|
143
|
-
);
|
|
144
|
-
return value;
|
|
145
|
-
}
|
|
146
|
-
if (!value || typeof value !== "object")
|
|
147
|
-
fault("unsupported-json-value", path, `${path} is not a JSON value`);
|
|
148
|
-
if (active.has(value))
|
|
149
|
-
fault("cyclic-json-value", path, `${path} contains a cycle`);
|
|
150
|
-
active.add(value);
|
|
114
|
+
function wasm(operation, payload) {
|
|
151
115
|
try {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
);
|
|
156
|
-
const prototype = Object.getPrototypeOf(value);
|
|
157
|
-
if (prototype !== Object.prototype && prototype !== null)
|
|
158
|
-
fault("unsupported-json-value", path, `${path} must be a plain object`);
|
|
159
|
-
const result = Object.create(null);
|
|
160
|
-
for (const key of Object.keys(value).sort((left, right) =>
|
|
161
|
-
left < right ? -1 : left > right ? 1 : 0,
|
|
162
|
-
)) {
|
|
163
|
-
if (!ASCII_KEY_PATTERN.test(key))
|
|
164
|
-
fault(
|
|
165
|
-
"unsupported-object-key",
|
|
166
|
-
`${path}/${key}`,
|
|
167
|
-
"object keys must be non-empty printable ASCII",
|
|
168
|
-
);
|
|
169
|
-
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);
|
|
170
120
|
}
|
|
171
|
-
|
|
172
|
-
} finally {
|
|
173
|
-
active.delete(value);
|
|
121
|
+
throw error;
|
|
174
122
|
}
|
|
175
123
|
}
|
|
176
124
|
|
|
177
125
|
export function v4CanonicalBytes(value) {
|
|
178
|
-
return Buffer.from(
|
|
179
|
-
`${JSON.stringify(canonicalize(value, "$", new Set()))}\n`,
|
|
180
|
-
"utf8",
|
|
181
|
-
);
|
|
126
|
+
return Buffer.from(wasm("canonical-json", value).canonicalUtf8, "utf8");
|
|
182
127
|
}
|
|
183
128
|
|
|
184
129
|
export function v4ContentRoot(domain, value) {
|
|
185
|
-
|
|
186
|
-
fault(
|
|
187
|
-
"unsupported-root-domain",
|
|
188
|
-
"$.domain",
|
|
189
|
-
`unsupported root domain: ${domain}`,
|
|
190
|
-
);
|
|
191
|
-
const hash = crypto.createHash("sha256");
|
|
192
|
-
hash.update(domain, "ascii");
|
|
193
|
-
hash.update(Buffer.from([0]));
|
|
194
|
-
hash.update(v4CanonicalBytes(value));
|
|
195
|
-
return `sha256:${hash.digest("hex")}`;
|
|
130
|
+
return wasm("content-root", { domain, value }).root;
|
|
196
131
|
}
|
|
197
132
|
|
|
198
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";
|