@pulse-compute/wasm-guest-link 1.0.0-beta.4 → 1.0.0-beta.6

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 CHANGED
@@ -7,9 +7,9 @@
7
7
  > **Supported entry points:** `None for application authors.`<br>
8
8
  > **Stability:** Internal first-party prebuilt guest-link interface synchronized with the compiler; no application-author or third-party guest compatibility guarantee.<br>
9
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.4/packages/implementation-packages/)
10
+ > **Canonical documentation:** [Package guide](https://pulsecompute.io/v1.0.0-beta.6/packages/implementation-packages/)
11
11
  >
12
- > This release-status block is generated from the synchronized `Pulse 1.0.0-beta.4` package policy.
12
+ > This release-status block is generated from the synchronized `Pulse 1.0.0-beta.6` package policy.
13
13
  <!-- pulse-package-status:end -->
14
14
 
15
15
  Internal Pulse implementation package for connecting validated first-party core
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pulse-compute/wasm-guest-link",
3
- "version": "1.0.0-beta.4",
3
+ "version": "1.0.0-beta.6",
4
4
  "license": "Apache-2.0",
5
5
  "description": "Internal first-party guest-unit validation, materialization, core Wasm composition, optimization, and final audit for Pulse.",
6
6
  "type": "commonjs",
@@ -14,7 +14,7 @@
14
14
  "./toolchain": "./src/toolchain.js"
15
15
  },
16
16
  "dependencies": {
17
- "@pulse-compute/wasm-contracts": "1.0.0-beta.4",
17
+ "@pulse-compute/wasm-contracts": "1.0.0-beta.6",
18
18
  "binaryen": "129.0.0-nightly.20260428"
19
19
  },
20
20
  "publishConfig": {
@@ -31,7 +31,7 @@
31
31
  "url": "git+https://github.com/pulse-compute/pulse.git",
32
32
  "directory": "wasm/packages/wasm-guest-link"
33
33
  },
34
- "homepage": "https://pulsecompute.io/v1.0.0-beta.4/packages/implementation-packages/",
34
+ "homepage": "https://pulsecompute.io/v1.0.0-beta.6/packages/implementation-packages/",
35
35
  "bugs": {
36
36
  "url": "https://github.com/pulse-compute/pulse/issues"
37
37
  }
package/src/constants.js CHANGED
@@ -99,27 +99,28 @@ const es256GuestUnit = Object.freeze({
99
99
  id: 'pulse.crypto.es256.rustcrypto-p256.v1',
100
100
  module: 'pulse_crypto_es256',
101
101
  owner: '@pulse-compute/crypto',
102
- packageVersion: '1.0.0-beta.4',
103
- abi: 'pulse.crypto.es256.verify.v1',
102
+ packageVersion: '1.0.0-beta.6',
103
+ abi: 'pulse.crypto.es256-rs256.verify-and-sign.v3',
104
104
  artifact: Object.freeze({
105
105
  file: 'prebuilt/es256-verifier.wasm',
106
- bytes: 21009,
107
- sha256: 'ee5ab1639cbe1be5a9510c01ab15a3569c0394818a9db98f3e0114ae829fff50'
106
+ bytes: 36378,
107
+ sha256: 'b1d09f10fddf7587cb9e87f959fa908457e076e207db078fc101390c70e4aecf'
108
108
  }),
109
109
  source: Object.freeze({
110
110
  directory: 'source',
111
- treeSha256: '76c8cf985b2ed384d069f7ba0d7ff1c8513679ea7aec513e1a07a3eeaa3b7208'
111
+ treeSha256: '581fa765f228bd1a3ab6a40ee3cbb35a9d7a101e2839d32e36ececc94b66a741'
112
112
  }),
113
113
  toolchain: Object.freeze({
114
114
  rustc: '1.97.1 (8bab26f4f 2026-07-14)',
115
115
  cargo: '1.97.1 (c980f4866 2026-06-30)',
116
+ zig: '0.13.0',
116
117
  binaryen: binaryenVersion
117
118
  }),
118
119
  provenance: Object.freeze({
119
- cargoLockSha256: '7aa8c6d72751653717a371147e71a546d8f21dfcd1cf698919563e79e2946cb4',
120
- reconstructionCommandIdentity: 'pulse.crypto.es256.rustcrypto-build.v1',
120
+ cargoLockSha256: 'd5ecc12c9c846468686974aaed841156cc82ab8f876fec4d40b2baa29dff1551',
121
+ reconstructionCommandIdentity: 'pulse.crypto.es256-rs256.build.v3',
121
122
  buildScript: 'build.cjs',
122
- buildScriptSha256: '9d9fe63de85c865467e204c4b078e392a913ee7018c3b8298f1b8689bdb36111',
123
+ buildScriptSha256: '85d99761b442ec3ea11af6496206f475c14e6c419b5aa89bbedc730d8b61e95d',
123
124
  optimizationPosture: 'native-size',
124
125
  binaryenWasmOptSha256: '1304eb38ad315a0d70d8427757f641c110d972468c126af645ef800b09c26e56',
125
126
  g0SourceDecision: '../../../../wasm/.test-results/jwt-g0/es256-source-decision.json',
@@ -147,6 +148,31 @@ const optimizationPostures = Object.freeze({
147
148
  ])
148
149
  });
149
150
 
151
+ // Keep the pinned prebuilt recipe above unchanged. Composed final modules use
152
+ // these bounded, layout-preserving passes before the existing final audit.
153
+ const finalOptimizationPostures = Object.freeze({
154
+ 'native-default': Object.freeze([
155
+ '--mvp-features',
156
+ '--merge-similar-functions',
157
+ '--one-caller-inline-max-function-size=64',
158
+ '--flexible-inline-max-function-size=0',
159
+ '--inline-max-combined-binary-size=1024',
160
+ '-Oz',
161
+ '--skip-pass=memory-packing',
162
+ '--strip-debug'
163
+ ]),
164
+ 'native-size': Object.freeze([
165
+ '--mvp-features',
166
+ '--merge-similar-functions',
167
+ '--one-caller-inline-max-function-size=64',
168
+ '--flexible-inline-max-function-size=0',
169
+ '--inline-max-combined-binary-size=1024',
170
+ '-Oz',
171
+ '--skip-pass=memory-packing',
172
+ '--strip-debug'
173
+ ])
174
+ });
175
+
150
176
  module.exports = Object.freeze({
151
177
  versions,
152
178
  binaryenVersion,
@@ -155,5 +181,6 @@ module.exports = Object.freeze({
155
181
  memoryAbiV2,
156
182
  es256FrameV2,
157
183
  es256GuestUnit,
158
- optimizationPostures
184
+ optimizationPostures,
185
+ finalOptimizationPostures
159
186
  });
package/src/contracts.js CHANGED
@@ -8,7 +8,7 @@ const {
8
8
  memoryAbiV2,
9
9
  es256FrameV2,
10
10
  es256GuestUnit,
11
- optimizationPostures
11
+ finalOptimizationPostures
12
12
  } = require('./constants.js');
13
13
  const { fail } = require('./errors.js');
14
14
  const { assertRelativePath } = require('./files.js');
@@ -198,7 +198,12 @@ function manifestRelativePath(value, field) {
198
198
  }
199
199
 
200
200
  function exactValue(value, expected, field, code = diagnosticCodes.invalid) {
201
- if (JSON.stringify(value) !== JSON.stringify(expected)) {
201
+ // JSON object member order is not part of the contract. The compiler writes
202
+ // sorted artifact JSON; retain array order and exact values when reloading it.
203
+ const canonical = item => JSON.stringify(item, (_key, nested) => plainObject(nested)
204
+ ? Object.fromEntries(Object.keys(nested).sort().map(key => [key, nested[key]]))
205
+ : nested);
206
+ if (canonical(value) !== canonical(expected)) {
202
207
  fail(code, `${field} does not match the reviewed ES256 guest contract.`, { expected, actual: value });
203
208
  }
204
209
  return value;
@@ -409,7 +414,7 @@ function normalizeGuestUnitManifestV2(input) {
409
414
  );
410
415
 
411
416
  exactKeys(input.toolchain, ['kind', 'target', 'locked', 'versions'], [], 'guest unit v2 toolchain');
412
- exactKeys(input.toolchain.versions, ['rustc', 'cargo', 'binaryen'], [], 'guest unit v2 toolchain.versions');
417
+ exactKeys(input.toolchain.versions, ['rustc', 'cargo', 'zig', 'binaryen'], [], 'guest unit v2 toolchain.versions');
413
418
  const toolchain = Object.freeze({
414
419
  kind: string(input.toolchain.kind, 'guest unit v2 toolchain.kind'),
415
420
  target: string(input.toolchain.target, 'guest unit v2 toolchain.target'),
@@ -417,6 +422,7 @@ function normalizeGuestUnitManifestV2(input) {
417
422
  versions: Object.freeze({
418
423
  rustc: string(input.toolchain.versions.rustc, 'guest unit v2 rustc version'),
419
424
  cargo: string(input.toolchain.versions.cargo, 'guest unit v2 cargo version'),
425
+ zig: string(input.toolchain.versions.zig, 'guest unit v2 Zig version'),
420
426
  binaryen: string(input.toolchain.versions.binaryen, 'guest unit v2 Binaryen version')
421
427
  })
422
428
  });
@@ -449,17 +455,10 @@ function normalizeGuestUnitManifestV2(input) {
449
455
  })
450
456
  })]);
451
457
  exactValue(imports, expectedImports, 'guest unit v2 imports', diagnosticCodes.importMismatch);
452
- const expectedExports = Object.freeze([Object.freeze({
453
- name: es256FrameV2.export,
454
- kind: 'function',
455
- parameters: es256FrameV2.parameters,
456
- results: es256FrameV2.results,
457
- role: 'abi'
458
- })]);
458
+ const expectedExports = Object.freeze(['pulse_crypto_es256_sign', 'pulse_crypto_es256_verify', 'pulse_crypto_rs256_sign', 'pulse_crypto_rs256_verify'].map(name => Object.freeze({
459
+ name, kind: 'function', parameters: es256FrameV2.parameters, results: es256FrameV2.results, role: 'abi'
460
+ })));
459
461
  exactValue(exports, expectedExports, 'guest unit v2 exports', diagnosticCodes.exportMismatch);
460
- if (exports.filter((entry) => entry.role === 'abi').length !== 1) {
461
- fail(diagnosticCodes.abiMismatch, 'Guest unit v2 must declare exactly one ABI function export.');
462
- }
463
462
 
464
463
  exactKeys(input.memory, ['identity', 'import', 'owner'], [], 'guest unit v2 memory');
465
464
  exactValue(input.memory, {
@@ -715,10 +714,10 @@ function normalizeGuestUnitPlanV1(input) {
715
714
  const directory = assertRelativePath(input.materialization.directory, 'guest unit plan materialization.directory');
716
715
  if (
717
716
  workspace !== '.pulse/guests'
718
- || directory !== `${workspace}/${unit.id}/${unit.artifactSha256}`
717
+ || directory !== `${workspace}/${unit.id}/${unit.artifactSha256}/${unit.manifestSha256}`
719
718
  || input.materialization.artifact !== 'unit.wasm'
720
719
  || input.materialization.manifest !== 'unit.json'
721
- || input.materialization.contentAddress !== 'artifact-sha256'
720
+ || input.materialization.contentAddress !== 'artifact-and-manifest-sha256'
722
721
  || input.materialization.generated !== true
723
722
  || input.materialization.authoritative !== false
724
723
  ) {
@@ -762,7 +761,7 @@ function normalizeGuestUnitPlanV1(input) {
762
761
  directory,
763
762
  artifact: 'unit.wasm',
764
763
  manifest: 'unit.json',
765
- contentAddress: 'artifact-sha256',
764
+ contentAddress: 'artifact-and-manifest-sha256',
766
765
  generated: true,
767
766
  authoritative: false
768
767
  }),
@@ -921,10 +920,10 @@ function normalizeGuestUnitPlanV2(input) {
921
920
  );
922
921
  if (
923
922
  workspace !== '.pulse/guests'
924
- || directory !== `${workspace}/${unit.id}/${unit.artifact.sha256}`
923
+ || directory !== `${workspace}/${unit.id}/${unit.artifact.sha256}/${unit.manifestSha256}`
925
924
  || input.materialization.artifact !== 'unit.wasm'
926
925
  || input.materialization.manifest !== 'unit.json'
927
- || input.materialization.contentAddress !== 'artifact-sha256'
926
+ || input.materialization.contentAddress !== 'artifact-and-manifest-sha256'
928
927
  || input.materialization.generated !== true
929
928
  || input.materialization.authoritative !== false
930
929
  ) {
@@ -1003,7 +1002,7 @@ function normalizeGuestUnitPlanV2(input) {
1003
1002
  directory,
1004
1003
  artifact: 'unit.wasm',
1005
1004
  manifest: 'unit.json',
1006
- contentAddress: 'artifact-sha256',
1005
+ contentAddress: 'artifact-and-manifest-sha256',
1007
1006
  generated: true,
1008
1007
  authoritative: false
1009
1008
  }),
@@ -1128,7 +1127,7 @@ function assertPlanMatchesManifest(plan, manifest) {
1128
1127
  }
1129
1128
 
1130
1129
  function optimizationArguments(posture) {
1131
- const args = optimizationPostures[posture];
1130
+ const args = finalOptimizationPostures[posture];
1132
1131
  if (!args) fail(diagnosticCodes.optimizationFailed, `Unsupported guest-link optimization posture ${posture}.`);
1133
1132
  return args;
1134
1133
  }
@@ -127,12 +127,12 @@ function assertGuestBinary(manifest, inspection) {
127
127
  type: 'i32',
128
128
  initializer: { instruction: 'i32.const', value: contract.layout.rustStack.endExclusive }
129
129
  })
130
- || inspection.instructions.globalSet !== 64
131
- || inspection.instructions.store !== 500
130
+ || inspection.instructions.globalSet !== 104
131
+ || inspection.instructions.store !== 823
132
132
  ) {
133
133
  fail(
134
134
  diagnosticCodes.memoryMismatch,
135
- `Guest unit ${manifest.id} binary does not match the reviewed stack-only mutable-state posture.`
135
+ `Guest unit ${manifest.id} binary does not match the reviewed stack and bounded-signature-output posture.`
136
136
  );
137
137
  }
138
138
  }
@@ -156,9 +156,9 @@ function assertGuestBinary(manifest, inspection) {
156
156
  }))) !== JSON.stringify([{
157
157
  memoryIndex: 0,
158
158
  offset: 131072,
159
- endExclusive: 131656,
160
- bytes: 584,
161
- sha256: '231fcd9a2fc4e8190c8b96c9f89708b8039ea1b801cc564e32fbc14ff44e53ee'
159
+ endExclusive: 131722,
160
+ bytes: 650,
161
+ sha256: 'a33fcc685d2bb0bbbaa4678207d5c4ab2698f41ed7694be4fe0ba590e93d98ce'
162
162
  }])
163
163
  ) {
164
164
  fail(diagnosticCodes.memoryMismatch, `Guest unit ${manifest.id} static data does not match the reviewed layout.`);
package/src/pipeline.js CHANGED
@@ -208,7 +208,7 @@ function assertPrimaryAndOwner(plan, manifest, primary, owner) {
208
208
  kind: entry.kind,
209
209
  type: { parameters: entry.parameters, results: entry.results }
210
210
  }));
211
- if (!equal(guestImports.map(surfaceImport), expectedGuestImports)) {
211
+ if (!equal(sortedSurface(guestImports.map(surfaceImport)), sortedSurface(expectedGuestImports))) {
212
212
  fail(diagnosticCodes.abiMismatch, 'Primary guest imports do not exactly match the selected guest ABI.');
213
213
  }
214
214
  const memoryImports = primary.imports.filter((entry) => entry.kind === 'memory');
package/src/stage.js CHANGED
@@ -364,10 +364,10 @@ function makeGuestUnitPlan(selection, resolved, facts, primaryBytes) {
364
364
  targetPolicy,
365
365
  materialization: {
366
366
  workspace: '.pulse/guests',
367
- directory: `.pulse/guests/${manifest.id}/${manifest.artifact.sha256}`,
367
+ directory: `.pulse/guests/${manifest.id}/${manifest.artifact.sha256}/${resolved.manifestSha256}`,
368
368
  artifact: 'unit.wasm',
369
369
  manifest: 'unit.json',
370
- contentAddress: 'artifact-sha256',
370
+ contentAddress: 'artifact-and-manifest-sha256',
371
371
  generated: true,
372
372
  authoritative: false
373
373
  },