From 77a14aa36a8bedf4841f470e99698677b56a1a23 Mon Sep 17 00:00:00 2001 From: Lann Martin Date: Fri, 21 Aug 2026 22:37:51 -0400 Subject: [PATCH] polyengine 0.3.0 (the deltic rename); @polymorph/test 0.2.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The engine renamed deltic -> polyengine (@deltic/* -> @polyengine/* on JSR) and cut 0.3.0. Full rename here to match: js/runner-deltic -> js/runner-polyengine, the viewer's deltic.mjs -> polyengine.mjs, the verify-deltic-* goldens -> verify-polyengine-*, justfile targets, and the runner's default target string (deltic/deno -> polyengine/deno, goldens regenerated). Pins move to exact jsr:@polyengine/*@0.3.0 with the lock regenerated; the minimumDependencyAge exclude follows the scope. Historical references to the deltic era stay under the old name where they record it accurately. @polymorph/test bumps 0.1.1 -> 0.2.0 (breaking: the exports rename to ./polyengine-worker, ./polyengine-engine, ./polyengine-worker-main, and workerMain's option key is now `polyengine`). Gates: just all, just check, polyengine-pin-gate, verify-polyengine, verify-viewer — all green against the published 0.3.0. --- .github/workflows/ci.yml | 4 +- .github/workflows/pages.yml | 12 +- .gitignore | 2 +- AGENTS.md | 23 +-- README.md | 4 +- docs/findings.md | 11 +- docs/runner-policy.md | 2 +- ...txt => verify-polyengine-fixture-fold.txt} | 0 ....jsonl => verify-polyengine-fixture.jsonl} | 2 +- ...e.jsonl => verify-polyengine-sample.jsonl} | 2 +- js/deno.json | 16 +-- js/runner-deltic/browser-bundle-entry.ts | 18 --- js/runner-deltic/deno.lock | 49 ------- .../README.md | 58 ++++---- .../bench-mint.mjs | 26 ++-- js/runner-polyengine/browser-bundle-entry.ts | 18 +++ .../browser-worker.mjs | 10 +- .../deno.json | 26 ++-- js/runner-polyengine/deno.lock | 49 +++++++ .../engine.mjs | 32 ++--- .../runner.ts | 24 ++-- .../selftest.mjs | 20 +-- .../worker-main.mjs | 26 ++-- js/viewer/README.md | 12 +- js/viewer/app.mjs | 4 +- js/viewer/harness.mjs | 6 +- js/viewer/{deltic.mjs => polyengine.mjs} | 24 ++-- js/viewer/selftest.mjs | 24 ++-- justfile | 131 +++++++++--------- 29 files changed, 319 insertions(+), 316 deletions(-) rename expected/{verify-deltic-fixture-fold.txt => verify-polyengine-fixture-fold.txt} (100%) rename expected/{verify-deltic-fixture.jsonl => verify-polyengine-fixture.jsonl} (87%) rename expected/{verify-deltic-sample.jsonl => verify-polyengine-sample.jsonl} (80%) delete mode 100644 js/runner-deltic/browser-bundle-entry.ts delete mode 100644 js/runner-deltic/deno.lock rename js/{runner-deltic => runner-polyengine}/README.md (63%) rename js/{runner-deltic => runner-polyengine}/bench-mint.mjs (81%) create mode 100644 js/runner-polyengine/browser-bundle-entry.ts rename js/{runner-deltic => runner-polyengine}/browser-worker.mjs (70%) rename js/{runner-deltic => runner-polyengine}/deno.json (55%) create mode 100644 js/runner-polyengine/deno.lock rename js/{runner-deltic => runner-polyengine}/engine.mjs (63%) rename js/{runner-deltic => runner-polyengine}/runner.ts (86%) rename js/{runner-deltic => runner-polyengine}/selftest.mjs (86%) rename js/{runner-deltic => runner-polyengine}/worker-main.mjs (80%) rename js/viewer/{deltic.mjs => polyengine.mjs} (65%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 94033c8..b0eabcf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,9 +37,9 @@ jobs: # The full verification matrix: component builds, all execution # paths (host-embed runner, composed wasi:cli runner under wasmtime, - # deltic runner under stock Deno + its selftest under plain Node, + # polyengine runner under stock Deno + its selftest under plain Node, # inventory + results pipeline), lockfile drift checks. No engine - # flags: the jco/JSPI lane was deleted in the deltic migration. + # flags: the jco/JSPI lane was deleted in the deltic (now polyengine) migration. verify: runs-on: ubuntu-latest timeout-minutes: 25 diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 5fe0f39..492d76b 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -59,18 +59,18 @@ jobs: # The tree mirrors the repository layout: the viewer resolves # its engines and the demo fixtures by relative path (see # js/viewer/README.md), so publishing preserves paths instead - # of flattening. Everything is runtime-linked by deltic in the + # of flattening. Everything is runtime-linked by polyengine in the # page — no transpiled trees, no shim node_modules. run: | set -euo pipefail - mkdir -p _site/js/viewer _site/js/runner-deltic _site/components/fixture-suite _site/examples/aggregate _site/expected + mkdir -p _site/js/viewer _site/js/runner-polyengine _site/components/fixture-suite _site/examples/aggregate _site/expected cp -r js/viewer/index.html js/viewer/app.mjs js/viewer/viewer.css \ - js/viewer/harness.mjs js/viewer/context.js js/viewer/deltic.mjs \ + js/viewer/harness.mjs js/viewer/context.js js/viewer/polyengine.mjs \ js/viewer/README.md js/viewer/generated js/viewer/suite \ - js/viewer/deltic \ + js/viewer/polyengine \ _site/js/viewer/ - cp js/runner-deltic/browser-worker.mjs js/runner-deltic/engine.mjs \ - _site/js/runner-deltic/ + cp js/runner-polyengine/browser-worker.mjs js/runner-polyengine/engine.mjs \ + _site/js/runner-polyengine/ cp components/fixture-suite/tests.lock _site/components/fixture-suite/ cp examples/aggregate/targets.toml _site/examples/aggregate/ cp expected/verify-pipeline-fixture.jsonl _site/expected/ diff --git a/.gitignore b/.gitignore index 5db6562..9283b91 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,4 @@ node_modules/ # Viewer build products (transpiles of the wasm engines/suites) js/viewer/generated/ js/viewer/suite/ -js/viewer/deltic/ +js/viewer/polyengine/ diff --git a/AGENTS.md b/AGENTS.md index 2a9b4fd..1cceb0f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -68,7 +68,7 @@ components/ guest components (build with --target wasm32-wasip2) drift-fixture broken by design: raw registration, drift check zero-gen-fixture broken by design: zero-row decline generator hang-fixture broken by design: CPU spin + async wedge (#45) -js/runner-deltic/ deltic runner leg: CLI, browser shard worker, node +js/runner-polyengine/ polyengine runner leg: CLI, browser shard worker, node selftest (runner-is-provider topology; release-pinned) actions/ composite GitHub Actions for consumers (#14): aggregate (matrix -> job summary, findings -> @@ -98,11 +98,11 @@ with copies; symlinks require `core.symlinks` on Windows. wasmtime 47 (`-W component-model-async -S p3`), wac-cli 0.10, wit-bindgen 0.60, Node 24 (plain — the selftest legs; no engine flags anywhere: -deltic's callback ABI needs no JSPI), deno 2.9 (deltic runner -leg + browser-asset build; deltic itself is consumed from JSR as exact -prerelease pins — see `js/runner-deltic/README.md`), Rust +polyengine's callback ABI needs no JSPI), deno 2.9 (polyengine runner +leg + browser-asset build; polyengine itself is consumed from JSR as exact +release pins — see `js/runner-polyengine/README.md`), Rust target `wasm32-wasip2`, wasm-tools (WIT validation), just (task -runner). jco is GONE from this repo (the deltic migration's Phase 4 +runner). jco is GONE from this repo (the deltic (now polyengine) migration's Phase 4 cutover); its findings in `docs/findings.md` are historical. Known sharp edges are catalogued in `docs/findings.md` — read it before fighting the toolchain; your bug is probably finding #5, #6, @@ -152,17 +152,18 @@ them before committing anything cross-cutting): 2. **Composed runner** (see `examples/compose/README.md`): bundle via `wac compose`, plug via `wac plug`, run under `wasmtime run -W component-model-async -S p3`. Same sample-suite verdicts. -3. **deltic runner + browser leg** (see `js/runner-deltic/README.md`): - drive the suite directly under deltic — no transpile step, no engine - flag; JSR-pinned in `js/runner-deltic/deno.json` + `deno.lock`. Same +3. **polyengine runner + browser leg** (see `js/runner-polyengine/README.md`): + drive the suite directly under polyengine — no transpile step, no engine + flag; JSR-pinned in `js/runner-polyengine/deno.json` + `deno.lock`. Same sample verdicts (shared human + fold goldens); tag scheduling from the suite's own embedded inventory (fixture leg runs `--missing hsm` like - Paths 1/4, lane goldens in `expected/verify-deltic-*`). The browser + Paths 1/4, lane goldens in `expected/verify-polyengine-*`). The browser worker (`browser-worker.mjs`, drop-in for `page-runner.mjs` via `workerUrl`) shares `harness.mjs`'s case loop; `selftest.mjs` gates - that engine path under plain node as `verify-deltic`'s last leg. (The + that engine path under plain node as `verify-polyengine`'s last leg. (The jco-node runner that used to be this path was deleted in the deltic - migration's Phase 4; `js/viewer/browser-worker.mjs` remains as + (now polyengine) migration's Phase 4; `js/viewer/browser-worker.mjs` + remains as consumer-facing glue for transpiled-module layouts.) 4. **Inventory + results pipeline**: ```sh diff --git a/README.md b/README.md index be92be2..9010df8 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ together is described in [ARCHITECTURE.md](ARCHITECTURE.md). Layout: [`crates/`](crates/) (host-side Rust: core model, formats, results schema, guest SDK, CLI, host-embed runner), [`components/`](components/) (guest components: reference provider, composed CLI runner core, sample -and fixture suites), [`js/`](js/) (deltic runner leg + browser harness), +and fixture suites), [`js/`](js/) (polyengine runner leg + browser harness), [`examples/compose/`](examples/compose/) (composition walkthrough), [`examples/aggregate/`](examples/aggregate/) (cross-target aggregation walkthrough), [`docs/findings.md`](docs/findings.md) (toolchain @@ -264,7 +264,7 @@ WPT, `go test`, LLVM lit) is tracked in the issues. decline cases). - The reference `test-context` provider component. - Runners: `wasi:cli`, `wasi:http` (served UI + remote API), in-browser via - deltic (runtime-linked), native embedding with a libtest-mimic frontend. + polyengine (runtime-linked), native embedding with a libtest-mimic frontend. - Semver-compatible-linking verification for the `test-context` growth path; custom-section survival through composition tooling. - Inventory lockfiles (names + tags) and the update workflow, including diff --git a/docs/findings.md b/docs/findings.md index 5fa2ee6..629748e 100644 --- a/docs/findings.md +++ b/docs/findings.md @@ -137,9 +137,10 @@ N trivially-passing cases, no corpus, no per-case data (`components/bench-suite`, count via `BENCH_CASES` env). Drivers: `bench-mint` bin (wasmtime, production `Runner` config: pooling, CoW, epoch instrumentation, untyped `Val` calls) and -`js/runner-deltic/bench-mint.mjs` (pinned deltic embedder, plain +`js/runner-polyengine/bench-mint.mjs` (pinned polyengine embedder, plain Node). Medians over 20/10 fresh instances, one dev box (17-core -x86_64 Linux), wasmtime 47.0.3 / deltic pre-83fff30 / Node 24. +x86_64 Linux), wasmtime 47.0.3 / deltic pre-83fff30 (the engine's +pre-rename name; now polyengine) / Node 24. 19. **wasmtime: `all()` splits ~3:1 registry-build : mint+lift, both linear.** At 10k cases: all#1 (build + mint + lift) 3.2ms, all#2 @@ -154,7 +155,7 @@ x86_64 Linux), wasmtime 47.0.3 / deltic pre-83fff30 / Node 24. wizer) buys more than lift avoidance alone; a direct-access interface caps out at ~25% unless stacked on a lazy/static registry. -20. **deltic (runtime linker, callback ABI): same shape, bigger +20. **polyengine (runtime linker, callback ABI): same shape, bigger constants.** Instantiate ~650µs (~30× wasmtime); mint+lift ~340–370ns/handle (~4.3×; mildly superlinear by 30k — V8 GC on the wrapper objects); per-call boundary overhead ~25µs (~10×); @@ -165,7 +166,7 @@ x86_64 Linux), wasmtime 47.0.3 / deltic pre-83fff30 / Node 24. 21. **`harness.mjs` fresh-instance relocation was the real JS-leg quadratic** (fixed — positional relocation, PR #83): `freshCases` re-found each case by a linear `name()` scan. Hot-loop `name()` - costs ~3.4µs under deltic (a cold single call measures ~26µs — + costs ~3.4µs under polyengine (a cold single call measures ~26µs — promise/JIT overhead that amortizes), so the scan averaged ~N/2 × 3.4µs ≈ **17ms per case** at 10k (33ms worst, measured), a multiple of the `all()` re-enumeration it followed and O(N²) @@ -223,7 +224,7 @@ bench-suite artifact built with its `wizer-init` feature. full-isolation run: 30.8s → 7.1s sequential (4.3×), **1.14s at jobs=8** — per-case isolation on a wizened suite undercuts the shared-instance numbers that motivated relaxing isolation in #22. -24. **deltic, wizened suite: net ~1.5× only.** all#1 6.9ms → 2.9ms, +24. **polyengine, wizened suite: net ~1.5× only.** all#1 6.9ms → 2.9ms, but instantiate 0.78ms → 2.17ms: V8 has no CoW memory images, so the 1.29MB active data segment is copied at every instantiation, eating most of the build win (translate also 24ms → 44ms, diff --git a/docs/runner-policy.md b/docs/runner-policy.md index 348a60d..08066f4 100644 --- a/docs/runner-policy.md +++ b/docs/runner-policy.md @@ -92,7 +92,7 @@ the wizened artifact (finding 22). When it does *not* pay: -- **JS legs (deltic, browser): net ~1.5× at best.** V8 has no +- **JS legs (polyengine, browser): net ~1.5× at best.** V8 has no copy-on-write memory images, so the 1.29 MB active data segment is copied at every instantiation (0.78 ms → 2.17 ms), eating most of the enumeration win (finding 24). Instance granularity K>1 remains diff --git a/expected/verify-deltic-fixture-fold.txt b/expected/verify-polyengine-fixture-fold.txt similarity index 100% rename from expected/verify-deltic-fixture-fold.txt rename to expected/verify-polyengine-fixture-fold.txt diff --git a/expected/verify-deltic-fixture.jsonl b/expected/verify-polyengine-fixture.jsonl similarity index 87% rename from expected/verify-deltic-fixture.jsonl rename to expected/verify-polyengine-fixture.jsonl index fa8ef96..7794cd5 100644 --- a/expected/verify-deltic-fixture.jsonl +++ b/expected/verify-polyengine-fixture.jsonl @@ -1,4 +1,4 @@ -{"component-test-results":"0.1","target":"deltic/deno","suite":{"name":"fixture_suite","artifact-sha256":""},"run":{"segment":0,"scheduling":"tags"}} +{"component-test-results":"0.1","target":"polyengine/deno","suite":{"name":"fixture_suite","artifact-sha256":""},"run":{"segment":0,"scheduling":"tags"}} {"case":"fixture/trap/before","status":"pass","provenance":"returned","diagnostics-complete":true,"diagnostics":["before the storm"]} {"case":"fixture/trap/boom","status":"fail","provenance":"trap","detail":"trap: guest trapped: unreachable","diagnostics-complete":false,"diagnostics":["about to trap"]} {"case":"fixture/trap/after","status":"pass","provenance":"returned","diagnostics-complete":true,"diagnostics":["still alive in a fresh instance"]} diff --git a/expected/verify-deltic-sample.jsonl b/expected/verify-polyengine-sample.jsonl similarity index 80% rename from expected/verify-deltic-sample.jsonl rename to expected/verify-polyengine-sample.jsonl index d17d205..0083bac 100644 --- a/expected/verify-deltic-sample.jsonl +++ b/expected/verify-polyengine-sample.jsonl @@ -1,4 +1,4 @@ -{"component-test-results":"0.1","target":"deltic/deno","suite":{"name":"sample_suite","artifact-sha256":""},"run":{"segment":0,"scheduling":"tags"}} +{"component-test-results":"0.1","target":"polyengine/deno","suite":{"name":"sample_suite","artifact-sha256":""},"run":{"segment":0,"scheduling":"tags"}} {"case":"sample/math/add","status":"pass","provenance":"returned","diagnostics-complete":true,"diagnostics":["computing 2 + 2","got 4"]} {"case":"sample/math/mul","status":"fail","provenance":"returned","detail":"6 * 9: expected 42, got 54","diagnostics-complete":true,"diagnostics":["computing 6 * 9","got 54, expecting the ultimate answer"]} {"case":"sample/token/attest","status":"skipped","provenance":"returned","detail":"token unavailable at run time; asserted attestation fails cleanly (no hang, no partial attestation)","diagnostics-complete":true,"diagnostics":["probing for hardware token","token unavailable; asserting clean error"]} diff --git a/js/deno.json b/js/deno.json index 1f89a75..93cd8e0 100644 --- a/js/deno.json +++ b/js/deno.json @@ -1,8 +1,8 @@ { "name": "@polymorph/test", - "version": "0.1.1", + "version": "0.2.0", "license": "Apache-2.0", - "//": "The polymorph:test stack's JS runner core on JSR — the one consumable JS surface (the repo-root npm-git facade is retired; this export map is the only one). Plain JS with relative and node: imports only; the browser-safe pieces (harness, context, imports, the workers) load in browsers unchanged, and the node: importers (node-runner, browser-driver) are Node/Deno-side drivers. The publish include-list IS the package: everything else under js/ is repo tooling (the deltic runner leg, selftests, the viewer app).", + "//": "The polymorph:test stack's JS runner core on JSR — the one consumable JS surface (the repo-root npm-git facade is retired; this export map is the only one). Plain JS with relative and node: imports only; the browser-safe pieces (harness, context, imports, the workers) load in browsers unchanged, and the node: importers (node-runner, browser-driver) are Node/Deno-side drivers. The publish include-list IS the package: everything else under js/ is repo tooling (the polyengine runner leg, selftests, the viewer app).", "exports": { "./harness": "./viewer/harness.mjs", "./context": "./viewer/context.js", @@ -11,9 +11,9 @@ "./page-runner": "./viewer/page-runner.mjs", "./node-runner": "./node-runner.mjs", "./browser-driver": "./browser-driver.mjs", - "./deltic-worker": "./runner-deltic/browser-worker.mjs", - "./deltic-engine": "./runner-deltic/engine.mjs", - "./deltic-worker-main": "./runner-deltic/worker-main.mjs" + "./polyengine-worker": "./runner-polyengine/browser-worker.mjs", + "./polyengine-engine": "./runner-polyengine/engine.mjs", + "./polyengine-worker-main": "./runner-polyengine/worker-main.mjs" }, "publish": { "include": [ @@ -25,9 +25,9 @@ "viewer/page-runner.mjs", "node-runner.mjs", "browser-driver.mjs", - "runner-deltic/worker-main.mjs", - "runner-deltic/browser-worker.mjs", - "runner-deltic/engine.mjs" + "runner-polyengine/worker-main.mjs", + "runner-polyengine/browser-worker.mjs", + "runner-polyengine/engine.mjs" ] } } diff --git a/js/runner-deltic/browser-bundle-entry.ts b/js/runner-deltic/browser-bundle-entry.ts deleted file mode 100644 index f9e6930..0000000 --- a/js/runner-deltic/browser-bundle-entry.ts +++ /dev/null @@ -1,18 +0,0 @@ -// The browser-leg bundle entry: one platform-neutral ES module carrying -// the embedder API + Translator + ct-runner glue + wasi shims, bundled -// from the SAME pinned JSR graph as the Deno leg (deno.json + deno.lock, -// --frozen). It replaces the sha-pinned `deltic-embedder.mjs` release -// asset the retired release-asset fetch script downloaded; the surface is -// upstream tools/release-bundle/entry.ts's, verbatim. -// -// deno bundle --config js/runner-deltic/deno.json --frozen \ -// --platform browser -o target/deltic-browser/deltic-embedder.mjs \ -// js/runner-deltic/browser-bundle-entry.ts -// -// (`just deltic-assets` builds it; verify-deltic/viewer-build consume it.) - -export * from "@deltic/runtime/embedder"; -export { Translator } from "@deltic/runtime/shim"; -export * from "@deltic/ct-runner"; -export { wasi } from "@deltic/wasi"; -export type { WasiImports, WasiOptions } from "@deltic/wasi"; diff --git a/js/runner-deltic/deno.lock b/js/runner-deltic/deno.lock deleted file mode 100644 index 961d377..0000000 --- a/js/runner-deltic/deno.lock +++ /dev/null @@ -1,49 +0,0 @@ -{ - "version": "5", - "specifiers": { - "jsr:@deltic/ct-runner@0.2.0": "0.2.0", - "jsr:@deltic/protocol@0.2": "0.2.0", - "jsr:@deltic/runtime@0.2": "0.2.0", - "jsr:@deltic/runtime@0.2.0": "0.2.0", - "jsr:@deltic/translator@0.2.0": "0.2.0", - "jsr:@deltic/wasi@0.2.0": "0.2.0" - }, - "jsr": { - "@deltic/ct-runner@0.2.0": { - "integrity": "810eec021dc07dbc7efe00e0e7df900f557c5b30bd11f077195eeb44bcce81b4", - "dependencies": [ - "jsr:@deltic/runtime@0.2" - ] - }, - "@deltic/protocol@0.2.0": { - "integrity": "028be6a3623c5e910598aa7a199209b85e8931ae484ac7f6638d610ddb0e19fa" - }, - "@deltic/runtime@0.2.0": { - "integrity": "cf8b0bdd9e6bc4488ba78cc91661103bfcbd78f5a5c4ff99132799618a9db4bb", - "dependencies": [ - "jsr:@deltic/protocol" - ] - }, - "@deltic/translator@0.2.0": { - "integrity": "8104b54e2acdccfd75f5ddc941d72b581e7defbbe31c05bbc66598d2df7a34f9", - "dependencies": [ - "jsr:@deltic/runtime@0.2" - ] - }, - "@deltic/wasi@0.2.0": { - "integrity": "82c76d4fda0a1c9238a91f8ebc7fdbac952a03aa06d4a2a820213df2654f5c24", - "dependencies": [ - "jsr:@deltic/protocol", - "jsr:@deltic/runtime@0.2" - ] - } - }, - "workspace": { - "dependencies": [ - "jsr:@deltic/ct-runner@0.2.0", - "jsr:@deltic/runtime@0.2.0", - "jsr:@deltic/translator@0.2.0", - "jsr:@deltic/wasi@0.2.0" - ] - } -} diff --git a/js/runner-deltic/README.md b/js/runner-polyengine/README.md similarity index 63% rename from js/runner-deltic/README.md rename to js/runner-polyengine/README.md index de16893..06ef59b 100644 --- a/js/runner-deltic/README.md +++ b/js/runner-polyengine/README.md @@ -1,32 +1,32 @@ -# js/runner-deltic +# js/runner-polyengine Host-side JS runner for `polymorph:test` suites on Deno via -[deltic](https://github.com/lann/deltic) — a runtime linker, so unlike +[polyengine](https://github.com/polymorph-components/polyengine) — a runtime linker, so unlike the jco leg there is no transpile step, no generated tree, and no engine flag (the contract's async exports run on the callback ABI under stock -Deno). Same runner-is-provider topology as `js/runner-node`: deltic's +Deno). Same runner-is-provider topology as `js/runner-node`: polyengine's `runSuite` supplies `test-context` host-side and mirrors `js/viewer/harness.mjs` case-loop semantics; `wasi()` serves the suites' `wasi:{cli,clocks,io,random,filesystem}` leaves. ```sh cargo build --target wasm32-wasip2 --release -p sample-suite # from repo root -deno run --allow-read=target --config js/runner-deltic/deno.json --frozen \ - js/runner-deltic/runner.ts target/wasm32-wasip2/release/sample_suite.wasm \ +deno run --allow-read=target --config js/runner-polyengine/deno.json --frozen \ + js/runner-polyengine/runner.ts target/wasm32-wasip2/release/sample_suite.wasm \ [--jsonl] ``` No fetch step and no extra permissions: the translator arrives with the -pinned `@deltic/translator` package and loads through the module graph +pinned `@polyengine/translator` package and loads through the module graph (`defaultTranslator()`). `--translator ` remains as a documented escape hatch for an externally-sourced translator build. Human mode reproduces `expected/verify-run-sample.txt` byte-for-byte (shared with the composed-cli and jco legs); `--jsonl` emits canonical -L4 results JSONL (`just verify-deltic` diffs it, normalized, against -`expected/verify-deltic-*.jsonl` and folds it through `component-test +L4 results JSONL (`just verify-polyengine` diffs it, normalized, against +`expected/verify-polyengine-*.jsonl` and folds it through `component-test fold` against the shared sample fold golden). Tag scheduling comes from -the suite's own embedded inventory (deltic#25): the fixture leg runs +the suite's own embedded inventory (polyengine#25): the fixture leg runs `--missing hsm` exactly like the embed leg and schedules `hsm`-marked cases out as `not-applicable`. @@ -37,8 +37,8 @@ cases out as `not-applicable`. `harness.mjs` case loop (striping, freshCases, timeouts, mark scheduling), no transpiled artifacts: the run message carries `{ bundleUrl, translatorUrl, suiteUrl, env?, missing?, only?, shard?, -caseTimeoutMs? }` and the worker loads `deltic-embedder.mjs`, built by -`just deltic-assets` from the pinned JSR graph (one platform-neutral +caseTimeoutMs? }` and the worker loads `polyengine-embedder.mjs`, built by +`just polyengine-assets` from the pinned JSR graph (one platform-neutral ES module: embedder API + Translator + runner glue + wasi shims). It drops into `page-runner.mjs`'s `runSuitesInPage` via its `workerUrl` parameter — page runner and browser driver unchanged. `engine.mjs` is the shared @@ -46,14 +46,14 @@ glue; `selftest.mjs` drives the same engine path under plain `node` (NO `--experimental-wasm-jspi` — the callback ABI needs no engine flag), asserting the documented sample/fixture verdicts, trap containment, tag scheduling, and striping partition equality; it runs -as `verify-deltic`'s last leg. +as `verify-polyengine`'s last leg. Suites that import a SUT host module (`polymorph:websocket`, `polymorph:webcrypto`, …) use `worker-main.mjs` (exported as -`./deltic-worker-main`) instead of the stock worker: the downstream -repo bundles one worker entry — the deltic engine surface, the message +`./polyengine-worker-main`) instead of the stock worker: the downstream +repo bundles one worker entry — the polyengine engine surface, the message loop, and its own host module, resolved through one import map — and -passes `workerMain({ deltic, suiteImports })` its inlined engine and an +passes `workerMain({ polyengine, suiteImports })` its inlined engine and an import-record factory. One bundle means one embedder module instance, which is what keeps `instanceof ComponentException` true across the host-module boundary; workers resolve no import maps, so this is the only sound @@ -62,38 +62,38 @@ bundleUrl-loading defaults. ## Pinning -deltic is consumed from JSR as **exact-pinned releases**: -`@deltic/{runtime,translator,wasi,ct-runner}` release in lockstep +polyengine is consumed from JSR as **exact-pinned releases**: +`@polyengine/{runtime,translator,wasi,ct-runner}` release in lockstep from one upstream commit, and upstream is caret-honest (within a minor line releases stay compatible; breaking changes bump the minor), so a bump within a minor line is routine and a minor bump is a compatibility review. The pin stays exact so the version is reviewable here and one -bump is one diff. Between releases every green deltic `main` commit +bump is one diff. Between releases every green polyengine `main` commit also publishes `-pre.g` prereleases (unordered hash versions — pin exactly) for when a not-yet-released commit is needed. -- `deno.json` — the import map holds the five `jsr:@deltic/...@` - specifiers. `@deltic/runtime/embedder` is mapped because - `@deltic/wasi` imports it by bare specifier. - `minimumDependencyAge` exempts the `@deltic` scope so same-day +- `deno.json` — the import map holds the five `jsr:@polyengine/...@` + specifiers. `@polyengine/runtime/embedder` is mapped because + `@polyengine/wasi` imports it by bare specifier. + `minimumDependencyAge` exempts the `@polyengine` scope so same-day publishes resolve (Deno >= 2.9 for the wildcard exclude). - `deno.lock` — carries JSR package integrity for that graph and is enforced with `--frozen` on every run, check, bundle, and `deno info` invocation. - No sha256 bookkeeping and no release-asset downloads: the browser-leg - assets are built from the same locked graph by `just deltic-assets` - into `target/deltic-browser/` — `deltic-embedder.mjs` bundled from - `browser-bundle-entry.ts`, and `deltic-translator-shim.wasm` copied + assets are built from the same locked graph by `just polyengine-assets` + into `target/polyengine-browser/` — `polyengine-embedder.mjs` bundled from + `browser-bundle-entry.ts`, and `polyengine-translator-shim.wasm` copied out of the lock-pinned module cache (the packaged - `@deltic/translator` asset). The directory is version-free: the lock + `@polyengine/translator` asset). The directory is version-free: the lock owns versioning. -- `just deltic-pin-gate` (a `verify-deltic` prerequisite, so it runs in - CI) asserts one version across every `@deltic` specifier in every +- `just polyengine-pin-gate` (a `verify-polyengine` prerequisite, so it runs in + CI) asserts one version across every `@polyengine` specifier in every `deno.json` and everything the lock resolves — the successor to the retired release-asset fetch script's `assertPinConsistency`. To bump: update the version in `deno.json`'s import map, delete `deno.lock`, re-run `deno install --entrypoint runner.ts browser-bundle-entry.ts` in this directory, and commit the diff; the pin -gate asserts agreement. Regenerate the `expected/verify-deltic-*` +gate asserts agreement. Regenerate the `expected/verify-polyengine-*` goldens only if an explained upstream behavior change moves them. diff --git a/js/runner-deltic/bench-mint.mjs b/js/runner-polyengine/bench-mint.mjs similarity index 81% rename from js/runner-deltic/bench-mint.mjs rename to js/runner-polyengine/bench-mint.mjs index d33ae9c..4891036 100644 --- a/js/runner-deltic/bench-mint.mjs +++ b/js/runner-polyengine/bench-mint.mjs @@ -1,20 +1,20 @@ -// Synthetic handle-mint benchmark for the deltic leg — the runtime-linked +// Synthetic handle-mint benchmark for the polyengine leg — the runtime-linked // sibling of crates/component-test-runner/src/bin/bench-mint.rs, measuring -// the same phases per fresh instance under the pinned deltic embedder on +// the same phases per fresh instance under the pinned polyengine embedder on // plain Node (callback ABI, no engine flags): // -// instantiate deltic.instantiate (runtime link + wasm instantiation) +// instantiate polyengine.instantiate (runtime link + wasm instantiation) // all#1 first all(): guest registry build + mint + lift (N wrappers) // all#2 second all(): mint + lift only (guest registry cached) // name[0] one test-case.name boundary call // run[0] one trivial case execution (borrowed context) // -// No teardown phase: deltic instances are GC-reclaimed, there is no +// No teardown phase: polyengine instances are GC-reclaimed, there is no // dispose surface. Case count rides the BENCH_CASES wasi env import // (see components/bench-suite). // -// node js/runner-deltic/bench-mint.mjs \ -// \ +// node js/runner-polyengine/bench-mint.mjs \ +// \ // [--cases 100,1000,10000] [--instances 10] import { readFileSync } from "node:fs"; @@ -40,17 +40,17 @@ for (let i = 0; i < args.length; i++) { const [bundlePath, translatorPath, suitePath] = positional; if (!suitePath) { console.error( - "usage: node bench-mint.mjs " + + "usage: node bench-mint.mjs " + " [--cases N,N,...] [--instances M]", ); process.exit(2); } -const deltic = await import(pathToFileURL(bundlePath).href); +const polyengine = await import(pathToFileURL(bundlePath).href); const suiteBytes = new Uint8Array(readFileSync(suitePath)); let t = performance.now(); -const translator = await deltic.Translator.create( +const translator = await polyengine.Translator.create( new Uint8Array(readFileSync(translatorPath)), ); const translatorMs = performance.now() - t; @@ -82,14 +82,14 @@ console.log( for (const n of caseCounts) { const imports = { - ...deltic.wasi({ cli: { env: { BENCH_CASES: String(n) } } }), - ...deltic.testContextImportRecord(), + ...polyengine.wasi({ cli: { env: { BENCH_CASES: String(n) } } }), + ...polyengine.testContextImportRecord(), }; const warmup = Math.min(3, instances); const samples = { instantiate: [], all1: [], all2: [], name0: [], run0: [] }; for (let i = 0; i < instances + warmup; i++) { let t = performance.now(); - const inst = await deltic.instantiate(artifacts, imports); + const inst = await polyengine.instantiate(artifacts, imports); const instantiate = performance.now() - t; const tests = inst.exports[TESTS] ?? inst.exports["tests"]; @@ -112,7 +112,7 @@ for (const n of caseCounts) { throw new Error(`unexpected case name '${name}'`); } - const ctx = new deltic.Context(() => {}); + const ctx = new polyengine.Context(() => {}); t = performance.now(); await cases1[0].run(ctx); // resolves = pass; throws = fail/trap const run0 = performance.now() - t; diff --git a/js/runner-polyengine/browser-bundle-entry.ts b/js/runner-polyengine/browser-bundle-entry.ts new file mode 100644 index 0000000..85bd99f --- /dev/null +++ b/js/runner-polyengine/browser-bundle-entry.ts @@ -0,0 +1,18 @@ +// The browser-leg bundle entry: one platform-neutral ES module carrying +// the embedder API + Translator + ct-runner glue + wasi shims, bundled +// from the SAME pinned JSR graph as the Deno leg (deno.json + deno.lock, +// --frozen). It replaces the sha-pinned `polyengine-embedder.mjs` release +// asset the retired release-asset fetch script downloaded; the surface is +// upstream tools/release-bundle/entry.ts's, verbatim. +// +// deno bundle --config js/runner-polyengine/deno.json --frozen \ +// --platform browser -o target/polyengine-browser/polyengine-embedder.mjs \ +// js/runner-polyengine/browser-bundle-entry.ts +// +// (`just polyengine-assets` builds it; verify-polyengine/viewer-build consume it.) + +export * from "@polyengine/runtime/embedder"; +export { Translator } from "@polyengine/runtime/shim"; +export * from "@polyengine/ct-runner"; +export { wasi } from "@polyengine/wasi"; +export type { WasiImports, WasiOptions } from "@polyengine/wasi"; diff --git a/js/runner-deltic/browser-worker.mjs b/js/runner-polyengine/browser-worker.mjs similarity index 70% rename from js/runner-deltic/browser-worker.mjs rename to js/runner-polyengine/browser-worker.mjs index 3d4a7cc..dc87346 100644 --- a/js/runner-deltic/browser-worker.mjs +++ b/js/runner-polyengine/browser-worker.mjs @@ -1,14 +1,14 @@ -// The deltic browser-side shard worker — the runtime-linked sibling of +// The polyengine browser-side shard worker — the runtime-linked sibling of // js/viewer/browser-worker.mjs (same reply protocol, same harness case // loop, no transpiled artifacts). Drop-in for page-runner.mjs's // runSuitesInPage via its workerUrl parameter; suite entries carry this // worker's run message instead of the jco one: // // { -// bundleUrl, // deltic-embedder.mjs, built from the pinned JSR -// // graph by `just deltic-assets` -// translatorUrl, // deltic-translator-shim.wasm, extracted from the -// // same locked graph (@deltic/translator's asset) +// bundleUrl, // polyengine-embedder.mjs, built from the pinned JSR +// // graph by `just polyengine-assets` +// translatorUrl, // polyengine-translator-shim.wasm, extracted from the +// // same locked graph (@polyengine/translator's asset) // suiteUrl, // the suite COMPONENT wasm (no transpile, no cores) // env?, // [name, value] pairs for wasi:cli/environment // missing?, only?, shard?, caseTimeoutMs?, diff --git a/js/runner-deltic/deno.json b/js/runner-polyengine/deno.json similarity index 55% rename from js/runner-deltic/deno.json rename to js/runner-polyengine/deno.json index 03ef764..b204012 100644 --- a/js/runner-deltic/deno.json +++ b/js/runner-polyengine/deno.json @@ -1,16 +1,16 @@ { - // MODULE IDENTITY — deltic is consumed from JSR as exact-pinned + // MODULE IDENTITY — polyengine is consumed from JSR as exact-pinned // releases. Upstream is caret-honest (within a minor line releases stay // compatible; breaking changes bump the minor); the pin stays exact so // the version is reviewable here and one bump is one diff. Between - // releases every green deltic `main` commit also publishes + // releases every green polyengine `main` commit also publishes // `-pre.g` prereleases (unordered hash versions — pin // exactly) for when a not-yet-released commit is needed. All four - // packages must carry the SAME version — `just verify-deltic`'s pin gate - // asserts that repo-wide. + // packages must carry the SAME version — `just verify-polyengine`'s pin + // gate asserts that repo-wide. // - // `@deltic/runtime/embedder` is mapped because `@deltic/wasi` - // imports it by bare specifier. `@deltic/translator` ships the translator + // `@polyengine/runtime/embedder` is mapped because `@polyengine/wasi` + // imports it by bare specifier. `@polyengine/translator` ships the translator // wasm built from the same commit: the Deno leg loads it through the // module graph (`defaultTranslator()`, permission-free) and the browser // leg extracts it from the lock-pinned module cache — no release-asset @@ -21,14 +21,14 @@ // re-run `deno install --entrypoint runner.ts browser-bundle-entry.ts` in // this directory, and commit the diff (see README.md "Pinning"). "imports": { - "@deltic/ct-runner": "jsr:@deltic/ct-runner@0.2.0", - "@deltic/runtime/embedder": "jsr:@deltic/runtime@0.2.0/embedder", - "@deltic/runtime/shim": "jsr:@deltic/runtime@0.2.0/shim", - "@deltic/translator": "jsr:@deltic/translator@0.2.0", - "@deltic/wasi": "jsr:@deltic/wasi@0.2.0" + "@polyengine/ct-runner": "jsr:@polyengine/ct-runner@0.3.0", + "@polyengine/runtime/embedder": "jsr:@polyengine/runtime@0.3.0/embedder", + "@polyengine/runtime/shim": "jsr:@polyengine/runtime@0.3.0/shim", + "@polyengine/translator": "jsr:@polyengine/translator@0.3.0", + "@polyengine/wasi": "jsr:@polyengine/wasi@0.3.0" }, // Deno's supply-chain minimum-dependency-age gate (24h default) applies - // even to exact prerelease pins; deltic publishes per commit, so the + // even to exact prerelease pins; polyengine publishes per commit, so the // scope is excluded (wildcard excludes need Deno >= 2.9; CI pins 2.9.5). - "minimumDependencyAge": { "age": "P1D", "exclude": ["jsr:@deltic/*"] } + "minimumDependencyAge": { "age": "P1D", "exclude": ["jsr:@polyengine/*"] } } diff --git a/js/runner-polyengine/deno.lock b/js/runner-polyengine/deno.lock new file mode 100644 index 0000000..b976134 --- /dev/null +++ b/js/runner-polyengine/deno.lock @@ -0,0 +1,49 @@ +{ + "version": "5", + "specifiers": { + "jsr:@polyengine/ct-runner@0.3.0": "0.3.0", + "jsr:@polyengine/protocol@0.1": "0.1.0", + "jsr:@polyengine/runtime@0.3": "0.3.0", + "jsr:@polyengine/runtime@0.3.0": "0.3.0", + "jsr:@polyengine/translator@0.3.0": "0.3.0", + "jsr:@polyengine/wasi@0.3.0": "0.3.0" + }, + "jsr": { + "@polyengine/ct-runner@0.3.0": { + "integrity": "d58720da80bf29cb6a975e4750a53bbe9b75ab6e3bde1340299ed69726702174", + "dependencies": [ + "jsr:@polyengine/runtime@0.3" + ] + }, + "@polyengine/protocol@0.1.0": { + "integrity": "0c97f34166f22ba55e7b084148df96e47aebe47cd9dd13930057759c9161bb1c" + }, + "@polyengine/runtime@0.3.0": { + "integrity": "97d7648c104dd0f08b4d10e1ed0117ab0cb5243db68c139f1f3df25755ed4e60", + "dependencies": [ + "jsr:@polyengine/protocol" + ] + }, + "@polyengine/translator@0.3.0": { + "integrity": "1d9fcd09d360850bc08927ed1cf8124d50a0fed09ed8c80f354a6d3aedfcad25", + "dependencies": [ + "jsr:@polyengine/runtime@0.3" + ] + }, + "@polyengine/wasi@0.3.0": { + "integrity": "991adfdd39f795f94bba91a523322b88d45ff42800669b5b472356676e3c97e7", + "dependencies": [ + "jsr:@polyengine/protocol", + "jsr:@polyengine/runtime@0.3" + ] + } + }, + "workspace": { + "dependencies": [ + "jsr:@polyengine/ct-runner@0.3.0", + "jsr:@polyengine/runtime@0.3.0", + "jsr:@polyengine/translator@0.3.0", + "jsr:@polyengine/wasi@0.3.0" + ] + } +} diff --git a/js/runner-deltic/engine.mjs b/js/runner-polyengine/engine.mjs similarity index 63% rename from js/runner-deltic/engine.mjs rename to js/runner-polyengine/engine.mjs index cf8c1fa..89bef90 100644 --- a/js/runner-deltic/engine.mjs +++ b/js/runner-polyengine/engine.mjs @@ -1,21 +1,21 @@ -// Shared engine glue for the deltic legs (browser shard worker + Node -// selftest): load the repo-built deltic embedder bundle (`just -// deltic-assets`, from the pinned JSR graph), translate the suite +// Shared engine glue for the polyengine legs (browser shard worker + Node +// selftest): load the repo-built polyengine embedder bundle (`just +// polyengine-assets`, from the pinned JSR graph), translate the suite // component, and hand back exactly what harness.mjs `runCases` needs. -// deltic is a runtime linker — the suite arrives as the COMPONENT wasm +// polyengine is a runtime linker — the suite arrives as the COMPONENT wasm // (no transpiled module, no core files, no imports module; WASI comes // from the bundle's wasi(), test-context from its ct-runner glue). // // The Context handed to runCases MUST be the bundle's own Context class: // `testContextImportRecord()` registers that exact class as the -// `polymorph:test/test-context` host resource, and deltic lowers borrows +// `polymorph:test/test-context` host resource, and polyengine lowers borrows // of it by class identity. /** * @param {object} input - * @param {object|string} input.bundle The deltic embedder module, or a URL + * @param {object|string} input.bundle The polyengine embedder module, or a URL * string to import it from (workers pass the URL; Node imports first). - * @param {Uint8Array} input.translatorBytes deltic-translator-shim.wasm. + * @param {Uint8Array} input.translatorBytes polyengine-translator-shim.wasm. * @param {Uint8Array} input.suiteBytes The suite COMPONENT wasm. * @param {[string, string][]} [input.env] wasi:cli environment pairs. * @param {object} [input.hostImports] SUT host-import record fragments @@ -27,19 +27,19 @@ export async function loadSuite( { bundle, translatorBytes, suiteBytes, env = [], hostImports = {} }, ) { - const deltic = typeof bundle === "string" ? await import(bundle) : bundle; - const translator = await deltic.Translator.create(translatorBytes); + const polyengine = typeof bundle === "string" ? await import(bundle) : bundle; + const translator = await polyengine.Translator.create(translatorBytes); const { plan, adapters } = translator.translate(suiteBytes); const artifacts = { plan, componentBytes: suiteBytes, adapters }; const imports = { - ...deltic.wasi({ cli: { env: Object.fromEntries(env) } }), - ...deltic.testContextImportRecord(), + ...polyengine.wasi({ cli: { env: Object.fromEntries(env) } }), + ...polyengine.testContextImportRecord(), ...hostImports, }; const newTests = async () => { - const inst = await deltic.instantiate(artifacts, imports); + const inst = await polyengine.instantiate(artifacts, imports); const tests = inst.exports["polymorph:test/tests@0.1.0"] ?? inst.exports["tests"]; if (tests === undefined) { throw new Error( @@ -49,15 +49,15 @@ export async function loadSuite( return tests; }; - // The suite's own L0 inventory (deltic reads it from the component, + // The suite's own L0 inventory (polyengine reads it from the component, // nested core modules included — the same records harness.mjs's // inventoryLookup reads from transpiled cores). A suite without records // yields an always-undefined lookup, and runCases throws inventory // drift on the first case — same posture as the jco worker. - const inventory = deltic.loadTagsInventory(suiteBytes); + const inventory = polyengine.loadTagsInventory(suiteBytes); const tagsOf = inventory === null ? () => undefined - : (name) => deltic.tagsOf(inventory, name); + : (name) => polyengine.tagsOf(inventory, name); - return { newTests, Context: deltic.Context, tagsOf }; + return { newTests, Context: polyengine.Context, tagsOf }; } diff --git a/js/runner-deltic/runner.ts b/js/runner-polyengine/runner.ts similarity index 86% rename from js/runner-deltic/runner.ts rename to js/runner-polyengine/runner.ts index 8c60dd4..6e5e603 100644 --- a/js/runner-deltic/runner.ts +++ b/js/runner-polyengine/runner.ts @@ -1,4 +1,4 @@ -// The deltic runner leg (Path 3b): drive an L1 suite under deltic — a +// The polyengine runner leg (Path 3b): drive an L1 suite under polyengine — a // runtime linker, so there is NO transpile step and NO engine flag; the // contract's async exports run on the callback ABI under stock Deno. // @@ -6,25 +6,25 @@ // provider: the host supplies test-context) and, in human mode, its exact // output format — `expected/verify-run-sample.txt` is shared verbatim with // the composed-cli and jco-node legs. With --jsonl it emits canonical L4 -// results JSONL instead (deltic's runSuite mirrors js/viewer/harness.mjs +// results JSONL instead (polyengine's runSuite mirrors js/viewer/harness.mjs // semantics; schema authority: crates/component-test-results). // -// deno run --allow-read=target --config js/runner-deltic/deno.json \ -// --frozen js/runner-deltic/runner.ts \ +// deno run --allow-read=target --config js/runner-polyengine/deno.json \ +// --frozen js/runner-polyengine/runner.ts \ // [--translator ] [--jsonl] [--target NAME] // -// The translator comes from the pinned @deltic/translator package through +// The translator comes from the pinned @polyengine/translator package through // the module graph (permission-free: no net grant, no read grant for the // asset). `--translator` stays as a documented escape hatch for driving an // externally-sourced translator wasm; absent, the packaged one is used. // -// The deltic pin lives in deno.json + deno.lock (which see, and README.md +// The polyengine pin lives in deno.json + deno.lock (which see, and README.md // for the bump procedure). -import { Translator } from "@deltic/runtime/shim"; -import { defaultTranslator } from "@deltic/translator"; -import { runSuite } from "@deltic/ct-runner"; -import { wasi } from "@deltic/wasi"; +import { Translator } from "@polyengine/runtime/shim"; +import { defaultTranslator } from "@polyengine/translator"; +import { runSuite } from "@polyengine/ct-runner"; +import { wasi } from "@polyengine/wasi"; interface Cli { suitePath: string; @@ -38,7 +38,7 @@ function parseArgs(argv: string[]): Cli { const positional: string[] = []; let translator: string | undefined; let jsonl = false; - let target = "deltic/deno"; + let target = "polyengine/deno"; let missing: string[] | undefined; for (let i = 0; i < argv.length; i++) { const a = argv[i]; @@ -94,7 +94,7 @@ function renderHuman(e: CaseEvent): string { lines.push(`test ${e.case}: SKIP: ${e.detail ?? ""}`); break; case "not-applicable": - // Tag scheduling (deltic ct-runner #25): the case was scheduled out + // Tag scheduling (polyengine ct-runner #25): the case was scheduled out // for this target, not executed. No shared human golden constrains // this line (the composed/jco legs never see tags). lines.push(`test ${e.case}: N/A: ${e.detail ?? ""}`); diff --git a/js/runner-deltic/selftest.mjs b/js/runner-polyengine/selftest.mjs similarity index 86% rename from js/runner-deltic/selftest.mjs rename to js/runner-polyengine/selftest.mjs index e3a345b..e2bbf9a 100644 --- a/js/runner-deltic/selftest.mjs +++ b/js/runner-polyengine/selftest.mjs @@ -1,12 +1,12 @@ -// The deltic engines' drift gate (verify-deltic's selftest leg) — the +// The polyengine engines' drift gate (verify-polyengine's selftest leg) — the // runtime-linked sibling of js/viewer/selftest.mjs, running the SAME -// harness.mjs case loop over deltic-instantiated suites. Plain `node`, -// NO --experimental-wasm-jspi: deltic's callback-ABI path needs no +// harness.mjs case loop over polyengine-instantiated suites. Plain `node`, +// NO --experimental-wasm-jspi: polyengine's callback-ABI path needs no // engine flag, which is the browser-leg premise this gate pins on every -// PR (the real-browser proof lives in deltic's own post-merge lanes). +// PR (the real-browser proof lives in polyengine's own post-merge lanes). // -// node js/runner-deltic/selftest.mjs \ -// +// node js/runner-polyengine/selftest.mjs \ +// import { strict as assert } from "node:assert"; import { readFileSync } from "node:fs"; @@ -17,7 +17,7 @@ import { loadSuite } from "./engine.mjs"; const [bundlePath, translatorPath, samplePath, fixturePath] = process.argv.slice(2); if (!fixturePath) { console.error( - "usage: node js/runner-deltic/selftest.mjs " + + "usage: node js/runner-polyengine/selftest.mjs " + " ", ); process.exit(2); @@ -71,7 +71,7 @@ async function run(engine, { missing = [], only, shard } = {}) { console.log("selftest: sample verdicts ok (callback ABI, no JSPI flag)"); } -// --- fixture: trap containment + tag scheduling through the deltic engine ----- +// --- fixture: trap containment + tag scheduling through the polyengine engine ----- { const engine = await suiteOf(fixturePath); const { counts, events } = await run(engine, { missing: ["hsm"] }); @@ -129,7 +129,7 @@ async function run(engine, { missing = [], only, shard } = {}) { ); console.log("selftest: only -> deselected census ok"); - // Striping partition equality (harness semantics over the deltic engine): + // Striping partition equality (harness semantics over the polyengine engine): // two shards merge to the full counts, disjoint cases, full union. const s0 = await run(engine, { missing: ["hsm"], shard: { index: 0, count: 2 } }); const s1 = await run(engine, { missing: ["hsm"], shard: { index: 1, count: 2 } }); @@ -141,4 +141,4 @@ async function run(engine, { missing = [], only, shard } = {}) { console.log("selftest: striping partition equality ok"); } -console.log("selftest: deltic engines ok"); +console.log("selftest: polyengine engines ok"); diff --git a/js/runner-deltic/worker-main.mjs b/js/runner-polyengine/worker-main.mjs similarity index 80% rename from js/runner-deltic/worker-main.mjs rename to js/runner-polyengine/worker-main.mjs index cf89f10..88eee87 100644 --- a/js/runner-deltic/worker-main.mjs +++ b/js/runner-polyengine/worker-main.mjs @@ -1,29 +1,29 @@ -// The deltic shard worker's message loop, shared by the stock worker +// The polyengine shard worker's message loop, shared by the stock worker // (./browser-worker.mjs) and downstream repos' bundled workers. // // A downstream conformance suite usually imports a SUT host module // (`polymorph:websocket/connections`, `polymorph:webcrypto/*`, …) that // the stock worker cannot supply: workers resolve no import maps, so the -// host module and the deltic engine must arrive in ONE bundle or the +// host module and the polyengine engine must arrive in ONE bundle or the // embedder module loads twice and `instanceof ComponentException` stops // holding across the boundary. The downstream pattern is a bundled worker // entry: // // // worker-entry.ts — deno bundle --platform browser -// import * as deltic from "./browser-bundle-entry.ts"; // jsr:@deltic/* -// import { workerMain } from "@polymorph/component-test-js/deltic-worker-main"; -// import { configure, websocketImports } from "../../js/deltic/websocket.ts"; +// import * as polyengine from "./browser-bundle-entry.ts"; // jsr:@polyengine/* +// import { workerMain } from "@polymorph/component-test-js/polyengine-worker-main"; +// import { configure, websocketImports } from "../../js/polyengine/websocket.ts"; // workerMain({ -// deltic, +// polyengine, // suiteImports: ({ env }) => { // configure({ /* the leg's bounds */ }); // return websocketImports(); // }, // }); // -// The bundler resolves every `@deltic/runtime/embedder` in the graph to +// The bundler resolves every `@polyengine/runtime/embedder` in the graph to // one module, so identity holds by construction; the run message's -// `bundleUrl` is unused when `deltic` is passed (the engine is inlined). +// `bundleUrl` is unused when `polyengine` is passed (the engine is inlined). // // Run message and reply protocol are ./browser-worker.mjs's, unchanged: // { bundleUrl?, translatorUrl, suiteUrl, env?, missing?, only?, shard?, @@ -45,18 +45,18 @@ async function fetchBytes(url) { * Install the shard worker's message handler. * * @param {object} [options] - * @param {object} [options.deltic] The deltic engine namespace (the + * @param {object} [options.polyengine] The polyengine engine namespace (the * embedder bundle's exports), already imported — bundled workers pass * their inlined copy. Absent, each run message's `bundleUrl` is * dynamically imported (the stock worker's behavior). - * @param {(input: { deltic: object, env: [string, string][] }) + * @param {(input: { polyengine: object, env: [string, string][] }) * => object | Promise} [options.suiteImports] Builds the * SUT host-import record for one suite instance; merged over the * engine's own wasi + test-context imports. Called once per run * message (instances share module-level host state exactly as the * repos' Deno legs do). */ -export function workerMain({ deltic, suiteImports } = {}) { +export function workerMain({ polyengine, suiteImports } = {}) { self.onunhandledrejection = (event) => { event.preventDefault?.(); self.postMessage({ kind: "error", error: String(event.reason?.stack ?? event.reason) }); @@ -79,10 +79,10 @@ export function workerMain({ deltic, suiteImports } = {}) { fetchBytes(translatorUrl), fetchBytes(suiteUrl), ]); - const bundle = deltic ?? bundleUrl; + const bundle = polyengine ?? bundleUrl; const resolved = typeof bundle === "string" ? await import(bundle) : bundle; const hostImports = suiteImports - ? await suiteImports({ deltic: resolved, env }) + ? await suiteImports({ polyengine: resolved, env }) : undefined; const { newTests, Context, tagsOf } = await loadSuite({ bundle: resolved, diff --git a/js/viewer/README.md b/js/viewer/README.md index f7cbfc6..0cd3e0d 100644 --- a/js/viewer/README.md +++ b/js/viewer/README.md @@ -15,7 +15,7 @@ code compiled to a component, so the page's verdicts are `component-test aggregate`'s verdicts by construction. **Live run**: point at any suite's component wasm (no transpile — -deltic links it at run time), choose the missing-features declaration +polyengine links it at run time), choose the missing-features declaration and a worker count, and the suite runs in a Web Worker pool — striped `index % workers` like every other runner, one suite instance per worker — streaming rows into the page. A @@ -45,16 +45,16 @@ deliberate trap showing as tracked expected-fail debt on both targets. the Node selftest; the gating jco adapters (#5) must use this same module — the gate and the page must not drift. - `context.js` — the host-implemented `test-context` provider. -- Live-run shards run in `../runner-deltic/browser-worker.mjs` (the - shared deltic worker; module workers cannot see import maps, so the +- Live-run shards run in `../runner-polyengine/browser-worker.mjs` (the + shared polyengine worker; module workers cannot see import maps, so the run message carries asset URLs). - `app.mjs`, `index.html`, `viewer.css` — the page. - `selftest.mjs` — the drift gate `just verify-viewer` runs: the wasm aggregate must reproduce the CLI's verdicts over the fixture - pipeline; the suite-execution legs live in verify-deltic's selftest to the + pipeline; the suite-execution legs live in verify-polyengine's selftest to the documented verdicts, including striping partition equality. -- `generated/`, `suite/`, `deltic/` — the aggregate component, demo - suite components, and pinned deltic assets (gitignored; +- `generated/`, `suite/`, `polyengine/` — the aggregate component, demo + suite components, and pinned polyengine assets (gitignored; `just viewer-build` populates them). The page is thin glue over the two verified engines; browser-only diff --git a/js/viewer/app.mjs b/js/viewer/app.mjs index 1a1e49b..c117449 100644 --- a/js/viewer/app.mjs +++ b/js/viewer/app.mjs @@ -11,7 +11,7 @@ // stream into a live table, and the finished run downloads as // results-JSONL or feeds straight into the Results pane. import { envelope, mergeCounts, workerCount } from "./harness.mjs"; -import { aggregateEngine, bundleUrl, translatorUrl } from "./deltic.mjs"; +import { aggregateEngine, bundleUrl, translatorUrl } from "./polyengine.mjs"; const $ = (id) => document.getElementById(id); @@ -424,7 +424,7 @@ $("btn-run").onclick = async () => { Array.from({ length: jobs }, (_, index) => new Promise((resolve, reject) => { const worker = new Worker( - new URL("../runner-deltic/browser-worker.mjs", import.meta.url), + new URL("../runner-polyengine/browser-worker.mjs", import.meta.url), { type: "module" }, ); worker.onmessage = ({ data }) => { diff --git a/js/viewer/harness.mjs b/js/viewer/harness.mjs index 5244017..ac55e6c 100644 --- a/js/viewer/harness.mjs +++ b/js/viewer/harness.mjs @@ -133,7 +133,7 @@ export function envelope(target, suite) { * `freshCases` (a timed-out shared instance may be wedged * mid-suspension, poisoning every later case). * - * `name()` may be Promise-shaped: deltic's embedder exports are + * `name()` may be Promise-shaped: polyengine's embedder exports are * uniformly async (contracts/embedder-api.md "Functions and async"), * while jco sync-lifted exports return plain values; awaiting a plain * value is a no-op, so this loop is host-agnostic. @@ -204,7 +204,7 @@ export async function runCases({ // rule), so the case sits at the same census index in the fresh // list — O(1) instead of a name() scan per case, which at 10^4 // scale costs ~N/2 boundary calls per case and dominates the - // whole loop (~130ms/case under deltic). One name() call + // whole loop (~130ms/case under polyengine). One name() call // verifies; disagreement is enumeration drift — unsound run, // not a failing case. const fresh = await freshCases(); @@ -249,7 +249,7 @@ export async function runCases({ } } catch (e) { const payload = e?.payload ?? e; - // Shape-compatible read: the deltic runner lifts err-result values as + // Shape-compatible read: the polyengine runner lifts err-result values as // A10 `{ kind, value }`; the jco-era node runner still emits the // pre-A10 `{ tag, val }` — this harness is shared by both, so read // either spelling rather than picking one. diff --git a/js/viewer/deltic.mjs b/js/viewer/polyengine.mjs similarity index 65% rename from js/viewer/deltic.mjs rename to js/viewer/polyengine.mjs index bf89c78..ea4ff81 100644 --- a/js/viewer/deltic.mjs +++ b/js/viewer/polyengine.mjs @@ -1,11 +1,11 @@ // Runtime-linked viewer engines (the jco replacement's Phase 4): the -// deltic browser assets (repo-built from the pinned JSR graph — see -// js/runner-deltic/README.md) are deployed beside the viewer by +// polyengine browser assets (repo-built from the pinned JSR graph — see +// js/runner-polyengine/README.md) are deployed beside the viewer by // `just viewer-build` (locally and on Pages alike — same relative // layout), and the aggregation component is instantiated at first use. // -// ./deltic/deltic-embedder.mjs one platform-neutral ES module -// ./deltic/deltic-translator-shim.wasm the runtime linker's translator +// ./polyengine/polyengine-embedder.mjs one platform-neutral ES module +// ./polyengine/polyengine-translator-shim.wasm the runtime linker's translator // ./generated/viewer-aggregate.wasm the aggregation COMPONENT // (the gate's own Rust — no // transpile step anymore) @@ -13,9 +13,9 @@ // Browser-only (fetch-based); js/viewer/selftest.mjs builds the same // engine under node with fs reads. -const ASSETS = new URL("./deltic/", import.meta.url); -export const bundleUrl = new URL("deltic-embedder.mjs", ASSETS).href; -export const translatorUrl = new URL("deltic-translator-shim.wasm", ASSETS).href; +const ASSETS = new URL("./polyengine/", import.meta.url); +export const bundleUrl = new URL("polyengine-embedder.mjs", ASSETS).href; +export const translatorUrl = new URL("polyengine-translator-shim.wasm", ASSETS).href; async function fetchBytes(url) { const res = await fetch(url); @@ -27,7 +27,7 @@ let enginePromise; /** * The aggregation engine: `(lock, manifest, [[target, jsonl], …]) -> - * Promise`. Instantiated once, lazily — deltic translates + * Promise`. Instantiated once, lazily — polyengine translates * the component in-page (~ms; no generated JS anywhere, CSP baseline * `wasm-unsafe-eval` only). A guest-side `result::err` surfaces as a * thrown error with `.payload` carrying the message, exactly like the @@ -35,16 +35,16 @@ let enginePromise; */ export function aggregateEngine() { enginePromise ??= (async () => { - const deltic = await import(bundleUrl); + const polyengine = await import(bundleUrl); const [translatorBytes, componentBytes] = await Promise.all([ fetchBytes(translatorUrl), fetchBytes(new URL("./generated/viewer-aggregate.wasm", import.meta.url)), ]); - const translator = await deltic.Translator.create(translatorBytes); + const translator = await polyengine.Translator.create(translatorBytes); const { plan, adapters } = translator.translate(componentBytes); - const inst = await deltic.instantiate( + const inst = await polyengine.instantiate( { plan, componentBytes, adapters }, - deltic.wasi(), + polyengine.wasi(), ); return inst.exports.run; })(); diff --git a/js/viewer/selftest.mjs b/js/viewer/selftest.mjs index c2817c4..1c0ae5c 100644 --- a/js/viewer/selftest.mjs +++ b/js/viewer/selftest.mjs @@ -2,19 +2,19 @@ // (`just verify-viewer`): // // 1. Aggregation: the wasm-compiled viewer-aggregate COMPONENT, run -// under deltic exactly as the page runs it (js/viewer/deltic.mjs), +// under polyengine exactly as the page runs it (js/viewer/polyengine.mjs), // must reproduce the CLI gate's verdicts over the fixture pipeline // (same summary accounting, same expected-fail assessments). // 2. Gating-adapter options of the shared harness loop (#50): // freshCases + caseTimeoutMs over synthetic cases. // // The suite-execution half of the old selftest lives in -// js/runner-deltic/selftest.mjs now — same harness.mjs loop, same -// suites, deltic engine (verify-deltic's last leg). Plain `node`: +// js/runner-polyengine/selftest.mjs now — same harness.mjs loop, same +// suites, polyengine engine (verify-polyengine's last leg). Plain `node`: // nothing here needs --experimental-wasm-jspi. // // Usage: node selftest.mjs -// +// // import { readFileSync } from "node:fs"; import { pathToFileURL } from "node:url"; @@ -30,21 +30,21 @@ const fail = (msg) => { if (!aggregatePath) { fail( "usage: selftest.mjs " + - " ", + " ", ); } // --- 1. Aggregation parity with the gate --------------------------- -// The same instantiation deltic.mjs performs in-page, with fs reads. -const deltic = await import(pathToFileURL(bundlePath).href); -const translator = await deltic.Translator.create( +// The same instantiation polyengine.mjs performs in-page, with fs reads. +const polyengine = await import(pathToFileURL(bundlePath).href); +const translator = await polyengine.Translator.create( new Uint8Array(readFileSync(translatorPath)), ); const componentBytes = new Uint8Array(readFileSync(aggregatePath)); const { plan, adapters } = translator.translate(componentBytes); -const inst = await deltic.instantiate( +const inst = await polyengine.instantiate( { plan, componentBytes, adapters }, - deltic.wasi(), + polyengine.wasi(), ); const aggregate = inst.exports.run; @@ -131,11 +131,11 @@ expect( fail("vanished case on re-enumeration did not throw"); } // mergeCounts stays exercised here (the striped suite legs live in - // js/runner-deltic/selftest.mjs). + // js/runner-polyengine/selftest.mjs). const twice = mergeCounts([counts, counts]); if (twice.total !== 6) fail(`mergeCounts: ${JSON.stringify(twice)}`); } console.log( - `viewer selftest ok: aggregate ${JSON.stringify(doc.summary)} (deltic-linked, no JSPI flag)`, + `viewer selftest ok: aggregate ${JSON.stringify(doc.summary)} (polyengine-linked, no JSPI flag)`, ); diff --git a/justfile b/justfile index 465b3d3..7a4d32a 100644 --- a/justfile +++ b/justfile @@ -19,7 +19,7 @@ default: ci: (gha::host-checks) (gha::verify) # Everything: host tests, component builds, all verification paths. -all: build test test-wasm lock-check verify-embed verify-compose verify-cli verify-deltic verify-pipeline verify-aggregate verify-viewer verify-imports verify-emit +all: build test test-wasm lock-check verify-embed verify-compose verify-cli verify-polyengine verify-pipeline verify-aggregate verify-viewer verify-imports verify-emit # The fast pre-commit checks: formatting, clippy, host tests, WIT # validation. The CI job of the same name runs the identical set # through gha::host-checks. @@ -130,74 +130,75 @@ verify-cli: build diff -u expected/verify-run-sample.txt <(printf '%s\n' "$out") echo "verify-cli: output matches expected/ (compose-runner, run, wizen)" -# The one-version-everywhere gate for the deltic pin (successor to the -# retired fetch script's `assertPinConsistency`): every jsr:@deltic/* -# specifier in every deno.json, and every @deltic package the lock -# resolves, must name the SAME prerelease — one version names one +# The one-version-everywhere gate for the polyengine pin (successor to the +# retired fetch script's `assertPinConsistency`): every jsr:@polyengine/* +# specifier in every deno.json, and every @polyengine package the lock +# resolves, must name the SAME version — one version names one # upstream commit, and the browser assets are built from that same graph. # -# CONTRACT: as of deltic pre-b297834 (A10), @deltic/protocol ships as a +# CONTRACT: as of upstream pre-b297834 (A10; cut under the engine's former +# name, deltic), @polyengine/protocol ships as a # stable, independently-versioned package (0.1.0, no per-commit prerelease -# hash) that @deltic/{runtime,wasi} depend on transitively — it is not -# named by any jsr:@deltic/*@ specifier in deno.json and isn't part +# hash) that @polyengine/{runtime,wasi} depend on transitively — it is not +# named by any jsr:@polyengine/*@ specifier in deno.json and isn't part # of the "one version names one commit" pin this gate polices. Excluded by -# name rather than by pattern, so drift in any *other* @deltic package +# name rather than by pattern, so drift in any *other* @polyengine package # still trips the gate. See contracts/embedder-api.md "Migration notes" -# (upstream, pre-b297834) and js/runner-deltic/deno.lock. -deltic-pin-gate: +# (upstream, pre-b297834) and js/runner-polyengine/deno.lock. +polyengine-pin-gate: #!/usr/bin/env bash set -euo pipefail - configs=(js/runner-deltic/deno.json) - v=$(grep -ho 'jsr:@deltic/[a-z-]*@[^/"]*' "${configs[@]}" | sed 's/.*@//' | sort -u) - test -n "$v" || { echo "deltic pin gate: no jsr:@deltic specifiers found" >&2; exit 1; } - [ "$(printf '%s\n' "$v" | wc -l)" = 1 ] || { echo "deltic pin drift: $v" >&2; exit 1; } - python3 - "$v" js/runner-deltic/deno.lock <<'PY' + configs=(js/runner-polyengine/deno.json) + v=$(grep -ho 'jsr:@polyengine/[a-z-]*@[^/"]*' "${configs[@]}" | sed 's/.*@//' | sort -u) + test -n "$v" || { echo "polyengine pin gate: no jsr:@polyengine specifiers found" >&2; exit 1; } + [ "$(printf '%s\n' "$v" | wc -l)" = 1 ] || { echo "polyengine pin drift: $v" >&2; exit 1; } + python3 - "$v" js/runner-polyengine/deno.lock <<'PY' import json, sys want, lock = sys.argv[1], json.load(open(sys.argv[2])) - stable = {"@deltic/protocol"} # see CONTRACT note above deltic-pin-gate + stable = {"@polyengine/protocol"} # see CONTRACT note above polyengine-pin-gate def pkg_name(k): - # k looks like "jsr:@deltic/foo@1.2.3" or "@deltic/foo@1.2.3" + # k looks like "jsr:@polyengine/foo@1.2.3" or "@polyengine/foo@1.2.3" rest = k[len("jsr:"):] if k.startswith("jsr:") else k return rest.rsplit("@", 1)[0] bad = {k: r for k, r in lock.get("specifiers", {}).items() - if "@deltic/" in k and r != want and pkg_name(k) not in stable} - bad.update({k: k for k in lock.get("jsr", {}) if k.startswith("@deltic/") + if "@polyengine/" in k and r != want and pkg_name(k) not in stable} + bad.update({k: k for k in lock.get("jsr", {}) if k.startswith("@polyengine/") and not k.endswith("@" + want) and pkg_name(k) not in stable}) if bad: - sys.exit(f"deltic lock drift (want {want}): {sorted(bad)}") + sys.exit(f"polyengine lock drift (want {want}): {sorted(bad)}") PY - echo "deltic pin gate: all @deltic packages pinned to $v (protocol excluded, stable)" + echo "polyengine pin gate: all @polyengine packages pinned to $v (protocol excluded, stable)" -# The deltic browser-leg assets, built from the pinned JSR graph (no +# The polyengine browser-leg assets, built from the pinned JSR graph (no # network fetch, no sha bookkeeping — deno.lock carries JSR package # integrity and --frozen enforces it): # -# target/deltic-browser/deltic-embedder.mjs bundled from -# js/runner-deltic/browser-bundle-entry.ts (embedder API + +# target/polyengine-browser/polyengine-embedder.mjs bundled from +# js/runner-polyengine/browser-bundle-entry.ts (embedder API + # Translator + ct-runner glue + wasi shims, one platform-neutral # ES module — what the browser worker and the node selftest load) -# target/deltic-browser/deltic-translator-shim.wasm the translator -# asset packaged in @deltic/translator, copied out of the +# target/polyengine-browser/polyengine-translator-shim.wasm the translator +# asset packaged in @polyengine/translator, copied out of the # lock-pinned module cache (the Deno runner leg needs no copy: it # loads the packaged translator through the module graph) # # The directory is version-free on purpose: the lock owns versioning. -deltic-assets: deltic-pin-gate +polyengine-assets: polyengine-pin-gate #!/usr/bin/env bash set -euo pipefail - out=target/deltic-browser + out=target/polyengine-browser mkdir -p "$out" - deno bundle --config js/runner-deltic/deno.json --frozen --platform browser \ - -o "$out/deltic-embedder.mjs" js/runner-deltic/browser-bundle-entry.ts + deno bundle --config js/runner-polyengine/deno.json --frozen --platform browser \ + -o "$out/polyengine-embedder.mjs" js/runner-polyengine/browser-bundle-entry.ts tmp=$(mktemp -d); trap 'rm -rf "$tmp"' EXIT - deno info --json --config js/runner-deltic/deno.json --frozen @deltic/translator \ + deno info --json --config js/runner-polyengine/deno.json --frozen @polyengine/translator \ > "$tmp/info.json" - pin=$(grep -o 'jsr:@deltic/runtime@[^/"]*' js/runner-deltic/deno.json | head -1 | sed 's/.*@//') - python3 - "$tmp/info.json" "$out/deltic-translator-shim.wasm" "$pin" <<'PY' + pin=$(grep -o 'jsr:@polyengine/runtime@[^/"]*' js/runner-polyengine/deno.json | head -1 | sed 's/.*@//') + python3 - "$tmp/info.json" "$out/polyengine-translator-shim.wasm" "$pin" <<'PY' import json, sys graph = json.load(open(sys.argv[1])) want = sys.argv[3] - mods = [m for m in graph["modules"] if "/@deltic/" in m.get("specifier", "")] + mods = [m for m in graph["modules"] if "/@polyengine/" in m.get("specifier", "")] bad = {m["specifier"] for m in mods if want not in m["specifier"]} if bad: sys.exit(f"pin drift in translator graph (expected {want}): {bad}") @@ -217,30 +218,30 @@ deltic-assets: deltic-pin-gate open(sys.argv[2], "wb").write(body) PY -# Path 3: deltic-deno runner (runner-is-provider, like Path 3, but no -# transpile step, no generated tree, and no engine flag — deltic is a +# Path 3: polyengine-deno runner (runner-is-provider, like Path 3, but no +# transpile step, no generated tree, and no engine flag — polyengine is a # runtime linker; the contract's async exports run on the callback ABI -# under stock Deno). Pinned to exact deltic JSR prereleases by -# js/runner-deltic/deno.json, with deno.lock enforced via --frozen and -# agreement asserted by deltic-pin-gate. The Deno leg's translator comes -# from the packaged @deltic/translator through the module graph; the -# browser/node legs use the repo-built assets (`just deltic-assets`). +# under stock Deno). Pinned to exact polyengine JSR releases by +# js/runner-polyengine/deno.json, with deno.lock enforced via --frozen and +# agreement asserted by polyengine-pin-gate. The Deno leg's translator comes +# from the packaged @polyengine/translator through the module graph; the +# browser/node legs use the repo-built assets (`just polyengine-assets`). # Tag scheduling comes from the suite's own embedded -# inventory (deltic#25): the fixture leg runs --missing hsm exactly like +# inventory (polyengine#25): the fixture leg runs --missing hsm exactly like # Paths 1/4 and schedules the hsm case out as not-applicable; the sample # legs reuse Path 2/3's human golden and Path 2/4's fold golden. The -# selftest leg drives the BROWSER worker's engine path (js/runner-deltic/ +# selftest leg drives the BROWSER worker's engine path (js/runner-polyengine/ # engine.mjs + the shared harness.mjs case loop) over the pinned embedder # bundle under plain node — no --experimental-wasm-jspi: the callback ABI # needs no engine flag, which is the browser-leg premise. -verify-deltic: build deltic-assets +verify-polyengine: build polyengine-assets #!/usr/bin/env bash set -euo pipefail tmp=$(mktemp -d); trap 'rm -rf "$tmp"' EXIT - translator=target/deltic-browser/deltic-translator-shim.wasm - bundle=target/deltic-browser/deltic-embedder.mjs - run() { deno run --allow-read=target --config js/runner-deltic/deno.json --frozen \ - js/runner-deltic/runner.ts "$@"; } + translator=target/polyengine-browser/polyengine-translator-shim.wasm + bundle=target/polyengine-browser/polyengine-embedder.mjs + run() { deno run --allow-read=target --config js/runner-polyengine/deno.json --frozen \ + js/runner-polyengine/runner.ts "$@"; } norm() { sed -E -e 's/"artifact-sha256":"[0-9a-f]{64}"/"artifact-sha256":""/' \ -e 's/,"duration-ms":[0-9]+//g'; } fold() { cargo run -q -p component-test-cli -- fold "$@"; } @@ -249,7 +250,7 @@ verify-deltic: build deltic-assets diff -u expected/verify-run-sample.txt <(printf '%s\n' "$out") run {{release_dir}}/sample_suite.wasm --jsonl > "$tmp/sample.jsonl" && code=0 || code=$? test "$code" -eq 1 - norm < "$tmp/sample.jsonl" | diff -u expected/verify-deltic-sample.jsonl - + norm < "$tmp/sample.jsonl" | diff -u expected/verify-polyengine-sample.jsonl - fold components/sample-suite/tests.lock < "$tmp/sample.jsonl" \ > "$tmp/sample-fold.txt" && code=0 || code=$? test "$code" -eq 1 @@ -257,14 +258,14 @@ verify-deltic: build deltic-assets run {{release_dir}}/fixture_suite.wasm --jsonl --missing hsm \ > "$tmp/fixture.jsonl" && code=0 || code=$? test "$code" -eq 1 - norm < "$tmp/fixture.jsonl" | diff -u expected/verify-deltic-fixture.jsonl - + norm < "$tmp/fixture.jsonl" | diff -u expected/verify-polyengine-fixture.jsonl - fold components/fixture-suite/tests.lock < "$tmp/fixture.jsonl" \ > "$tmp/fixture-fold.txt" && code=0 || code=$? test "$code" -eq 1 - diff -u expected/verify-deltic-fixture-fold.txt "$tmp/fixture-fold.txt" - node js/runner-deltic/selftest.mjs "$bundle" "$translator" \ + diff -u expected/verify-polyengine-fixture-fold.txt "$tmp/fixture-fold.txt" + node js/runner-polyengine/selftest.mjs "$bundle" "$translator" \ {{release_dir}}/sample_suite.wasm {{release_dir}}/fixture_suite.wasm - echo "verify-deltic: output matches expected/ (incl. shared human + fold goldens)" + echo "verify-polyengine: output matches expected/ (incl. shared human + fold goldens)" # Path 4: inventory + results pipeline (lock check, JSONL fold). The # fixture leg exercises the JSONL wire shape for trap provenance, @@ -359,25 +360,25 @@ emit-demo: build # --- viewer ------------------------------------------------------------ # Build the viewer's engines: the viewer-aggregate component (the gate's -# aggregation compiled to wasm — runtime-linked by deltic in the page, +# aggregation compiled to wasm — runtime-linked by polyengine in the page, # no transpile step) and the demo suites (component wasm, verbatim), -# plus the pinned deltic assets copied beside the viewer so local serve -# and Pages share one relative layout (js/viewer/deltic.mjs). -viewer-build: build deltic-assets +# plus the pinned polyengine assets copied beside the viewer so local serve +# and Pages share one relative layout (js/viewer/polyengine.mjs). +viewer-build: build polyengine-assets #!/usr/bin/env bash set -euo pipefail cargo build --release --target wasm32-wasip2 -p viewer-aggregate - mkdir -p js/viewer/deltic js/viewer/generated js/viewer/suite - cp target/deltic-browser/deltic-translator-shim.wasm \ - target/deltic-browser/deltic-embedder.mjs js/viewer/deltic/ + mkdir -p js/viewer/polyengine js/viewer/generated js/viewer/suite + cp target/polyengine-browser/polyengine-translator-shim.wasm \ + target/polyengine-browser/polyengine-embedder.mjs js/viewer/polyengine/ cp {{release_dir}}/viewer_aggregate.wasm js/viewer/generated/viewer-aggregate.wasm cp {{release_dir}}/sample_suite.wasm {{release_dir}}/fixture_suite.wasm js/viewer/suite/ -# The viewer's drift gate: the wasm aggregate under deltic (exactly the +# The viewer's drift gate: the wasm aggregate under polyengine (exactly the # page's instantiation) must reproduce the CLI gate's verdicts over the # fixture pipeline, plus the shared harness loop's gating adapters over # synthetic cases. Plain node — no JSPI flag anywhere. The suite- -# execution legs live in verify-deltic's selftest. The page itself is +# execution legs live in verify-polyengine's selftest. The page itself is # thin glue over these engines plus worker plumbing. verify-viewer: viewer-build #!/usr/bin/env bash @@ -395,8 +396,8 @@ verify-viewer: viewer-build node js/viewer/selftest.mjs \ "$tmp/tests.lock" examples/aggregate/targets.toml \ "$tmp/native.jsonl" "$tmp/sim.jsonl" \ - js/viewer/deltic/deltic-embedder.mjs \ - js/viewer/deltic/deltic-translator-shim.wasm \ + js/viewer/polyengine/polyengine-embedder.mjs \ + js/viewer/polyengine/polyengine-translator-shim.wasm \ js/viewer/generated/viewer-aggregate.wasm # The shared consumer glue (import binding, envelope normalization,