@pulse-compute/wasm-guest-link 0.0.0 → 1.0.0-beta.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/README.md +94 -2
- package/package.json +29 -7
- package/src/constants.js +159 -0
- package/src/contracts.js +1143 -0
- package/src/errors.js +76 -0
- package/src/files.js +149 -0
- package/src/index.js +33 -0
- package/src/inspect.js +510 -0
- package/src/materialize.js +424 -0
- package/src/memory-owner.js +29 -0
- package/src/pipeline.js +729 -0
- package/src/stage.js +578 -0
- package/src/toolchain.js +125 -0
package/README.md
CHANGED
|
@@ -1,5 +1,97 @@
|
|
|
1
1
|
# @pulse-compute/wasm-guest-link
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<!-- pulse-package-status:start -->
|
|
4
|
+
> **Support tier:** Implementation/transitive surface<br>
|
|
5
|
+
> **Audience:** Pulse compiler, release, and first-party guest-unit maintainers.<br>
|
|
6
|
+
> **Install directly:** No for application projects; it is an internal synchronized compiler dependency.<br>
|
|
7
|
+
> **Supported entry points:** `None for application authors.`<br>
|
|
8
|
+
> **Stability:** Internal first-party prebuilt guest-link interface synchronized with the compiler; no application-author or third-party guest compatibility guarantee.<br>
|
|
9
|
+
> **npm:** [`@pulse-compute/wasm-guest-link`](https://www.npmjs.com/package/@pulse-compute/wasm-guest-link)<br>
|
|
10
|
+
> **Canonical documentation:** [Package guide](https://pulsecompute.io/v1.0.0-beta.2/packages/implementation-packages/)
|
|
11
|
+
>
|
|
12
|
+
> This release-status block is generated from the synchronized `Pulse 1.0.0-beta.2` package policy.
|
|
13
|
+
<!-- pulse-package-status:end -->
|
|
4
14
|
|
|
5
|
-
|
|
15
|
+
Internal Pulse implementation package for connecting validated first-party core
|
|
16
|
+
Wasm guest units into one final audited Native artifact.
|
|
17
|
+
|
|
18
|
+
The package owns:
|
|
19
|
+
|
|
20
|
+
- `pulse.guest-unit.v1` / `pulse.guest-unit-plan.v1` validation plus the
|
|
21
|
+
closed ES256-only v2 contracts;
|
|
22
|
+
- package-prebuilt hash, source-provenance, and binary verification;
|
|
23
|
+
- content-addressed `.pulse/guests/` materialization;
|
|
24
|
+
- the direct pinned Binaryen toolchain;
|
|
25
|
+
- static core-Wasm composition and post-link optimization;
|
|
26
|
+
- `pulse.guest-link-report.v1` and `pulse.final-wasm-audit.v1`;
|
|
27
|
+
- normalized, redacted guest-link diagnostics.
|
|
28
|
+
|
|
29
|
+
The original implementation continues to accept the A4-bound
|
|
30
|
+
`pulse.guest-memory.borrowed-span.v1` contract: one fixed 32-page
|
|
31
|
+
link-stage-owned memory, synchronous read-only borrowed spans of at most 4096
|
|
32
|
+
bytes, no allocation or retention, MVP features, and no fallback.
|
|
33
|
+
|
|
34
|
+
G2 adds a separate closed `pulse.guest-unit.v2` /
|
|
35
|
+
`pulse.guest-unit-plan.v2` path for the reviewed
|
|
36
|
+
`pulse.crypto.es256.rustcrypto-p256.v1` package prebuilt. That path preserves
|
|
37
|
+
the same single fixed memory while reserving the frozen 16,640-byte private
|
|
38
|
+
invocation frame. It accepts no other v2 unit, owner, ABI, artifact, source
|
|
39
|
+
tree, frame capacity, or toolchain identity. Both default Native and
|
|
40
|
+
`experimental-native-size` realization plans perform post-link optimization
|
|
41
|
+
and audit the layout before and after optimization.
|
|
42
|
+
|
|
43
|
+
It does not own package semantics, provider packaging, source builds, local
|
|
44
|
+
overrides, dynamic loading, or third-party guest registration. Package
|
|
45
|
+
manifests contain normalized metadata only; they cannot supply executables,
|
|
46
|
+
shell commands, or argument vectors. Every binary claim is independently
|
|
47
|
+
verified before composition.
|
|
48
|
+
|
|
49
|
+
The exported package root is an internal compiler integration surface. It is
|
|
50
|
+
not an application-author API.
|
|
51
|
+
|
|
52
|
+
The ES256 unit is linked and exercised as a G2 Node Native integration proof,
|
|
53
|
+
but it is not selected by application lowering and is not executable through
|
|
54
|
+
the crypto or JWT public surfaces. G3 owns that activation.
|
|
55
|
+
|
|
56
|
+
## Release boundary
|
|
57
|
+
|
|
58
|
+
The package is synchronized with the compiler as an implementation dependency.
|
|
59
|
+
It accepts only trusted first-party `package-prebuilt` units selected through
|
|
60
|
+
the compiler's closed package-lowering path. It does not expose project
|
|
61
|
+
configuration, CLI guest commands, source-build adapters, local overrides,
|
|
62
|
+
runtime loading, self-registration, or a third-party guest API.
|
|
63
|
+
|
|
64
|
+
Selected-unit failures are terminal. No error path retries another owner,
|
|
65
|
+
realization, execution mode, or provider path.
|
|
66
|
+
|
|
67
|
+
## JWT/crypto proof relationship
|
|
68
|
+
|
|
69
|
+
The sealed guest-link pipeline is evidence that the accepted borrowed-memory
|
|
70
|
+
contract can produce one audited final core module. It is not load-bearing for
|
|
71
|
+
HS256. The synchronized JWT/crypto packages select
|
|
72
|
+
`guest-source:pulse-hmac-as` for Native targets and emits zero linked guest
|
|
73
|
+
units; JavaScript selects the Web Crypto runtime builtin.
|
|
74
|
+
|
|
75
|
+
The historical guest pipeline result is recorded in
|
|
76
|
+
`wasm/.test-results/guest-link-b4/phase-b-seal.json`. Its relationship to the
|
|
77
|
+
current four-target JWT proof is audited by
|
|
78
|
+
`wasm/.test-results/jwt-e4/jwt-phase-e-seal.json`. Neither result creates a
|
|
79
|
+
third-party guest ABI or authorizes publication, deployment, or activation.
|
|
80
|
+
|
|
81
|
+
## Validation
|
|
82
|
+
|
|
83
|
+
The Phase B seal replays the valid production pipeline, the complete negative
|
|
84
|
+
diagnostic matrix, content-addressed reuse and deletion/recreation, Node
|
|
85
|
+
execution, and `fastly compute serve` over the exact production core artifact.
|
|
86
|
+
It cross-checks the core identity against the sealed A3 evidence without
|
|
87
|
+
rebuilding the package-prebuilt Rust source:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
PULSE_FASTLY_BIN=/path/to/fastly \
|
|
91
|
+
PULSE_VICEROY_BIN=/path/to/viceroy \
|
|
92
|
+
node ../../scripts/run-wasm-tests.cjs --task guest-link-b-seal --no-report
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The seal writes `wasm/.test-results/guest-link-b4/phase-b-seal.json`, including
|
|
96
|
+
artifact-size and focused validation wall-clock measurements. It performs no
|
|
97
|
+
remote deployment.
|
package/package.json
CHANGED
|
@@ -1,16 +1,38 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pulse-compute/wasm-guest-link",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "Inert bootstrap placeholder for @pulse-compute/wasm-guest-link.",
|
|
3
|
+
"version": "1.0.0-beta.2",
|
|
5
4
|
"license": "Apache-2.0",
|
|
5
|
+
"description": "Internal first-party guest-unit validation, materialization, core Wasm composition, optimization, and final audit for Pulse.",
|
|
6
|
+
"type": "commonjs",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": "^22.14.0 || ^24.0.0"
|
|
9
|
+
},
|
|
10
|
+
"main": "./src/index.js",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": "./src/index.js",
|
|
13
|
+
"./stage": "./src/stage.js",
|
|
14
|
+
"./toolchain": "./src/toolchain.js"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@pulse-compute/wasm-contracts": "1.0.0-beta.2",
|
|
18
|
+
"binaryen": "129.0.0-nightly.20260428"
|
|
19
|
+
},
|
|
20
|
+
"publishConfig": {
|
|
21
|
+
"access": "public"
|
|
22
|
+
},
|
|
6
23
|
"files": [
|
|
24
|
+
"src",
|
|
7
25
|
"README.md",
|
|
8
26
|
"LICENSE",
|
|
9
27
|
"NOTICE"
|
|
10
28
|
],
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "git+https://github.com/pulse-compute/pulse.git",
|
|
32
|
+
"directory": "wasm/packages/wasm-guest-link"
|
|
33
|
+
},
|
|
34
|
+
"homepage": "https://pulsecompute.io/v1.0.0-beta.2/packages/implementation-packages/",
|
|
35
|
+
"bugs": {
|
|
36
|
+
"url": "https://github.com/pulse-compute/pulse/issues"
|
|
15
37
|
}
|
|
16
|
-
}
|
|
38
|
+
}
|
package/src/constants.js
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const versions = Object.freeze({
|
|
4
|
+
guestUnit: 'pulse.guest-unit.v1',
|
|
5
|
+
guestUnitV2: 'pulse.guest-unit.v2',
|
|
6
|
+
guestUnitPlan: 'pulse.guest-unit-plan.v1',
|
|
7
|
+
guestUnitPlanV2: 'pulse.guest-unit-plan.v2',
|
|
8
|
+
guestLinkReport: 'pulse.guest-link-report.v1',
|
|
9
|
+
guestLinkReportV2: 'pulse.guest-link-report.v2',
|
|
10
|
+
finalWasmAudit: 'pulse.final-wasm-audit.v1',
|
|
11
|
+
finalWasmAuditV2: 'pulse.final-wasm-audit.v2',
|
|
12
|
+
memoryAbi: 'pulse.guest-memory.borrowed-span.v1',
|
|
13
|
+
memoryAbiV2: 'pulse.guest-memory.invocation-frame.v2'
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
const binaryenVersion = '129.0.0-nightly.20260428';
|
|
17
|
+
|
|
18
|
+
const diagnosticCodes = Object.freeze({
|
|
19
|
+
invalid: 'PULSE_GUEST_UNIT_INVALID',
|
|
20
|
+
hashMismatch: 'PULSE_GUEST_UNIT_HASH_MISMATCH',
|
|
21
|
+
ownerMismatch: 'PULSE_GUEST_UNIT_OWNER_MISMATCH',
|
|
22
|
+
abiMismatch: 'PULSE_GUEST_UNIT_ABI_MISMATCH',
|
|
23
|
+
importMismatch: 'PULSE_GUEST_UNIT_IMPORT_MISMATCH',
|
|
24
|
+
exportMismatch: 'PULSE_GUEST_UNIT_EXPORT_MISMATCH',
|
|
25
|
+
memoryMismatch: 'PULSE_GUEST_UNIT_MEMORY_MISMATCH',
|
|
26
|
+
startMismatch: 'PULSE_GUEST_UNIT_START_MISMATCH',
|
|
27
|
+
featureMismatch: 'PULSE_GUEST_UNIT_FEATURE_MISMATCH',
|
|
28
|
+
materializationFailed: 'PULSE_GUEST_UNIT_MATERIALIZATION_FAILED',
|
|
29
|
+
linkFailed: 'PULSE_GUEST_LINK_FAILED',
|
|
30
|
+
optimizationFailed: 'PULSE_GUEST_OPTIMIZATION_FAILED',
|
|
31
|
+
finalAuditFailed: 'PULSE_GUEST_FINAL_AUDIT_FAILED'
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const memoryAbi = Object.freeze({
|
|
35
|
+
identity: versions.memoryAbi,
|
|
36
|
+
pointerWidthBits: 32,
|
|
37
|
+
pageBytes: 65536,
|
|
38
|
+
minimumPages: 32,
|
|
39
|
+
maximumPages: 32,
|
|
40
|
+
bytes: 32 * 65536,
|
|
41
|
+
maximumBorrowedBytes: 4096,
|
|
42
|
+
invalidRangeStatus: 0x8000_0000,
|
|
43
|
+
importModule: 'env',
|
|
44
|
+
importName: 'memory',
|
|
45
|
+
layout: Object.freeze({
|
|
46
|
+
rustStack: Object.freeze({ start: 0, endExclusive: 65536 }),
|
|
47
|
+
rustStatic: Object.freeze({ start: 131072, endExclusive: 262144 }),
|
|
48
|
+
primaryStatic: Object.freeze({ start: 262144, endExclusive: 524288 }),
|
|
49
|
+
borrowedInput: Object.freeze({ start: 524288, endExclusive: 32 * 65536 })
|
|
50
|
+
})
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const es256FrameV2 = Object.freeze({
|
|
54
|
+
identity: 'pulse.crypto.es256.invocation-frame.v2',
|
|
55
|
+
memoryIdentity: versions.memoryAbiV2,
|
|
56
|
+
pointerWidthBits: 32,
|
|
57
|
+
byteOrder: 'little-endian',
|
|
58
|
+
magic: 0x3253_4550,
|
|
59
|
+
version: 2,
|
|
60
|
+
headerBytes: 64,
|
|
61
|
+
capacityBytes: 16640,
|
|
62
|
+
alignmentBytes: 16,
|
|
63
|
+
signingInputBytesMaximum: 16340,
|
|
64
|
+
publicKeyBytes: 64,
|
|
65
|
+
signatureBytes: 64,
|
|
66
|
+
export: 'pulse_crypto_es256_verify',
|
|
67
|
+
parameters: Object.freeze(['i32', 'i32']),
|
|
68
|
+
results: Object.freeze(['i32'])
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
const memoryAbiV2 = Object.freeze({
|
|
72
|
+
identity: versions.memoryAbiV2,
|
|
73
|
+
pointerWidthBits: 32,
|
|
74
|
+
pageBytes: 65536,
|
|
75
|
+
minimumPages: 32,
|
|
76
|
+
maximumPages: 32,
|
|
77
|
+
bytes: 32 * 65536,
|
|
78
|
+
importModule: 'env',
|
|
79
|
+
importName: 'memory',
|
|
80
|
+
layout: Object.freeze({
|
|
81
|
+
rustStack: Object.freeze({ start: 0, endExclusive: 65536 }),
|
|
82
|
+
stackStaticGuard: Object.freeze({ start: 65536, endExclusive: 131072 }),
|
|
83
|
+
rustStatic: Object.freeze({ start: 131072, endExclusive: 262144 }),
|
|
84
|
+
primaryStatic: Object.freeze({ start: 262144, endExclusive: 524288 }),
|
|
85
|
+
invocationFrame: Object.freeze({
|
|
86
|
+
start: 524288,
|
|
87
|
+
endExclusive: 524288 + es256FrameV2.capacityBytes
|
|
88
|
+
}),
|
|
89
|
+
unallocated: Object.freeze({
|
|
90
|
+
start: 524288 + es256FrameV2.capacityBytes,
|
|
91
|
+
endExclusive: 32 * 65536
|
|
92
|
+
})
|
|
93
|
+
}),
|
|
94
|
+
frame: es256FrameV2
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
const es256GuestUnit = Object.freeze({
|
|
98
|
+
version: versions.guestUnitV2,
|
|
99
|
+
id: 'pulse.crypto.es256.rustcrypto-p256.v1',
|
|
100
|
+
module: 'pulse_crypto_es256',
|
|
101
|
+
owner: '@pulse-compute/crypto',
|
|
102
|
+
packageVersion: '1.0.0-beta.2',
|
|
103
|
+
abi: 'pulse.crypto.es256.verify.v1',
|
|
104
|
+
artifact: Object.freeze({
|
|
105
|
+
file: 'prebuilt/es256-verifier.wasm',
|
|
106
|
+
bytes: 21009,
|
|
107
|
+
sha256: 'ee5ab1639cbe1be5a9510c01ab15a3569c0394818a9db98f3e0114ae829fff50'
|
|
108
|
+
}),
|
|
109
|
+
source: Object.freeze({
|
|
110
|
+
directory: 'source',
|
|
111
|
+
treeSha256: '76c8cf985b2ed384d069f7ba0d7ff1c8513679ea7aec513e1a07a3eeaa3b7208'
|
|
112
|
+
}),
|
|
113
|
+
toolchain: Object.freeze({
|
|
114
|
+
rustc: '1.97.1 (8bab26f4f 2026-07-14)',
|
|
115
|
+
cargo: '1.97.1 (c980f4866 2026-06-30)',
|
|
116
|
+
binaryen: binaryenVersion
|
|
117
|
+
}),
|
|
118
|
+
provenance: Object.freeze({
|
|
119
|
+
cargoLockSha256: '7aa8c6d72751653717a371147e71a546d8f21dfcd1cf698919563e79e2946cb4',
|
|
120
|
+
reconstructionCommandIdentity: 'pulse.crypto.es256.rustcrypto-build.v1',
|
|
121
|
+
buildScript: 'build.cjs',
|
|
122
|
+
buildScriptSha256: 'c3b97e10e67cc2a34d0d6dced7bd81cb5fdaeeabe9cf75b5319d419b7dbebdf9',
|
|
123
|
+
optimizationPosture: 'native-size',
|
|
124
|
+
binaryenWasmOptSha256: '1304eb38ad315a0d70d8427757f641c110d972468c126af645ef800b09c26e56',
|
|
125
|
+
g0SourceDecision: '../../../../wasm/.test-results/jwt-g0/es256-source-decision.json',
|
|
126
|
+
g0SourceDecisionSha256: '58db9e3587ace112a8864c7916f603d8773dce653deafb7d743c0dc1f4d62d63'
|
|
127
|
+
})
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
const optimizationPostures = Object.freeze({
|
|
131
|
+
'native-default': Object.freeze([
|
|
132
|
+
'--mvp-features',
|
|
133
|
+
'--optimize-level',
|
|
134
|
+
'2',
|
|
135
|
+
'--shrink-level',
|
|
136
|
+
'0',
|
|
137
|
+
'--strip-debug'
|
|
138
|
+
]),
|
|
139
|
+
'native-size': Object.freeze([
|
|
140
|
+
'--mvp-features',
|
|
141
|
+
'--optimize-level',
|
|
142
|
+
'3',
|
|
143
|
+
'--shrink-level',
|
|
144
|
+
'2',
|
|
145
|
+
'--converge',
|
|
146
|
+
'--strip-debug'
|
|
147
|
+
])
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
module.exports = Object.freeze({
|
|
151
|
+
versions,
|
|
152
|
+
binaryenVersion,
|
|
153
|
+
diagnosticCodes,
|
|
154
|
+
memoryAbi,
|
|
155
|
+
memoryAbiV2,
|
|
156
|
+
es256FrameV2,
|
|
157
|
+
es256GuestUnit,
|
|
158
|
+
optimizationPostures
|
|
159
|
+
});
|