Skip to content

Commit ff71d2e

Browse files
committed
feat: US-007 - Update crypto expectations and regenerate conformance report
1 parent b574c95 commit ff71d2e

3 files changed

Lines changed: 37 additions & 27 deletions

File tree

packages/secure-exec/tests/node-conformance/expectations.json

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"nodeVersion": "22.14.0",
33
"sourceCommit": "v22.14.0",
4-
"lastUpdated": "2026-03-24",
4+
"lastUpdated": "2026-03-25",
55
"expectations": {
66
"test-cluster-*.js": {
77
"reason": "cluster module is Tier 5 (Unsupported) — require(cluster) throws by design",
@@ -1917,12 +1917,12 @@
19171917
"expected": "fail"
19181918
},
19191919
"test-crypto-key-objects.js": {
1920-
"reason": "fs.readFileSync encoding argument handled as path component — test reads fixture PEM keys which fail to load",
1920+
"reason": "fs.readFileSync() still folds the encoding argument into the VFS path for PEM fixtures, so the test tries to open '/test/fixtures/rsa_public.pem/ascii'",
19211921
"category": "implementation-gap",
19221922
"expected": "fail"
19231923
},
19241924
"test-crypto-padding.js": {
1925-
"reason": "createCipheriv/createDecipheriv do not throw expected exceptions for invalid padding options",
1925+
"reason": "OpenSSL cipher errors still miss Node's `reason` field snapshot shape, so invalid-padding assertions on `ERR_OSSL_WRONG_FINAL_BLOCK_LENGTH` fail",
19261926
"category": "implementation-gap",
19271927
"expected": "fail"
19281928
},
@@ -1932,17 +1932,17 @@
19321932
"expected": "fail"
19331933
},
19341934
"test-crypto-private-decrypt-gh32240.js": {
1935-
"reason": "Sandbox KeyObject.export() does not honor encrypted PEM export options yet, so the encrypted-key failure path is not exercised faithfully",
1935+
"reason": "encrypted private-key decrypt path does not throw the expected failure, so the test hits `Missing expected exception`",
19361936
"category": "implementation-gap",
19371937
"expected": "fail"
19381938
},
19391939
"test-crypto-psychic-signatures.js": {
1940-
"reason": "ECDSA key import fails with unsupported key format — bridge cannot decode the specific ECDSA public key encoding used in test",
1940+
"reason": "ECDSA psychic-signature fixture parsing still crashes with `TypeError: Cannot read properties of null (reading '2')`",
19411941
"category": "implementation-gap",
19421942
"expected": "fail"
19431943
},
19441944
"test-crypto-rsa-dsa.js": {
1945-
"reason": "fs.readFileSync encoding argument handled as path component — test reads fixture PEM/cert files which fail to load",
1945+
"reason": "crypto cert fixtures are incomplete in the conformance VFS, so the test fails opening `/test/fixtures/rsa_cert.crt`",
19461946
"category": "implementation-gap",
19471947
"expected": "fail"
19481948
},
@@ -1952,7 +1952,7 @@
19521952
"expected": "fail"
19531953
},
19541954
"test-crypto-sign-verify.js": {
1955-
"reason": "fs.readFileSync encoding argument handled as path component — test reads fixture PEM/cert files which fail to load",
1955+
"reason": "crypto cert fixtures are incomplete in the conformance VFS, so the test fails opening `/test/fixtures/rsa_cert.crt`",
19561956
"category": "implementation-gap",
19571957
"expected": "fail"
19581958
},
@@ -3251,7 +3251,7 @@
32513251
"expected": "fail"
32523252
},
32533253
"test-webcrypto-sign-verify-eddsa.js": {
3254-
"reason": "WebCrypto subtle.importKey() not implemented — crypto.subtle API methods return undefined",
3254+
"reason": "EdDSA WebCrypto path still fails runtime assertions during sign/verify coverage (`AssertionError2: false == true`)",
32553255
"category": "implementation-gap",
32563256
"expected": "fail"
32573257
},
@@ -3606,57 +3606,57 @@
36063606
"expected": "fail"
36073607
},
36083608
"test-crypto-async-sign-verify.js": {
3609-
"reason": "uses crypto/webcrypto APIs not fully bridged in sandbox",
3609+
"reason": "crypto fixture set is incomplete in the conformance VFS, so async sign/verify fails opening `/test/fixtures/rsa_public.pem`",
36103610
"category": "implementation-gap",
36113611
"expected": "fail"
36123612
},
36133613
"test-crypto-certificate.js": {
3614-
"reason": "tests Node.js-specific error codes (ERR_*) — sandbox polyfills throw plain errors",
3614+
"reason": "crypto certificate fixtures are incomplete in the conformance VFS, so the test fails opening `/test/fixtures/rsa_spkac.spkac`",
36153615
"category": "implementation-gap",
36163616
"expected": "fail"
36173617
},
36183618
"test-crypto-classes.js": {
3619-
"reason": "uses crypto/webcrypto APIs not fully bridged in sandbox",
3619+
"reason": "constructor/factory parity is incomplete for crypto classes, so `createX()` instances fail `instanceof crypto.X` assertions",
36203620
"category": "implementation-gap",
36213621
"expected": "fail"
36223622
},
36233623
"test-crypto-dh-group-setters.js": {
3624-
"reason": "uses crypto/webcrypto APIs not fully bridged in sandbox",
3624+
"reason": "ECDH instances still expose `setPrivateKey()` where Node expects `undefined`, so the group-setter surface mismatches Node",
36253625
"category": "implementation-gap",
36263626
"expected": "fail"
36273627
},
36283628
"test-crypto-getcipherinfo.js": {
3629-
"reason": "tests Node.js-specific error codes (ERR_*) — sandbox polyfills throw plain errors",
3629+
"reason": "`crypto.getCipherInfo()` is still missing from the sandbox crypto surface",
36303630
"category": "implementation-gap",
36313631
"expected": "fail"
36323632
},
36333633
"test-crypto-hash.js": {
3634-
"reason": "tests Node.js-specific error codes (ERR_*) — sandbox polyfills throw plain errors",
3634+
"reason": "hash parity still breaks Node's identity-sensitive output assertions (`Values identical but not reference-equal`) in the vendored hash suite",
36353635
"category": "implementation-gap",
36363636
"expected": "fail"
36373637
},
36383638
"test-crypto-hkdf.js": {
3639-
"reason": "tests Node.js-specific error codes (ERR_*) — sandbox polyfills throw plain errors",
3639+
"reason": "`crypto.hkdf()` is still missing from the sandbox crypto surface, so the test gets `hkdf is not a function`",
36403640
"category": "implementation-gap",
36413641
"expected": "fail"
36423642
},
36433643
"test-crypto-hmac.js": {
3644-
"reason": "tests Node.js-specific error codes (ERR_*) — sandbox polyfills throw plain errors",
3644+
"reason": "`crypto.Hmac` constructor parity is incomplete, so calling it without `new` does not return a fresh Hmac instance like Node",
36453645
"category": "implementation-gap",
36463646
"expected": "fail"
36473647
},
36483648
"test-crypto-oneshot-hash.js": {
3649-
"reason": "tests Node.js-specific error codes (ERR_*) — sandbox polyfills throw plain errors",
3649+
"reason": "one-shot hash argument validation still misses Node's `ERR_INVALID_ARG_TYPE` error shape",
36503650
"category": "implementation-gap",
36513651
"expected": "fail"
36523652
},
36533653
"test-crypto-randomuuid.js": {
3654-
"reason": "tests Node.js-specific error codes (ERR_*) — sandbox polyfills throw plain errors",
3654+
"reason": "`require('crypto').randomUUID` is still missing from the module overlay, so the test gets `TypeError: randomUUID is not a function`",
36553655
"category": "implementation-gap",
36563656
"expected": "fail"
36573657
},
36583658
"test-crypto-webcrypto-aes-decrypt-tag-too-small.js": {
3659-
"reason": "crypto polyfill behavior gap",
3659+
"reason": "AES-GCM decrypt rejects undersized tags with `TypeError: Invalid authentication tag length: 0` instead of Node's `OperationError`",
36603660
"category": "implementation-gap",
36613661
"expected": "fail"
36623662
},
@@ -5699,32 +5699,32 @@
56995699
"expected": "fail"
57005700
},
57015701
"test-webcrypto-constructors.js": {
5702-
"reason": "crypto.subtle (WebCrypto) API not fully implemented in sandbox",
5702+
"reason": "WebCrypto constructors still throw the wrong error shape (`TypeError` with missing `ERR_ILLEGAL_CONSTRUCTOR` metadata)",
57035703
"category": "implementation-gap",
57045704
"expected": "fail"
57055705
},
57065706
"test-webcrypto-derivebits-hkdf.js": {
5707-
"reason": "crypto.subtle (WebCrypto) API not fully implemented in sandbox",
5707+
"reason": "HKDF deriveBits/deriveKey parity is still broken, and the vendored test aborts with `Deriving bits failed`",
57085708
"category": "implementation-gap",
57095709
"expected": "fail"
57105710
},
57115711
"test-webcrypto-digest.js": {
5712-
"reason": "uses crypto/webcrypto APIs not fully bridged in sandbox",
5712+
"reason": "WebCrypto digest argument validation still misses Node's `ERR_INVALID_ARG_TYPE` error metadata",
57135713
"category": "implementation-gap",
57145714
"expected": "fail"
57155715
},
57165716
"test-webcrypto-export-import-cfrg.js": {
5717-
"reason": "uses crypto/webcrypto APIs not fully bridged in sandbox",
5717+
"reason": "WebCrypto import/export fixture set is incomplete in the conformance VFS, so the test fails opening `/test/fixtures/rsa_public_2048.pem`",
57185718
"category": "implementation-gap",
57195719
"expected": "fail"
57205720
},
57215721
"test-webcrypto-export-import-ec.js": {
5722-
"reason": "uses crypto/webcrypto APIs not fully bridged in sandbox",
5722+
"reason": "WebCrypto import/export fixture set is incomplete in the conformance VFS, so the test fails opening `/test/fixtures/rsa_public_2048.pem`",
57235723
"category": "implementation-gap",
57245724
"expected": "fail"
57255725
},
57265726
"test-webcrypto-export-import-rsa.js": {
5727-
"reason": "uses crypto/webcrypto APIs not fully bridged in sandbox",
5727+
"reason": "WebCrypto import/export fixture set is incomplete in the conformance VFS, so the test fails opening `/test/fixtures/ec_p256_public.pem`",
57285728
"category": "implementation-gap",
57295729
"expected": "fail"
57305730
},

scripts/ralph/prd.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@
137137
"Typecheck passes"
138138
],
139139
"priority": 7,
140-
"passes": false,
140+
"passes": true,
141141
"notes": "Cleanup story. ~13 tests will remain as vacuous-skip, ~8 as requires-v8-flags, ~4 as unsupported-module. All fixable tests should be passing by now."
142142
},
143143
{

scripts/ralph/progress.txt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- `CryptoKey` is bridged from both `process.ts` and `require-setup.ts`; keep their `instanceof` semantics aligned (for example via shared `Symbol.hasInstance` behavior) or `KeyObject.toCryptoKey()` conformance breaks even when key data is correct
66
- When the session cipher bridge is unavailable, crypto constructor-time validation still has to happen eagerly through the one-shot host bridge; otherwise Node conformance misses `createCipheriv()`/`createDecipheriv()` throw-on-construction cases
77
- `bridge-initial-globals.ts` intentionally removes `SharedArrayBuffer`; when vendored conformance files hard-require it, classify the expectation as a `security-constraint` instead of treating the failure as a crypto implementation bug
8+
- When a crypto/node-conformance expectation reason looks stale, temporarily remove just that entry and rerun the exact vendored file filter; the runner prints the real sandbox stderr, which is often a missing fixture or error-shape mismatch rather than the older bridge-gap guess
89
- Conformance tests live in packages/secure-exec/tests/node-conformance/ — vendored Node.js v22.14.0 test/parallel/
910
- Runner is packages/secure-exec/tests/node-conformance/runner.test.ts — run with: pnpm vitest run packages/secure-exec/tests/node-conformance/runner.test.ts
1011
- Expectations are in packages/secure-exec/tests/node-conformance/expectations.json — each entry has expected (pass/fail/skip), reason, category
@@ -82,5 +83,14 @@
8283
- **Learnings for future iterations:**
8384
- Cipher constructor assertions in Node’s vendored tests still need eager host validation even when the real streaming session bridge is unavailable; a validate-only call through the one-shot bridge keeps those semantics aligned without buffering ciphertext early.
8485
- CCM support needs buffered AAD/authTagLength handling in the isolate wrapper plus AEAD-aware auth-tag serialization on the host; fixing only one side leaves `getAuthTag()` and stream-mode CCM tests broken.
85-
- `SharedArrayBuffer` is removed by design in the sandbox bootstrap, so conformance failures that stem from that global disappearing should be tracked as `security-constraint` expectations rather than crypto bridge regressions.
86+
- `SharedArrayBuffer` is removed by design in the sandbox bootstrap, so conformance failures that stem from that global disappearing should be tracked as `security-constraint` expectations rather than crypto bridge regressions.
87+
---
88+
## [2026-03-25 04:10 PDT] - US-007
89+
- Audited the remaining crypto and webcrypto conformance expectations, replaced stale placeholder reasons with specific reproducible failure causes, and kept the vacuous-skip / requires-v8-flags classifications aligned with the current runner behavior.
90+
- Regenerated the node conformance JSON/docs outputs after the expectation cleanup and marked the crypto cleanup story complete in the PRD.
91+
- Files changed: `packages/secure-exec/tests/node-conformance/expectations.json`, `scripts/ralph/prd.json`, `scripts/ralph/progress.txt`
92+
- **Learnings for future iterations:**
93+
- Several remaining crypto failures are currently fixture-VFS gaps (`/test/fixtures/*.pem`, `.crt`, `.spkac`), so expectation reasons should name the missing fixture path instead of blaming a generic bridge gap.
94+
- The vendored runner is the quickest way to verify expectation accuracy: removing one entry and rerunning the exact file gives a concrete stderr snippet that can be copied into the reason.
95+
- Module-overlay drift still shows up in conformance as missing APIs like `require('crypto').randomUUID` and `crypto.hkdf`, even when related globals or bridge handlers exist elsewhere.
8696
---

0 commit comments

Comments
 (0)