You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Small doc/contract/strictness cleanups collected while auditing. None is a
correctness emergency; each is either a doc claim that no longer matches the
source, a contract that omits behavior the code ships, or a strictness gap
that lets a wrong shape pass silently.
Found in structured audit round 3 (2026-08-21). Audit/testing regime: #175.
Undocumented dual key spellings for world-level imports. runtime/src/embedder/instantiate.ts:499-514 resolves the kebab
interface/resource id verbatim first, then falls back to camelCase; pick() accepts both pascalCase and raw kebab for resource classes
(instantiate.ts:584, :646). contracts/embedder-api.md names only
camelCase, and principle 3 permits liberal acceptance only where the TS
type names a single canonical form. Consumers can (and will) couple to
the unsanctioned kebab spelling. Either sanction both spellings in the
contract or reject the non-canonical one.
EmbedderOptions.verifyHash opt-out is not in the contract. runtime/src/embedder/instantiate.ts:129-131 (default true) lets a
caller skip the sha-256 check that contracts/embedder-api.md A4
states unconditionally ("fails loudly"). Contract-document the escape
hatch or remove it.
fromHostbool coerces instead of type-checking. runtime/src/embedder/values.ts:287-288 returns Boolean(v) for any
input, while every sibling primitive lower rejects wrong-typed input
with a site-named TypeError. "false" lowers as true; shape bugs
pass silently.
A dropped-but-unbound Stream handle can still be transferred live. runtime/src/embedder/streams.ts:293-299: drop() on an unbound
handle only sets #dropped (there is no #host to drop). A later
lower calls takeValue (streams.ts:216-227), which runs bindElement and never consults #dropped, minting a live shared end
for the guest. takeValue should refuse a dropped handle.
Contracts
contracts/plan-format.mdexports[] schema is out of sync with the
wire format. It omits the "instance" kind entirely — emitted by the
shim since the resources corpus
(crates/translator-shim/src/plan.rs:565), consumed at runtime/src/exec/executor.ts:851 and runtime/src/digest/digest.ts:209 — and documents the "type" kind
with the wrong shape: the C2 amendment
(contracts/plan-format.md:355-365) says {"kind":"type","resource":n}, while the wire shape is {kind:"type", name, type:{kind:"resource"|"value", …}}
(runtime/src/plan/format.ts:259-278). The contract's own compat rule
requires producer + consumer + contract in sync.
Cache-key features component is inert caller-supplied salt. runtime/src/cache/core.ts:122-139 takes features: string[] = []
from the caller and never derives it from the translator, while crates/translator-shim/src/lib.rs:111-113 documents producer.features as "part of the artifact-cache key" (echoed by docs/architecture.md §10 and contracts/plan-format.md:30-36). Sound
today only because translatorBuildHash subsumes it (features are
compiled into the shim wasm) — it becomes a cache-poisoning bug the day translateRaw grows a runtime features parameter. Doc drift plus a
dormant trap.
Digest name-flattening join is collision-capable and unspecified. runtime/src/digest/digest.ts:161-162 and :186 flatten with [...path, name].join("/"): import "a/b" with empty path collides
with import "b" at path ["a"]. Not covered by contracts/digest.md's normalization rules. Preferred resolution is
length-prefixing/nesting when the imports corpus lands — not blessing
the join after the fact.
The envelope container format has no contracts/*.md authority. WireEnvelope (runtime/src/plan/format.ts:284-295) is defined only by crates/translator-shim/README.md, yet it is the production deploy
artifact (tools/translate output, embedder-api A4) and the cache
determinism unit. It carries no version field of its own, and
truncation/extension behavior is unstated.
WASI
WASI WIT sets are not vendored in-repo. No wasi:io, wasi:cli, wasi:filesystem, wasi:random, or wasi:sockets WIT at @0.2
exists anywhere in the tree (the only vendored wasi:* packages are clocks@0.3.0/0.3.1, http@0.3.1, sockets@0.3.0, and those sit
under examples/guests/http-fetch/wit/deps/ as example-guest deps, not
as an authority). Every 0.2-track semantic judgment therefore rests on
unvendored authority, and source comments cite line numbers into WITs
that cannot be checked in-tree (e.g. wasi/src/io.ts:69 cites
"io.wit:23"). Same gap for wasi:cli/filesystem/random@0.3.
Recommend vendoring the claimed sets — wasi/src/internal/fs_provider.ts:8
claims WASI 0.2.12.
header-error.forbidden is never produced. wasi/src/http.ts:324-337 and :351-365 validate syntax only;
forbidden names are accepted into fields and then silently owned by fetch at send time. This is the platform-managed-headers divergence
already recorded at wasi/src/http.ts:57-59 — the divergence record
should name forbidden explicitly.
Monotonic clock get-resolution claims 1 µs. wasi/src/clocks.ts:23-26 pins RESOLUTION_NS = 1_000n, optimistic
where performance.now() is coarsened to 100 µs (non-cross-origin-
isolated browser contexts).
Harness
Deno conformance lane pins no totals. harness/tests/conformance_test.ts:120-139 fails on unexpected
failures, stale xfails, and zero commands, but nothing bounds skip
counts or asserts the pass count — so pass→skip drift is invisible on
the primary lane (the shell/browser lanes do pin totals). Corollary: an
xfail entry whose command degrades from failed to skipped is
neither stale nor failing on the Deno lane.
fileDeltas whole-file exemption has no stale detection. tools/browser/classify.ts:61,83-85: a fileDeltas entry turns ANY
failure in the named file into an xfail, with no equivalent of the
per-line stale check. Currently unused by all 9 overlay files, so this
is latent machinery risk only; the first future use should get per-line
deltas instead wherever feasible.
Node openAt passes O_CREAT|O_DIRECTORY to the OS. wasi/src/filesystem_node.ts:236-262: for a nonexistent path with create + directory set, the ENOTDIR pre-check is skipped
(existing === undefined) and the combination reaches open(2), which
Linux documents as unspecified — it can create a regular file and then
fail ENOTDIR, leaving a stray file behind. wasmtime rejects
create+directory up front as invalid.
Small doc/contract/strictness cleanups collected while auditing. None is a
correctness emergency; each is either a doc claim that no longer matches the
source, a contract that omits behavior the code ships, or a strictness gap
that lets a wrong shape pass silently.
Found in structured audit round 3 (2026-08-21). Audit/testing regime: #175.
README/docs
README.md:20claims "1250 passing / 0failing"; the measured, expectation-pinned value is 1257
(
harness/browser/expectations/chromium.ts:54,harness/shell/expectations/*.ts). The README number predates theClose the non-pin conformance xfail residues (5 shim gaps + 6 named residues) #13/polymorph-tls: smoke the jco-leg surface under deltic (unexamined) #18 corpus prunes.
Embedder API
runtime/src/embedder/instantiate.ts:499-514resolves the kebabinterface/resource id verbatim first, then falls back to camelCase;
pick()accepts both pascalCase and raw kebab for resource classes(
instantiate.ts:584,:646).contracts/embedder-api.mdnames onlycamelCase, and principle 3 permits liberal acceptance only where the TS
type names a single canonical form. Consumers can (and will) couple to
the unsanctioned kebab spelling. Either sanction both spellings in the
contract or reject the non-canonical one.
EmbedderOptions.verifyHashopt-out is not in the contract.runtime/src/embedder/instantiate.ts:129-131(defaulttrue) lets acaller skip the sha-256 check that
contracts/embedder-api.mdA4states unconditionally ("fails loudly"). Contract-document the escape
hatch or remove it.
fromHostboolcoerces instead of type-checking.runtime/src/embedder/values.ts:287-288returnsBoolean(v)for anyinput, while every sibling primitive lower rejects wrong-typed input
with a site-named
TypeError."false"lowers astrue; shape bugspass silently.
Streamhandle can still be transferred live.runtime/src/embedder/streams.ts:293-299:drop()on an unboundhandle only sets
#dropped(there is no#hostto drop). A laterlower calls
takeValue(streams.ts:216-227), which runsbindElementand never consults#dropped, minting a live shared endfor the guest.
takeValueshould refuse a dropped handle.Contracts
contracts/plan-format.mdexports[]schema is out of sync with thewire format. It omits the
"instance"kind entirely — emitted by theshim since the resources corpus
(
crates/translator-shim/src/plan.rs:565), consumed atruntime/src/exec/executor.ts:851andruntime/src/digest/digest.ts:209— and documents the"type"kindwith the wrong shape: the C2 amendment
(
contracts/plan-format.md:355-365) says{"kind":"type","resource":n}, while the wire shape is{kind:"type", name, type:{kind:"resource"|"value", …}}(
runtime/src/plan/format.ts:259-278). The contract's own compat rulerequires producer + consumer + contract in sync.
featurescomponent is inert caller-supplied salt.runtime/src/cache/core.ts:122-139takesfeatures: string[] = []from the caller and never derives it from the translator, while
crates/translator-shim/src/lib.rs:111-113documentsproducer.featuresas "part of the artifact-cache key" (echoed bydocs/architecture.md§10 andcontracts/plan-format.md:30-36). Soundtoday only because
translatorBuildHashsubsumes it (features arecompiled into the shim wasm) — it becomes a cache-poisoning bug the day
translateRawgrows a runtime features parameter. Doc drift plus adormant trap.
runtime/src/digest/digest.ts:161-162and:186flatten with[...path, name].join("/"): import"a/b"with empty path collideswith import
"b"at path["a"]. Not covered bycontracts/digest.md's normalization rules. Preferred resolution islength-prefixing/nesting when the imports corpus lands — not blessing
the join after the fact.
contracts/*.mdauthority.WireEnvelope(runtime/src/plan/format.ts:284-295) is defined only bycrates/translator-shim/README.md, yet it is the production deployartifact (
tools/translateoutput, embedder-api A4) and the cachedeterminism unit. It carries no version field of its own, and
truncation/extension behavior is unstated.
WASI
wasi:io,wasi:cli,wasi:filesystem,wasi:random, orwasi:socketsWIT at@0.2exists anywhere in the tree (the only vendored
wasi:*packages areclocks@0.3.0/0.3.1,http@0.3.1,sockets@0.3.0, and those situnder
examples/guests/http-fetch/wit/deps/as example-guest deps, notas an authority). Every 0.2-track semantic judgment therefore rests on
unvendored authority, and source comments cite line numbers into WITs
that cannot be checked in-tree (e.g.
wasi/src/io.ts:69cites"io.wit:23"). Same gap for
wasi:cli/filesystem/random@0.3.Recommend vendoring the claimed sets —
wasi/src/internal/fs_provider.ts:8claims WASI 0.2.12.
header-error.forbiddenis never produced.wasi/src/http.ts:324-337and:351-365validate syntax only;forbidden names are accepted into
fieldsand then silently owned byfetchat send time. This is the platform-managed-headers divergencealready recorded at
wasi/src/http.ts:57-59— the divergence recordshould name
forbiddenexplicitly.get-resolutionclaims 1 µs.wasi/src/clocks.ts:23-26pinsRESOLUTION_NS = 1_000n, optimisticwhere
performance.now()is coarsened to 100 µs (non-cross-origin-isolated browser contexts).
Harness
harness/tests/conformance_test.ts:120-139fails on unexpectedfailures, stale xfails, and zero commands, but nothing bounds skip
counts or asserts the pass count — so pass→skip drift is invisible on
the primary lane (the shell/browser lanes do pin totals). Corollary: an
xfail entry whose command degrades from failed to skipped is
neither stale nor failing on the Deno lane.
fileDeltaswhole-file exemption has no stale detection.tools/browser/classify.ts:61,83-85: afileDeltasentry turns ANYfailure in the named file into an xfail, with no equivalent of the
per-line stale check. Currently unused by all 9 overlay files, so this
is latent machinery risk only; the first future use should get per-line
deltas instead wherever feasible.
openAtpassesO_CREAT|O_DIRECTORYto the OS.wasi/src/filesystem_node.ts:236-262: for a nonexistent path withcreate+directoryset, the ENOTDIR pre-check is skipped(
existing === undefined) and the combination reachesopen(2), whichLinux documents as unspecified — it can create a regular file and then
fail
ENOTDIR, leaving a stray file behind. wasmtime rejectscreate+directory up front as
invalid.