From 86214fa8a7862b25ed5623e7140d45ca15a3f8a4 Mon Sep 17 00:00:00 2001 From: Lann Martin Date: Sun, 9 Aug 2026 20:22:26 -0400 Subject: [PATCH] Deltic legs: both composed artifacts runtime-linked on stock Deno MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two standing conformance targets, deltic-deno + deltic-deno-delegated (conformance/driver-ct/deltic/, the deltic analogue of jco/run-node.mjs and the pattern polymorph-websocket#40 established): the composed artifacts run runtime-linked under the release-pinned deltic — no transpile step, no generated tree, no --experimental-wasm-jspi (async exports run on the callback ABI under stock Deno). No SUT host module on this leg (the TLS delivery is fused in-guest); the import surface is deltic's wasiShims() + its runner-supplied test-context. Tag scheduling reads the suite's embedded inventory (it survives wac composition; deltic#25), with --missing mirroring targets.toml per target; results provenance points at the un-composed suite exactly like the wasmtime legs' --suite-artifact, so the aggregate's mixed-hash warning never fires. Pin: pre-83fff30 (deno.json import map + frozen deno.lock; translator asset sha-pinned by fetch-translator.ts). Matrix: 9 targets, 56 results, 0 failing — the deltic rows match the wasmtime/jco rows case for case (plain: 2 N/A + 1 pass in delegated/; delegated: 1 N/A + 2 pass). CI conformance job gains a pinned deno setup; matrix regenerated with the two new columns (browser legs run locally via CHROME_PATH for the refresh). just conformance green end to end, matrix-check included. --- .github/workflows/ci.yml | 4 + AGENTS.md | 2 +- conformance/README.md | 2 + conformance/driver-ct/deltic/README.md | 37 +++++ conformance/driver-ct/deltic/deno.json | 12 ++ conformance/driver-ct/deltic/deno.lock | 66 +++++++++ .../driver-ct/deltic/fetch-translator.ts | 86 +++++++++++ conformance/driver-ct/deltic/run.ts | 139 ++++++++++++++++++ conformance/driver-ct/justfile | 32 +++- conformance/driver-ct/matrix.md | 16 +- conformance/driver-ct/targets.toml | 10 ++ 11 files changed, 397 insertions(+), 9 deletions(-) create mode 100644 conformance/driver-ct/deltic/README.md create mode 100644 conformance/driver-ct/deltic/deno.json create mode 100644 conformance/driver-ct/deltic/deno.lock create mode 100644 conformance/driver-ct/deltic/fetch-translator.ts create mode 100644 conformance/driver-ct/deltic/run.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f7abe06..75ccd0e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -110,6 +110,10 @@ jobs: node-version: 24 cache: npm cache-dependency-path: conformance/driver-ct/jco/package-lock.json + - name: Set up Deno (the deltic-deno legs; stock, no flags) + uses: denoland/setup-deno@v2 + with: + deno-version: "2.9.5" - name: Install just, wasm-tools, and wac # wac-cli has no install-action manifest; the action falls back to # cargo-binstall for it, which resolves releases through diff --git a/AGENTS.md b/AGENTS.md index 20f300d..16144c3 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -76,7 +76,7 @@ design record. | Recipe | Verifies | | --- | --- | | `just check` | fmt, clippy (all features), workspace tests (RFC 9001 vectors, profile/provider pinning, class-D key rejection), wasm build | -| `just conformance` | the cross-implementation conformance suite (see `conformance/README.md`): the shared guest suite composed with each delivery — the `tls` world's in-guest Ed25519 posture and the `tls-delegated` world with the fixture signer — run under the pinned component-test runner, transpiled under Node 24 JSPI (the jco-node targets), and in headless Chromium (the jco-browser targets; CI or CONFORMANCE_BROWSER=1), with import-satisfaction and signer-reachability gates, validated against the committed case inventory (`tests.lock`) and target manifest, and diffed against the committed matrix. `just conformance-ct::run-webcrypto` (on demand: clones the sibling repo) adds the delegated posture over a real `polymorph:webcrypto` provider | +| `just conformance` | the cross-implementation conformance suite (see `conformance/README.md`): the shared guest suite composed with each delivery — the `tls` world's in-guest Ed25519 posture and the `tls-delegated` world with the fixture signer — run under the pinned component-test runner, transpiled under Node 24 JSPI (the jco-node targets), runtime-linked under deltic on stock Deno (the deltic-deno targets — no transpile, no engine flag; release-pinned in `conformance/driver-ct/deltic/`), and in headless Chromium (the jco-browser targets; CI or CONFORMANCE_BROWSER=1), with import-satisfaction and signer-reachability gates, validated against the committed case inventory (`tests.lock`) and target manifest, and diffed against the committed matrix. `just conformance-ct::run-webcrypto` (on demand: clones the sibling repo) adds the delegated posture over a real `polymorph:webcrypto` provider | | `just smoke-quic` | QUIC over `wasi:sockets` UDP under Wasmtime | | `just smoke-tls-virt` | both tls-virt deliveries against `openssl s_server` over real TCP (needs openssl + python3): the composed guest virtualizer (handle-address and import-satisfaction gates), and the wasmtime host provider on both sockets generations — wasip3 and `std::net`/0.2 guests — with handle-address and profile-cipher-suite gates plus plain-TCP passthrough-delegation legs | | `just interop` | cross-implementation, over real transports, fresh Ed25519 private PKI per run: the composed TLS component against OpenSSL and Go peers over TCP in both directions (including the close_notify-vs-truncation and reset scenarios), and the noq leg against quic-go over UDP in both directions | diff --git a/conformance/README.md b/conformance/README.md index da59c83..66dac9c 100644 --- a/conformance/README.md +++ b/conformance/README.md @@ -38,6 +38,8 @@ JSPI — one suite, one composition, two engines. | `composed-delegated-webcrypto` | as above, but the signer is the `examples/webcrypto-signer` shim over a real `polymorph:webcrypto` provider; on demand (`just conformance-ct::run-webcrypto`), declared `optional` | | `jco-node` | the `composed` artifact, transpiled, under Node 24 JSPI | | `jco-node-delegated` | the `composed-delegated` artifact, likewise | +| `deltic-deno` | the `composed` artifact runtime-linked under deltic on stock Deno (no transpile, no engine flag) | +| `deltic-deno-delegated` | the `composed-delegated` artifact, likewise | | `jco-browser` | the `composed` artifact inside headless Chromium (the upstream page driver; gates in CI, locally `CONFORMANCE_BROWSER=1`; declared `optional`) | | `jco-browser-delegated` | the `composed-delegated` artifact, likewise | diff --git a/conformance/driver-ct/deltic/README.md b/conformance/driver-ct/deltic/README.md new file mode 100644 index 0000000..129c738 --- /dev/null +++ b/conformance/driver-ct/deltic/README.md @@ -0,0 +1,37 @@ +# conformance/driver-ct/deltic + +The deltic leg of the conformance matrix: the composed artifacts +(`suite-plain`, `suite-delegated`) run **runtime-linked** under +[deltic](https://github.com/lann/deltic) on stock Deno — no transpile +step, no generated tree, no `--experimental-wasm-jspi` (the WIT +contract's async exports run on the callback ABI). The deltic analogue +of `../jco/run-node.mjs`; targets `deltic-deno` and +`deltic-deno-delegated` in `../targets.toml`. + +There is no SUT host module on this leg (the TLS delivery is fused +in-guest, the artifacts import only wasi 0.2 and test-context), so the +whole import surface is deltic's own `wasiShims()` + its runner-supplied +`test-context`. Tag scheduling reads the suite's embedded +`component-test:tags@0.1` inventory (it survives wac composition); +`--missing` mirrors `targets.toml` per target. + +```sh +just conformance-ct::run-deltic # suite-plain -> deltic-deno +just conformance-ct::run-deltic-delegated # suite-delegated -> deltic-deno-delegated +``` + +The on-demand webcrypto composition (`suite-delegated-webcrypto`) runs +under deltic the same way — deltic's own repo smokes it +(`tools/smoke-tls`) — but like the wasmtime row it is not a standing +target here. + +## Pinning + +deltic is pinned to a release tag in `deno.json` (import-map URLs; +`deno.lock` carries the module-graph integrity, enforced with +`--frozen`) and `fetch-translator.ts` (TAG + sha256 for the +`deltic-translator-shim.wasm` release asset, cached under +`target/deltic//`), cross-checked at run time. To bump: update the +tag in both files and the sha from the release's `SHA256SUMS`, delete +`deno.lock`, re-run `deno cache run.ts fetch-translator.ts` here, and +commit the diff. diff --git a/conformance/driver-ct/deltic/deno.json b/conformance/driver-ct/deltic/deno.json new file mode 100644 index 0000000..6fd1543 --- /dev/null +++ b/conformance/driver-ct/deltic/deno.json @@ -0,0 +1,12 @@ +{ + "//": "The deltic release pin (TAG in fetch-translator.ts must match; its assertPinConsistency checks). @deltic/runtime/embedder is mapped because wasi-shims imports it by bare specifier internally.", + "imports": { + "@deltic/ct-runner": "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/ct-runner/src/mod.ts", + "@deltic/runtime/embedder": "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/embedder/mod.ts", + "@deltic/runtime/shim": "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/shim/mod.ts", + "@deltic/wasi-shims": "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/wasi-shims/src/mod.ts" + }, + "tasks": { + "check": "deno check run.ts fetch-translator.ts" + } +} diff --git a/conformance/driver-ct/deltic/deno.lock b/conformance/driver-ct/deltic/deno.lock new file mode 100644 index 0000000..281c48d --- /dev/null +++ b/conformance/driver-ct/deltic/deno.lock @@ -0,0 +1,66 @@ +{ + "version": "5", + "remote": { + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/ct-runner/src/context.ts": "366db52e3189260a7fd2fc2fdb90aea9bd6a3055d83c42acad082eb75565c634", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/ct-runner/src/import-analysis.ts": "64971e796ebccd98730ba2a0e78b599db38284f22b7976687fc4cad898703c32", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/ct-runner/src/mod.ts": "24a88cb8dda9c1d346a1809297cc5b2ab1c3a2d39c4914694c2ee5f76e9911db", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/ct-runner/src/run-suite.ts": "76d76ed7dfbeb7ce24410dfabadb8f1524fe6e1adb0428b7d361310168a44411", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/ct-runner/src/tags.ts": "d64136eb7e21e18e73cc255e052f59377d2be869f4929bf4fc6de026f3b74a0b", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/cabi/async_values.ts": "af1279d4e4db5b756268979aeff5b27c1cf6c0f021213655676ade90472f282b", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/cabi/context.ts": "b4b60891ef9d9e72b208636f6ba37f0b9b6962d307af6156ad3b5ad59a626902", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/cabi/flatten.ts": "6c980fe38d7adce349d5e028b819eb0ffbb92714f958c1d5daae8da3e7ed3889", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/cabi/float.ts": "0483e8c1aa8786eee4c6f6357fee6738555e4310650c474aba6cd811a80d7d36", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/cabi/handles.ts": "30510750261499f48a812bb8c349a8f88a3bb7239175e6f1d4e6d10c38571e5d", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/cabi/layout.ts": "8122141b39f4d8189c13d91fc1b37825ceead86988f879f3fa9351bbef96f8f2", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/cabi/lift.ts": "e4475a44a5618114f288025601b535bc04b97e9a37b3be21f51d3be092d419c8", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/cabi/load.ts": "c1d8ddb1b3b3c59afe30710a97ad6dd7ae1ecd59aa1d427a5eaf4552d3b1ea01", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/cabi/lower.ts": "916ef7476dc583783770f4c42de7a655350531b3763c81a92249cca96f5e4d80", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/cabi/memory.ts": "09728360d6413fb30a5a7bff1ba6abec1ac6474ff150d45f093b8ebe5e65cd51", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/cabi/mod.ts": "b79cf9e2bab2e837fee76fa61dc18bff66d941e08597f1b76de93811bd6d6008", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/cabi/store.ts": "97aaecfeb4dfbf5c3c132fb5eadf1f5677924936eee0c7fa75a266a00cd73634", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/cabi/strings.ts": "9589dda3857725792ae15ef6888449b48e973b9eb0f3058ed64e10bf4d39b793", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/cabi/trap.ts": "307d8b48806eeba30400b3d7db9370cee70a12298851c1c19053dd8ca0013e1c", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/cabi/types.ts": "d0392e8cdf2990a76c8a1f9b85795d3b7c19b8eb006c2b159b671d08c39b9535", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/cabi/values.ts": "9e6ddcc4192d05897b2cbea250db3fef0ad9bf6548ba87aff378ee14b7ab7022", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/embedder/casing.ts": "1e9083becfc08107c09015ce3db79c304b05c40085a3c899ea1c8ebe25fcd45f", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/embedder/errors.ts": "b0cac244526b92c052d165f2aee1d9492e5915a5a4cad114e1ab575ffe1587ba", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/embedder/imports.ts": "98cca003e4a1131c35854c91b458f109d6761a3e8f67c23730f7e9bc28bbad88", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/embedder/instantiate.ts": "2479c085a82adc20eb3e8e11832cad8daaa50992d383e8a38d73fbc7259f52e5", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/embedder/mod.ts": "0a4f42b8c569b528b4c3172c3394ad5f9ddafa33bcaf5eccd00e645e111da2b1", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/embedder/resources.ts": "d209e5f13545b9c0c095ac4e188b72370d97c9bd394ba7c8793ddd74f436b1ef", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/embedder/streams.ts": "4ef894a43da94b4cb01ee65798a108a8fb3f6b2dc6013c71881f63e0806df565", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/embedder/values.ts": "ed876f9103f4a4f34e8eb475934091156bee1447f5a029ea300644b8f3ee71eb", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/embedder/version.ts": "b1c589988e5fb88dce3a014846c9253399e286f12afb5fd92509c8d6090ad4bb", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/exec/boundary.ts": "8a162aefc3524ce1a72f294a95eadc92b66764de75bad84966301192a57ae92e", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/exec/executor.ts": "55044c381d842a9d0f17731d55b47b48023d3a9222806e4b0607b53615a1dc97", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/exec/host_streams.ts": "63f6b113806c401ae9895df82448da70a7745a97b6e2f04061fb5bc64e7d0acf", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/exec/mod.ts": "a46320977ece14342bcb72c9c9e36d65a1cd09d789591d0909d7d1185264010b", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/intrinsics/async_builtins.ts": "526795358da8908d54a483bb47eebc43e0a1ea59e69ece94d0c6890ad0fa8784", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/intrinsics/context.ts": "be93b23d127ff71d5c372781f89d1c3746c5d32a44e67ebbcd91f2b0f0807e93", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/intrinsics/errors.ts": "9d09fc1818b4dc98b238aa69008a9110d9d305b6a8e806604f3bd48fca1eebcb", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/intrinsics/fact_calls.ts": "aa0b0aef81b59cdcd8dc572c20e1f57a8f5592f75a0d5d666032851df9201229", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/intrinsics/mod.ts": "f9c095e561f5fbb51f70693b21f272f66241f2e8ff2e1a83cd4176bcd0104eb9", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/intrinsics/stream_builtins.ts": "bbc1e1ea0e4616026a46d790a68695aa70589a88b08a6275acdb525f0ab531ec", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/intrinsics/transcode.ts": "e3fcaeb7a60b6cbad999d9389d4bce59e305e6f54e035ba791f909e10d1f82c7", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/jspi/bridge.ts": "7cf3706d3bf34b503aea516a31918a8d930aba3dac7e94ec04caecd23fe6025e", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/jspi/mechanics.ts": "dc0fe4965b3ef8c0aff6674afd8bae2a38942ab934fa07fd2eb7db72b2462f17", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/jspi/mod.ts": "4d047b820b50c410ed946c62dc48286f8abe4787ce6ae5466cd0ae255d98943c", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/jspi/types.ts": "86929224733a764a148ac75a9d6b95d61ab4c8123a48fe956d998e97726a1432", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/plan/format.ts": "90e31bbc7137c2f80c0782e1431afb6f81827aab8d38dba1178b8761f1b3ea0a", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/plan/loader.ts": "107db77e724a7f74f161a5fd20e7110a6e6f182c46f18282eba650bc887dc876", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/shim/mod.ts": "34af2240dfd0be720def487db2db34eaad6ba9178003f20e2193d03a0632779b", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/shim/translator.ts": "7ea1a4101363ee62ddedb9d6c3f798fd6042886ef38ee13046ac3cdb9485bf24", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/task/mod.ts": "5decca8045dfd9743910e83d512258a7be3b0d0917954b8d9cdbac38e03f7dfb", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/task/scheduler.ts": "18a4404f620407bd867876115861ee0cf98f6f1ccd41c5f3c877ef90e429ef9c", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/task/streams.ts": "83b522a6393ba06fbdb87881bc6761f3fce9c03b85e9eda03d3befe7d2605a60", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/task/subtask.ts": "750b13a1318f62836bfd149f1b9144de5b017fd7a84adc8e2fb2151e63130fbc", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/task/thread.ts": "81fe38b37a1ec130803b478a24e428b19ee4e1ef8c0bae741395cd8d52751580", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/runtime/src/task/waitable.ts": "5e1fc092e3d8f1fb4429d6a91d8886b3e474aa9ac6254e7924fd896c4929e1f9", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/wasi-shims/src/cli.ts": "d1617e12dc2569f4ee107f8b92488797daf431d14b8a86a1ab10750a28757394", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/wasi-shims/src/clocks.ts": "05468a822b635408ce3a671b40fd06fd4448c220019f9449bf029ac1c7e59664", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/wasi-shims/src/filesystem.ts": "6dcead5346d78084c3923410e44875e678f3b58db0c2d59513339b428596ec25", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/wasi-shims/src/io.ts": "dfe270e5ad3388c02696e27a5c69c58a411759fe8c99416361b0ac10177366da", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/wasi-shims/src/mod.ts": "1748985cf851252e1755aafd9ebb9c7ae96003ec41322d9524a952062d2b8570", + "https://raw.githubusercontent.com/lann/deltic/pre-83fff30/wasi-shims/src/random.ts": "dc04d20de5399cc7fa8685a04ec954618e3994a374ef94535fff408a745425e2" + } +} diff --git a/conformance/driver-ct/deltic/fetch-translator.ts b/conformance/driver-ct/deltic/fetch-translator.ts new file mode 100644 index 0000000..16f64d3 --- /dev/null +++ b/conformance/driver-ct/deltic/fetch-translator.ts @@ -0,0 +1,86 @@ +// Fetch (and cache) the deltic translator-shim wasm for the pinned release. +// +// deltic is a runtime linker: components are translated by a wasm build of +// its translator, shipped as a release asset so consumers need no Rust +// toolchain. This script downloads that asset once into target/deltic/, +// verifies it against the pinned sha256, and prints the cached path on +// stdout (the `conformance-ct::run-deltic*` recipes capture it). +// +// THE PIN lives here (TAG + TRANSLATOR_SHA256) and in the sibling +// deno.json's import-map URLs. `assertPinConsistency` fails loud if the +// two drift. Bumping: update TAG here and in deno.json, update +// TRANSLATOR_SHA256 from the release's SHA256SUMS, delete deno.lock, and +// re-run `deno cache run.ts fetch-translator.ts` in this directory to +// regenerate it (commit the diff). + +const TAG = "pre-83fff30"; +const TRANSLATOR_SHA256 = + "6d02b363785593595a789d083cda0aebb1de790726718ccf543198354fa3870c"; +const ASSET = "deltic-translator-shim.wasm"; + +const HERE = new URL(".", import.meta.url); +const REPO_ROOT = new URL("../../../", HERE); +const CACHE_DIR = new URL(`target/deltic/${TAG}/`, REPO_ROOT); +const CACHED = new URL(ASSET, CACHE_DIR); +const RELEASE_URL = + `https://github.com/lann/deltic/releases/download/${TAG}/${ASSET}`; + +async function sha256Hex(bytes: Uint8Array): Promise { + const digest = await crypto.subtle.digest( + "SHA-256", + bytes as BufferSource, + ); + return Array.from(new Uint8Array(digest)) + .map((b) => b.toString(16).padStart(2, "0")) + .join(""); +} + +/** The one-pin-everywhere gate: every raw.githubusercontent URL in the + * sibling import map must reference TAG. */ +async function assertPinConsistency(): Promise { + const denoJson = await Deno.readTextFile(new URL("deno.json", HERE)); + const urls = denoJson.match(/https:\/\/raw\.githubusercontent\.com[^"]+/g) ?? []; + if (urls.length === 0) { + throw new Error("deno.json: no pinned deltic URLs found"); + } + for (const url of urls) { + if (!url.includes(`/lann/deltic/${TAG}/`)) { + throw new Error( + `pin drift: deno.json pins ${url}\nbut fetch-translator.ts pins ${TAG}`, + ); + } + } +} + +async function main() { + await assertPinConsistency(); + + try { + const bytes = await Deno.readFile(CACHED); + if (await sha256Hex(bytes) === TRANSLATOR_SHA256) { + console.log(CACHED.pathname); + return; + } + console.error(`cached ${ASSET} has a stale digest; re-fetching`); + } catch { + // not cached yet + } + + console.error(`fetching ${RELEASE_URL} …`); + const resp = await fetch(RELEASE_URL); + if (!resp.ok) { + throw new Error(`GET ${RELEASE_URL}: ${resp.status} ${resp.statusText}`); + } + const bytes = new Uint8Array(await resp.arrayBuffer()); + const got = await sha256Hex(bytes); + if (got !== TRANSLATOR_SHA256) { + throw new Error( + `sha256 mismatch for ${ASSET}@${TAG}:\n want ${TRANSLATOR_SHA256}\n got ${got}`, + ); + } + await Deno.mkdir(CACHE_DIR, { recursive: true }); + await Deno.writeFile(CACHED, bytes); + console.log(CACHED.pathname); +} + +await main(); diff --git a/conformance/driver-ct/deltic/run.ts b/conformance/driver-ct/deltic/run.ts new file mode 100644 index 0000000..7b066c5 --- /dev/null +++ b/conformance/driver-ct/deltic/run.ts @@ -0,0 +1,139 @@ +// The deltic leg of the conformance harness: runs a composed artifact +// (the shared suite fused with one TLS delivery) runtime-linked under +// deltic on stock Deno, and writes component-test results JSONL for the +// aggregate — the deltic analogue of ../jco/run-node.mjs, mirroring its +// frame exactly: +// +// run-node.mjs | this runner +// --------------------------------------+--------------------------- +// jco transpile + loadCoreModules | translator.translate(bytes) +// bindImports (preview2-shim, both | wasiShims() (track-keyed: +// wasi minor spellings bound) | one @0.2 provider serves +// | every minor) +// inventoryLookup(coreBytes) + missing | deltic reads the suite's own +// via runSuiteJsonl | embedded inventory; missing +// | via runSuite (deltic#25) +// node --experimental-wasm-jspi | stock deno, callback ABI — +// | no engine flag +// +// The artifacts import only wasi 0.2 and test-context, so there is no +// SUT host module on this leg (the TLS delivery is fused in-guest); +// deltic's runner supplies test-context itself. No network, no PKI: +// the suite's cryptography runs in-guest. +// +// deno run --allow-read=../../.. --allow-write=../results \ +// --config deno.json --frozen run.ts --suite suite-plain \ +// --missing delegated-signer --target deltic-deno \ +// --translator + +import { Translator } from "@deltic/runtime/shim"; +import type { ComponentArtifacts } from "@deltic/runtime/embedder"; +import { runSuite } from "@deltic/ct-runner"; +import { wasiShims } from "@deltic/wasi-shims"; + +const ROOT = new URL("../../../", import.meta.url); +const RESULTS = new URL("../results/", import.meta.url); +/** The un-composed suite: results provenance points here, exactly like + * the wasmtime legs' `--suite-artifact` (wac-composed artifacts each + * hash differently; the aggregate warns on mixed provenance). */ +const GUEST = new URL( + "target/wasm32-wasip2/release/conformance_guest_ct.wasm", + ROOT, +); + +async function sha256Hex(bytes: Uint8Array): Promise { + const digest = await crypto.subtle.digest("SHA-256", bytes as BufferSource); + return Array.from(new Uint8Array(digest)) + .map((b) => b.toString(16).padStart(2, "0")) + .join(""); +} + +// The single-attempt wall bound per case, matching the other legs. +const CASE_TIMEOUT_MS = 60_000; + +interface Cli { + suite: string; + target: string; + suiteName: string; + missing: string[]; + translator: string; +} + +function parseCli(argv: string[]): Cli { + let suite: string | undefined; + let target: string | undefined; + // The lockfile suite identity (the un-composed suite's wasm stem); + // the composed artifact's name never appears in results. + let suiteName = "conformance-guest-ct"; + let missing: string[] = []; + let translator: string | undefined; + for (let i = 0; i < argv.length; i++) { + switch (argv[i]) { + case "--suite": + suite = argv[++i]; + break; + case "--target": + target = argv[++i]; + break; + case "--suite-name": + suiteName = argv[++i]; + break; + case "--missing": + missing = argv[++i].split(",").filter((f) => f !== ""); + break; + case "--translator": + translator = argv[++i]; + break; + default: + throw new Error(`unknown argument ${argv[i]}`); + } + } + if (!suite || !target || !translator) { + console.error( + "usage: run.ts --suite --target " + + "--translator [--missing f1,f2] [--suite-name name]", + ); + Deno.exit(2); + } + return { suite, target, suiteName, missing, translator }; +} + +async function main() { + const cli = parseCli(Deno.args); + const componentBytes = await Deno.readFile( + new URL(`target/conformance/${cli.suite}.wasm`, ROOT), + ); + const translator = await Translator.create( + await Deno.readFile(cli.translator), + ); + const { plan, adapters } = translator.translate(componentBytes); + const artifacts: ComponentArtifacts = { plan, componentBytes, adapters }; + + const lines: string[] = []; + const counts = await runSuite(artifacts, { + imports: wasiShims(), + target: cli.target, + suiteName: cli.suiteName, + missing: cli.missing, + caseTimeoutMs: CASE_TIMEOUT_MS, + emit: (line) => lines.push(line), + log: (msg) => console.error(` ${msg}`), + }); + + // --suite-artifact semantics (see GUEST above): re-point the envelope's + // artifact-sha256 at the un-composed suite. + const envelope = JSON.parse(lines[0]); + envelope.suite["artifact-sha256"] = await sha256Hex(await Deno.readFile(GUEST)); + lines[0] = JSON.stringify(envelope); + + await Deno.mkdir(RESULTS, { recursive: true }); + const out = new URL(`${cli.target}.jsonl`, RESULTS); + await Deno.writeTextFile(out, lines.join("\n") + "\n"); + console.error( + `${counts.passed} passed | ${counts.failed} failed | ${counts.skipped} skipped | ` + + `${counts.na} n/a (${counts.total} total) -> ${out.pathname}`, + ); + if (!(counts.failed === 0 && counts.total > 0)) Deno.exit(1); +} + +await main(); diff --git a/conformance/driver-ct/justfile b/conformance/driver-ct/justfile index 3e0f9fd..d1c25a1 100644 --- a/conformance/driver-ct/justfile +++ b/conformance/driver-ct/justfile @@ -123,6 +123,34 @@ run-jco-node-delegated: _jco-prepared node --experimental-wasm-jspi run-node.mjs --suite suite-delegated \ --target jco-node-delegated +# The composed artifact runtime-linked under deltic on stock Deno — +# no transpile step, no generated tree, no engine flag (callback ABI). +# The pin and the module-graph lock live in deltic/ (see its README). +run-deltic: build + #!/usr/bin/env bash + set -euo pipefail + cd {{root}}/conformance/driver-ct/deltic + translator=$(deno run --allow-read=. --allow-write=../../../target/deltic \ + --allow-net=github.com,objects.githubusercontent.com,release-assets.githubusercontent.com \ + fetch-translator.ts) + deno run --allow-read=../../..,"$translator" --allow-write=../results \ + --config deno.json --frozen run.ts \ + --suite suite-plain --missing delegated-signer \ + --target deltic-deno --translator "$translator" + +# The composed-delegated artifact under deltic on stock Deno. +run-deltic-delegated: build + #!/usr/bin/env bash + set -euo pipefail + cd {{root}}/conformance/driver-ct/deltic + translator=$(deno run --allow-read=. --allow-write=../../../target/deltic \ + --allow-net=github.com,objects.githubusercontent.com,release-assets.githubusercontent.com \ + fetch-translator.ts) + deno run --allow-read=../../..,"$translator" --allow-write=../results \ + --config deno.json --frozen run.ts \ + --suite suite-delegated \ + --target deltic-deno-delegated --translator "$translator" + # The on-demand third target: the `tls-delegated` world over the # webcrypto-signer shim and a real polymorph:webcrypto provider, cloned # and built at the rev pinned alongside the shim's vendored WIT. @@ -170,6 +198,8 @@ aggregate: _ct-tools --results composed-delegated={{results}}/composed-delegated.jsonl \ --results jco-node={{results}}/jco-node.jsonl \ --results jco-node-delegated={{results}}/jco-node-delegated.jsonl \ + --results deltic-deno={{results}}/deltic-deno.jsonl \ + --results deltic-deno-delegated={{results}}/deltic-deno-delegated.jsonl \ ${extra[@]+"${extra[@]}"} \ -o {{results}}/matrix.md @@ -197,7 +227,7 @@ _run-browser-if-enabled: # The standing matrix: inventory check, all standing targets, # aggregate. Stale on-demand webcrypto results are cleared first so the # standing run is deterministic. -all: lock-check run-composed run-delegated run-jco-node run-jco-node-delegated _run-browser-if-enabled _clear-webcrypto aggregate +all: lock-check run-composed run-delegated run-jco-node run-jco-node-delegated run-deltic run-deltic-delegated _run-browser-if-enabled _clear-webcrypto aggregate _clear-webcrypto: rm -f results/composed-delegated-webcrypto.jsonl diff --git a/conformance/driver-ct/matrix.md b/conformance/driver-ct/matrix.md index 6c9b61b..f67be1e 100644 --- a/conformance/driver-ct/matrix.md +++ b/conformance/driver-ct/matrix.md @@ -4,13 +4,13 @@ - target `composed-delegated-webcrypto`: no results (declared optional) -| Case | composed | composed-delegated | composed-delegated-webcrypto | jco-browser | jco-browser-delegated | jco-node | jco-node-delegated | -| --- | --- | --- | --- | --- | --- | --- | --- | -| data (1 cases) | pass | pass | — | pass | pass | pass | pass | -| delegated (3 cases) | 2 N/A, 1 pass | 1 N/A, 2 pass | — | 2 N/A, 1 pass | 1 N/A, 2 pass | 2 N/A, 1 pass | 1 N/A, 2 pass | -| handshake (1 cases) | pass | pass | — | pass | pass | pass | pass | -| identity (1 cases) | pass | pass | — | pass | pass | pass | pass | -| shutdown (1 cases) | pass | pass | — | pass | pass | pass | pass | +| Case | composed | composed-delegated | composed-delegated-webcrypto | deltic-deno | deltic-deno-delegated | jco-browser | jco-browser-delegated | jco-node | jco-node-delegated | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| data (1 cases) | pass | pass | — | pass | pass | pass | pass | pass | pass | +| delegated (3 cases) | 2 N/A, 1 pass | 1 N/A, 2 pass | — | 2 N/A, 1 pass | 1 N/A, 2 pass | 2 N/A, 1 pass | 1 N/A, 2 pass | 2 N/A, 1 pass | 1 N/A, 2 pass | +| handshake (1 cases) | pass | pass | — | pass | pass | pass | pass | pass | pass | +| identity (1 cases) | pass | pass | — | pass | pass | pass | pass | pass | pass | +| shutdown (1 cases) | pass | pass | — | pass | pass | pass | pass | pass | pass | ## Failures @@ -21,6 +21,8 @@ None. - `composed`: 2 N/A, 5 pass (7 total) - `composed-delegated`: 1 N/A, 6 pass (7 total) - `composed-delegated-webcrypto`: no results +- `deltic-deno`: 2 N/A, 5 pass (7 total) +- `deltic-deno-delegated`: 1 N/A, 6 pass (7 total) - `jco-browser`: 2 N/A, 5 pass (7 total) - `jco-browser-delegated`: 1 N/A, 6 pass (7 total) - `jco-node`: 2 N/A, 5 pass (7 total) diff --git a/conformance/driver-ct/targets.toml b/conformance/driver-ct/targets.toml index 42dff55..38da8fa 100644 --- a/conformance/driver-ct/targets.toml +++ b/conformance/driver-ct/targets.toml @@ -38,6 +38,16 @@ missing-features = ["delegated-signer"] [targets.jco-node-delegated] missing-features = [] +# The composed artifact runtime-linked under deltic on stock Deno +# (driver-ct/deltic/run.ts): no transpile step, no engine flag — the +# release-pinned runtime links the component at load time. +[targets.deltic-deno] +missing-features = ["delegated-signer"] + +# The composed-delegated artifact under deltic on stock Deno. +[targets.deltic-deno-delegated] +missing-features = [] + # As composed-delegated, but the signer is the webcrypto-signer shim # over a real polymorph:webcrypto provider (the sibling repository, # cloned and built at the rev pinned alongside the shim's vendored