Consume deltic from JSR: packaged translator, no fetch step - #45
Conversation
deltic publishes exactly-pinned JSR prereleases per green upstream
commit (0.1.0-pre.g<shorthash>), with @deltic/translator shipping the
translator wasm for the same commit — the runtime/translator
plan-format coupling is self-consistent inside each graph by
construction. That dissolves most of the raw-URL pin architecture:
- import maps move to jsr:@deltic/{runtime,wasi-shims,translator}
versions; deno.lock carries integrity, --frozen enforces it;
minimumDependencyAge exempts jsr:@deltic/* from Deno's default
supply-chain age gate so same-day prereleases resolve (everything
else keeps the default);
- fetch-translator.ts is retired: host-deltic's harness and the spike
drivers load @deltic/translator's packaged asset through the module
graph (permission-free on Deno — no --allow-net, no sha bookkeeping,
no target/deltic cache); what remains of the one-pin-repo-wide gate
is an equality assert across the two deno configs in the exam-deltic
recipe;
- the raw-URL translate-CLI invocation in ping-demo's build.sh becomes
a small shared script (experiments/iroh-relay-ws/host/translate.ts:
defaultTranslator + Translator.translateRaw), which also lets the
spikes' browser harnesses pre-translate their guests — all three
browser surfaces now ride the A4 envelope path, the ?translator=
query-param plumbing is gone, and no translator ever ships to a
browser.
Gates: just exam-deltic — EXAM PASS (5/5, pin assert green);
iroh-relay-ws run.sh + browser-test (phase 2 p50 550us);
iroh-blobs run.sh + browser-test (phase 2 6.36 MiB/s);
ping-demo build.sh + Playwright suite PASS; deno checks green across
host-deltic and all three experiments; just check green.
lann
left a comment
There was a problem hiding this comment.
Reviewed with independent verification (details below). Direction is right and matches deltic's consumption README exactly; one small real bug and one gate-coverage suggestion before merge, two nits.
Bug (fresh checkout): the browser harnesses write the envelope into dist/ before anything creates it. Both browser-test.mjs files run translateGuest() → translate.ts → Deno.writeTextFile(<host>/dist/<guest>.plan.json) before bundleEntry(). dist/ is gitignored, Deno.writeTextFile does not create parent dirs (verified: NotFound), and in the old order the first dist/ writer was deno bundle, which does create the output dir (verified). So on a fresh clone the browser test dies at the translate step in both spikes; existing workspaces don't see it because dist/ survives from earlier runs. Cheapest robust fix: await Deno.mkdir(dirname(output), { recursive: true }) in translate.ts — it covers every caller including future ones (ping-demo's build.sh is unaffected only because it happens to mkdir -p "$SITE" first).
Gate suggestion: assert one version across all @deltic/* pins, not just @deltic/runtime across the two configs. The retired assertPinConsistency checked every deltic URL in each file against THE tag; the new exam-deltic grep only compares @deltic/runtime between the two deno.jsons. A bump that moves runtime+wasi-shims but forgets @deltic/translator (or vice versa) passes the gate and lands in exactly the territory this PR calls impossible "by construction": translator wasm from one commit, runtime from another — plan-format skew, or two runtime copies in the graph (WitError identity break), depending on how the ~0.1.0-pre.g<hash> range dedupes (hash prereleases are unordered, so dedupe direction is luck). Self-consistency is by construction only when the import map agrees with itself. One-liner that closes the whole class:
v=$(grep -ho 'jsr:@deltic/[a-z-]*@[^/"]*' host-deltic/deno.json experiments/iroh-relay-ws/host/deno.json | sed 's/.*@//' | sort -u)
[ "$(printf '%s\n' "$v" | wc -l)" = 1 ] || { echo "deltic pin drift: $v" >&2; exit 1; }(Tested against the branch: yields exactly 0.1.0-pre.ga67ee83; the minimumDependencyAge exclude jsr:@deltic/* doesn't match the pattern.)
Nits
host-deltic/deno.lockstill carries 48 stalepre-58b2404remote entries (pre-existing; nothing references them,--frozentolerates extras). The README's own bump procedure — delete both locks, regenerate — would drop them; worth doing while touching the locks anyway.- The browser-test translate step widened from scoped grants to bare
--allow-read --allow-write. Retiring--allow-netis the win, but read/write could stay scoped (--allow-read=<ROOT> --allow-write=<host>/dist). Dev harness, so nit.
Verified during review
- Consumption pattern matches deltic README §"Consuming the unstable prereleases" verbatim (exact
0.1.0-pre.g<shorthash>pins, theminimumDependencyAgestanza, packageddefaultTranslator()); CI pins Deno 2.9.5, satisfying the ≥2.9 wildcard-exclude requirement. - Reproduced the age-gate necessity empirically: unqualified
deno info jsr:@deltic/translator@0.1.0-pre.ga67ee83is blocked by the default 24 h gate today; the version exists on JSR (as do runtime/wasi-shims at the same hash, per lock integrity +--frozenCI). defaultTranslator()/Translator.translateRaw()verified at a67ee83, including the Deno permission-free module-graph load path claimed in the body;artifactsFrompre-exists inharness.ts(ping-demo already rides it), so the browser entries' import is sound.- No leftover
fetch-translator/DELTIC_TRANSLATOR/ raw-URL deltic references on the branch outside lockfiles. - Merge semantics vs. main's #44/#32 (branch is 2 merges behind): no new callers of the deleted machinery landed on main, and main's newer websocket pin (
f8fdf66) still imports only@deltic/runtime/embedder, which both configs map — textually and semantically clean. - CI has no deno-side gate (
just check= fmt/clippy/wit/test), so I ran the Deno graphs independently at the branch's.depspins:deno checkgreen for host-deltic src and all three experiments (run/browser-entry/translate/harness, blobs host, ping-demodemo.ts).
LGTM once the dist/ fix lands; the gate strengthening can ride the same commit or a follow-up.
… every @deltic package
|
Pushed the review fixes directly (fc713d1) rather than waiting — all three actionable items from the review, plus a correction to the review itself: What the commit does
Review correction — the "48 stale lock entries" nit was wrong. Deleting and regenerating Gates re-run on the branch (all green): |
The follow-up ruling flagged in #43: deltic consumption moves from raw.githubusercontent URLs + the sha-pinned release-asset fetch to the JSR prereleases deltic now publishes per green commit (
0.1.0-pre.g<shorthash>, same hash as the GitHub release).What this buys
@deltic/translatorships the translator wasm inside the package at the same version as the runtime, so the plan-format coupling thatfetch-translator.tsexisted to police is now self-consistent per graph by construction. The fetch step, the sha256 bookkeeping, thetarget/deltic/cache, and the--allow-netgrants all retire; on Deno the translator loads through the module graph permission-free.deno.jsons carrying the same JSR versions + their lockfiles (--frozen). The residual cross-config convention (one deltic version repo-wide) is asserted by theexam-delticrecipe — the natural fail-loud point now thatfetch-translator.ts's gate is gone.translate.ts(defaultTranslator()+Translator.translateRaw), and the spikes' browser harnesses use it too: all three browser surfaces now ride the A4 envelope path — component + envelope fetched, no translator on any page, and the?translator=query-param plumbing is deleted.minimumDependencyAgeexemptsjsr:@deltic/*(per deltic's consumption README) so same-day prerelease bumps resolve; every other dependency keeps Deno's default 24-hour supply-chain gate.Not changed: the sibling host modules still come from the
.depscheckouts pinned bysetup.sh; the deltic version itself stays0.1.0-pre.ga67ee83(same commit #43 pinned by tag).Gates (all green):
just exam-deltic5/5 incl. the new pin assert; relay-wsrun.sh+ browser-test (phase-2 echo p50 550 µs); blobsrun.sh+ browser-test (phase-2 fetch 6.36 MiB/s); ping-demobuild.sh+ full Playwright suite;deno checkacross host-deltic and all three experiments;just check.