From 76cea0fe844e0195b521fcb180c3cb1007171a9e Mon Sep 17 00:00:00 2001 From: Lann Martin Date: Wed, 12 Aug 2026 10:59:21 -0400 Subject: [PATCH] deltic: bump pin to 0.1.0-pre.g078aa15; A10 rename (ComponentException, {kind, value}) Coordinated family migration for deltic amendment A10 (breaking): WitError -> ComponentException (isWitError -> isComponentException) and variant-family discriminants {tag, val} -> {kind, value} (payloadless cases still omit the payload property; case names kebab-case verbatim). Pin moves to the first prerelease whose @deltic/protocol dependency (0.2.0) carries the rename. jco-era surfaces keep jco conventions. Gates: deltic-pin-gate, deltic-assets, verify-deltic (incl. selftest legs + goldens) all green --- js/runner-deltic/README.md | 2 +- js/runner-deltic/deno.json | 10 +++---- js/runner-deltic/deno.lock | 48 +++++++++++++++++++------------- js/runner-deltic/engine.mjs | 2 +- js/runner-deltic/worker-main.mjs | 5 ++-- js/viewer/harness.mjs | 14 +++++++--- justfile | 20 +++++++++++-- 7 files changed, 65 insertions(+), 36 deletions(-) diff --git a/js/runner-deltic/README.md b/js/runner-deltic/README.md index fc4f450..33027db 100644 --- a/js/runner-deltic/README.md +++ b/js/runner-deltic/README.md @@ -55,7 +55,7 @@ repo bundles one worker entry — the deltic 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 import-record factory. One bundle means one embedder module instance, -which is what keeps `instanceof WitError` true across the host-module +which is what keeps `instanceof ComponentException` true across the host-module boundary; workers resolve no import maps, so this is the only sound shape. The stock `browser-worker.mjs` is `workerMain()` with the bundleUrl-loading defaults. diff --git a/js/runner-deltic/deno.json b/js/runner-deltic/deno.json index a180dd4..ac22263 100644 --- a/js/runner-deltic/deno.json +++ b/js/runner-deltic/deno.json @@ -19,11 +19,11 @@ // 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.1.0-pre.ga67ee83", - "@deltic/runtime/embedder": "jsr:@deltic/runtime@0.1.0-pre.ga67ee83/embedder", - "@deltic/runtime/shim": "jsr:@deltic/runtime@0.1.0-pre.ga67ee83/shim", - "@deltic/translator": "jsr:@deltic/translator@0.1.0-pre.ga67ee83", - "@deltic/wasi-shims": "jsr:@deltic/wasi-shims@0.1.0-pre.ga67ee83" + "@deltic/ct-runner": "jsr:@deltic/ct-runner@0.1.0-pre.g078aa15", + "@deltic/runtime/embedder": "jsr:@deltic/runtime@0.1.0-pre.g078aa15/embedder", + "@deltic/runtime/shim": "jsr:@deltic/runtime@0.1.0-pre.g078aa15/shim", + "@deltic/translator": "jsr:@deltic/translator@0.1.0-pre.g078aa15", + "@deltic/wasi-shims": "jsr:@deltic/wasi-shims@0.1.0-pre.g078aa15" }, // Deno's supply-chain minimum-dependency-age gate (24h default) applies // even to exact prerelease pins; deltic publishes per commit, so the diff --git a/js/runner-deltic/deno.lock b/js/runner-deltic/deno.lock index c13ad2c..6407ece 100644 --- a/js/runner-deltic/deno.lock +++ b/js/runner-deltic/deno.lock @@ -1,41 +1,49 @@ { "version": "5", "specifiers": { - "jsr:@deltic/ct-runner@0.1.0-pre.ga67ee83": "0.1.0-pre.ga67ee83", - "jsr:@deltic/runtime@0.1.0-pre.ga67ee83": "0.1.0-pre.ga67ee83", - "jsr:@deltic/runtime@~0.1.0-pre.ga67ee83": "0.1.0-pre.ga67ee83", - "jsr:@deltic/translator@0.1.0-pre.ga67ee83": "0.1.0-pre.ga67ee83", - "jsr:@deltic/wasi-shims@0.1.0-pre.ga67ee83": "0.1.0-pre.ga67ee83" + "jsr:@deltic/ct-runner@0.1.0-pre.g078aa15": "0.1.0-pre.g078aa15", + "jsr:@deltic/protocol@0.2": "0.2.0", + "jsr:@deltic/runtime@0.1.0-pre.g078aa15": "0.1.0-pre.g078aa15", + "jsr:@deltic/runtime@~0.1.0-pre.g078aa15": "0.1.0-pre.g078aa15", + "jsr:@deltic/translator@0.1.0-pre.g078aa15": "0.1.0-pre.g078aa15", + "jsr:@deltic/wasi-shims@0.1.0-pre.g078aa15": "0.1.0-pre.g078aa15" }, "jsr": { - "@deltic/ct-runner@0.1.0-pre.ga67ee83": { - "integrity": "d78e96eba54e53dabe7c1de5a67782aad755362824d741913ab4d36941ebfbcc", + "@deltic/ct-runner@0.1.0-pre.g078aa15": { + "integrity": "d777a53e6be337d999a80de030628e1226ae7649ca62e49dd444e58d0973e6be", "dependencies": [ - "jsr:@deltic/runtime@~0.1.0-pre.ga67ee83" + "jsr:@deltic/runtime@~0.1.0-pre.g078aa15" ] }, - "@deltic/runtime@0.1.0-pre.ga67ee83": { - "integrity": "2a2b0949031747a2340dc186299e654ea9f361ae39ac6bd633019940682db4ed" + "@deltic/protocol@0.2.0": { + "integrity": "028be6a3623c5e910598aa7a199209b85e8931ae484ac7f6638d610ddb0e19fa" }, - "@deltic/translator@0.1.0-pre.ga67ee83": { - "integrity": "e4f1bb219e56b62262b0c9665e3f6646aa13883b2cfbb9d6306f69d19974d412", + "@deltic/runtime@0.1.0-pre.g078aa15": { + "integrity": "5e64f8dc6d32190ecd394d6ad9881eb0fa97b6598b1e7f2ef1d52cff4674287c", "dependencies": [ - "jsr:@deltic/runtime@~0.1.0-pre.ga67ee83" + "jsr:@deltic/protocol" ] }, - "@deltic/wasi-shims@0.1.0-pre.ga67ee83": { - "integrity": "a5754e65d50873e675695a51279989e22b3771e31f16a84a09feb15905c574a7", + "@deltic/translator@0.1.0-pre.g078aa15": { + "integrity": "7125f99ac46af4a69f1c432def2b7ea4be63509c3a7ebae83537357615ec33ef", "dependencies": [ - "jsr:@deltic/runtime@~0.1.0-pre.ga67ee83" + "jsr:@deltic/runtime@~0.1.0-pre.g078aa15" + ] + }, + "@deltic/wasi-shims@0.1.0-pre.g078aa15": { + "integrity": "fba2081f804eaaccf95e31cdd634fd85a2d724f6be7f62578ddc26aef03524a1", + "dependencies": [ + "jsr:@deltic/protocol", + "jsr:@deltic/runtime@~0.1.0-pre.g078aa15" ] } }, "workspace": { "dependencies": [ - "jsr:@deltic/ct-runner@0.1.0-pre.ga67ee83", - "jsr:@deltic/runtime@0.1.0-pre.ga67ee83", - "jsr:@deltic/translator@0.1.0-pre.ga67ee83", - "jsr:@deltic/wasi-shims@0.1.0-pre.ga67ee83" + "jsr:@deltic/ct-runner@0.1.0-pre.g078aa15", + "jsr:@deltic/runtime@0.1.0-pre.g078aa15", + "jsr:@deltic/translator@0.1.0-pre.g078aa15", + "jsr:@deltic/wasi-shims@0.1.0-pre.g078aa15" ] } } diff --git a/js/runner-deltic/engine.mjs b/js/runner-deltic/engine.mjs index 838d008..e812ea3 100644 --- a/js/runner-deltic/engine.mjs +++ b/js/runner-deltic/engine.mjs @@ -21,7 +21,7 @@ * @param {object} [input.hostImports] SUT host-import record fragments * (interface id -> implementation), merged over the engine's wasi + * test-context imports. MUST be built against the same embedder module - * instance as `bundle` (one WitError class; see worker-main.mjs). + * instance as `bundle` (one ComponentException class; see worker-main.mjs). * @returns {Promise<{newTests: () => Promise, Context, tagsOf}>} */ export async function loadSuite( diff --git a/js/runner-deltic/worker-main.mjs b/js/runner-deltic/worker-main.mjs index 64261c9..cf89f10 100644 --- a/js/runner-deltic/worker-main.mjs +++ b/js/runner-deltic/worker-main.mjs @@ -5,8 +5,9 @@ // (`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 -// embedder module loads twice and `instanceof WitError` stops holding -// across the boundary. The downstream pattern is a bundled worker entry: +// 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/* diff --git a/js/viewer/harness.mjs b/js/viewer/harness.mjs index 5362172..5244017 100644 --- a/js/viewer/harness.mjs +++ b/js/viewer/harness.mjs @@ -249,12 +249,18 @@ export async function runCases({ } } catch (e) { const payload = e?.payload ?? e; - if (payload?.tag === "failed") { + // Shape-compatible read: the deltic 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. + const kind = payload?.kind ?? payload?.tag; + const value = payload && "value" in payload ? payload.value : payload?.val; + if (kind === "failed") { failed++; - event = { case: name, status: "fail", provenance: "returned", detail: payload.val }; - } else if (payload?.tag === "skipped") { + event = { case: name, status: "fail", provenance: "returned", detail: value }; + } else if (kind === "skipped") { skipped++; - event = { case: name, status: "skipped", provenance: "returned", detail: payload.val }; + event = { case: name, status: "skipped", provenance: "returned", detail: value }; } else { failed++; event = { diff --git a/justfile b/justfile index f38e0c3..f467bbf 100644 --- a/justfile +++ b/justfile @@ -139,6 +139,15 @@ verify-cli: build # specifier in every deno.json, and every @deltic package the lock # resolves, must name the SAME prerelease — 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 +# stable, independently-versioned package (0.1.0, no per-commit prerelease +# hash) that @deltic/runtime/wasi-shims depend on transitively — it is not +# named by any jsr:@deltic/*@ 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 +# still trips the gate. See contracts/embedder-api.md "Migration notes" +# (upstream, pre-b297834) and js/runner-deltic/deno.lock. deltic-pin-gate: #!/usr/bin/env bash set -euo pipefail @@ -149,14 +158,19 @@ deltic-pin-gate: python3 - "$v" js/runner-deltic/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 + def pkg_name(k): + # k looks like "jsr:@deltic/foo@1.2.3" or "@deltic/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} + 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/") - and not k.endswith("@" + want)}) + and not k.endswith("@" + want) and pkg_name(k) not in stable}) if bad: sys.exit(f"deltic lock drift (want {want}): {sorted(bad)}") PY - echo "deltic pin gate: all @deltic packages pinned to $v" + echo "deltic pin gate: all @deltic packages pinned to $v (protocol excluded, stable)" # The deltic browser-leg assets, built from the pinned JSR graph (no # network fetch, no sha bookkeeping — deno.lock carries JSR package