Skip to content

Commit d8b71c8

Browse files
authored
CM-4 correction: wasmtime holds the gate and defers entry; switch the working assumption (#43) (#44)
1 parent 493f37d commit d8b71c8

13 files changed

Lines changed: 672 additions & 311 deletions

contracts/intrinsics.md

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -202,11 +202,20 @@ Status: **auto-detection is ON by default** (M2 exit, commit 652c1dc):
202202
all blocking sites lit, per-declaration suspendability classification
203203
(async-form copy built-ins never block; sync forms do; cancel forms per
204204
their own flag), `KNOWN_DIVERGENT` empty, the plain path pinned
205-
zero-cost for sync-only components. Two spots where wasmtime supersedes
206-
definitions.py are implemented and tracked upstream: cancel-copy
207-
completion superseding (CM-3) and entry-gating ending at
208-
resolution-plus-block rather than activation end (see
209-
upstream-component-model-repo-findings.md). Host-import lowers are
210-
deliberately outside the suspension classification — a sync-lowered
211-
Promise-returning host function degrades to a clean `NeedsJspi`
212-
capability signal.
205+
zero-cost for sync-only components. One spot where wasmtime supersedes
206+
definitions.py is implemented and tracked upstream: cancel-copy
207+
completion superseding (CM-3). The former second spot — "entry-gating
208+
ending at resolution-plus-block rather than activation end" — was a
209+
mischaracterization of wasmtime corrected on 2026-08-10 (wasmtime holds
210+
the gate for the whole invocation and defers the entry *decision*; see
211+
upstream-component-model-repo-findings.md CM-4 and
212+
exams/wasmtime-exclusivity/wasmtime-actual-semantics.md). deltic's
213+
shipping release-at-resolution rule is a deltic-only divergence slated
214+
for replacement by the hold + deferred-entry model
215+
([#43](https://github.com/lann/deltic/issues/43)); note the migration
216+
touches suspendability classification (a deferred async-lowered call
217+
trampoline becomes a potential suspension point — #43 carries the
218+
constraint that the plain path stays zero-cost for sync-only
219+
components). Host-import lowers are deliberately outside the suspension
220+
classification — a sync-lowered Promise-returning host function degrades
221+
to a clean `NeedsJspi` capability signal.

docs/architecture.md

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,22 @@ contracts throughout the repo. Related documents:
5656
wasmtime exhibits it too. The tie-breaking authority for semantic
5757
questions is the spec + `definitions.py`, with wasmtime as corroborating
5858
evidence — never the other way around. **One bounded exception**
59-
(operator decision, 2026-08-09): where `definitions.py` contradicts the
60-
spec repo's *own wast corpus* and wasmtime implements the corpus side,
61-
the corpus semantics is adopted as the working assumption — the
62-
expectation is that the reference will be amended, not the tests. Each
63-
such case must be a named finding in
59+
(operator decision, 2026-08-09; content corrected 2026-08-10): where
60+
`definitions.py` contradicts the spec repo's *own wast corpus* and
61+
wasmtime implements the corpus side, the corpus semantics — **as
62+
wasmtime actually implements it, verified against wasmtime source or
63+
trace, not as inferred from the test alone** (the CM-4 lesson:
64+
sync-streams.wast was satisfiable by two different semantics, and the
65+
first inference picked the wrong one) — is adopted as the working
66+
assumption; the expectation is that the reference will be amended, not
67+
the tests. Each such case must be a named finding in
6468
`upstream-component-model-repo-findings.md` (currently CM-3 and CM-4;
65-
CM-4's amendment sketch: `exams/wasmtime-exclusivity/spec-amendment.md`)
66-
and flips back if upstream adjudicates the other way. Bare wasmtime
67-
behavior with no corpus backing never supersedes the reference.
69+
CM-4's corrected model — hold-lifetime gate + deferred entry decision —
70+
is tracked for runtime adoption at
71+
[#43](https://github.com/lann/deltic/issues/43); amendment sketch:
72+
`exams/wasmtime-exclusivity/spec-amendment.md`) and flips back if
73+
upstream adjudicates the other way. Bare wasmtime behavior with no
74+
corpus backing never supersedes the reference.
6875
- TypeScript throughout the JS side: the runtime, the harness, and all
6976
generated bindings.
7077
- A performance story that can get fast later without rearchitecting.

docs/milestones.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ track: [consumers.md](consumers.md).
1414
| S0 | **Spike**: wasmtime-environ + FACT on wasm32 | **DONE — GO** (2026-08-08). `wasmtime-environ =47.0.3` builds for wasm32-unknown-unknown with zero imports; runs under Deno; FACT adapters (sync + async) emitted as core wasm; 1.66 MiB size-tuned (~0.5 MiB gzip); sub-ms steady-state translation. Fallback (vendoring FACT) not needed. The spike crate was promoted into `crates/translator-shim`. |
1515
| M0 | Contracts + plan executor on the task-model skeleton | **DONE** (2026-08-08). `contracts/{plan-format,descriptor-ir,intrinsics}.md` v0 pinned (the Phase-2 fan-out gate); spike promoted to `translator-shim` emitting plan v0; runtime structured around Task/Thread/Subtask from the start; `examples/guests/build/hello.component.wasm` (real wit-bindgen guest: strings, realloc, post-return) runs in Deno. |
1616
| M1 | Canonical ABI core | **DONE** (2026-08-08). Official suite green on Deno across all five sync directories — binary 119/122 (3 xfail: wasmtime-pin drift ×2, module-exports plan gap), validation 446/448 (+2 same-drift xfails), linking 272/272, resources 36/36, values 155/191 (+36 xfails, all M2-task-core-shaped) — zero unexpected failures; sync + async wit-bindgen guest fixtures roundtrip; transcoder trampoline (all 12 ops); imported resources; live component imports; structured verdicts; canonical world digest handshake (`contracts/digest.md`); typed TS facades for fixture worlds. Multi-agent per `AGENTS.md`: 3 parallel tracks, 2 reviewer rounds (5 blocking findings fixed), interrupted mid-flight by a driver restart and recovered via task_id resumes. |
17-
| M2 | **Concurrency complete on Deno** | **DONE** (2026-08-08, exit review APPROVE-WITH-NITS at 652c1dc). JSPI auto-detection ON by default; **1250/1349 executing suite commands pass, zero failures, every one of the 99 xfails in a named class** (47 wasmparser pin-drift → exits on the wasmtime bump, [#1](https://github.com/lann/deltic/issues/1); 41 🧵-deferred cascades, [#12](https://github.com/lann/deltic/issues/12); 5 shim gaps + 6 small named residues, [#13](https://github.com/lann/deltic/issues/13)). Delivered: the 0.3 task core, callback ABI, FACT cross-component calls (all four ABI combos), streams/futures/error-context with full rendezvous, host-side ends, cross-component cancellation, JSPI stackful+blocking paths with per-declaration suspendability, instance poisoning, deadlock detection with wasmtime-exact wording. wit-bindgen async roundtrip trio + producer guests green. Empirical engine pins (a)–(j) incl. "the fast path still suspends"; five JSPI host constraints recorded in `contracts/intrinsics.md`; two wasmtime-supersedes-reference findings (CM-3, CM-4) + NOTE-1 tracked upstream. Plain path pinned zero-cost for sync-only components. |
17+
| M2 | **Concurrency complete on Deno** | **DONE** (2026-08-08, exit review APPROVE-WITH-NITS at 652c1dc). JSPI auto-detection ON by default; **1250/1349 executing suite commands pass, zero failures, every one of the 99 xfails in a named class** (47 wasmparser pin-drift → exits on the wasmtime bump, [#1](https://github.com/lann/deltic/issues/1); 41 🧵-deferred cascades, [#12](https://github.com/lann/deltic/issues/12); 5 shim gaps + 6 small named residues, [#13](https://github.com/lann/deltic/issues/13)). Delivered: the 0.3 task core, callback ABI, FACT cross-component calls (all four ABI combos), streams/futures/error-context with full rendezvous, host-side ends, cross-component cancellation, JSPI stackful+blocking paths with per-declaration suspendability, instance poisoning, deadlock detection with wasmtime-exact wording. wit-bindgen async roundtrip trio + producer guests green. Empirical engine pins (a)–(j) incl. "the fast path still suspends"; five JSPI host constraints recorded in `contracts/intrinsics.md`; two wasmtime-supersedes-reference findings (CM-3, CM-4) + NOTE-1 tracked upstream (CM-4 recharacterized 2026-08-10 — wasmtime holds the gate and defers the entry decision; runtime migration [#43](https://github.com/lann/deltic/issues/43); see findings tracker). Plain path pinned zero-cost for sync-only components. |
1818
| M3 | Cross-engine | **Substantially done** (2026-08-09). Browser lanes over the full 1395-command corpus via `deno bundle` + playwright, per-lane expectation overlays with stale-delta detection (Deno's xfail.ts untouched): **Chromium at exact Deno parity (1250/0/99/41/5, deltas [])**; Firefox green behind the JSPI pref with ONE variance (trap message text — SpiderMonkey wording; explicitly tolerated per architecture.md §1); WebKit (WPE 26.5) capped by **JSC lacking multi-memory** (58 compile failures + cascades — engine gap; notable: its JSPI works UNFLAGGED — [#11](https://github.com/lann/deltic/issues/11)). En route: **M3A-1** — the scheduler's ambient rode `node:async_hooks`, invisible on Deno, fatal in every browser; replaced by explicit ambient threading (differentially verified to zero disagreement over the corpus), pinned by `platform_purity_test.ts`. Artifact cache (architecture.md §10 layer 1) landed: content-addressed by component sha × translator-wasm sha × features, dir + Cache API backends, instantiate-from-cache proven. Residuals became issues: CI service [#6](https://github.com/lann/deltic/issues/6); code-cache empirical check + in-browser webCache exercise [#7](https://github.com/lann/deltic/issues/7). |
1919
| C0 | **Consumer smoke test** ([consumers.md](consumers.md)) | **DONE** (2026-08-09, `tools/smoke-c0/` + REPORT.md). Real consumer artifacts under deltic on Deno with throwaway glue: experiment-mosh's `compose-async-tdz` repro green (pins the lann/jco#51 shape — `ok(42)` through 2 FACT adapters); iroh's `exec-model` probe green including the jco#11 kill shot (later export calls against a live detached pump); websocket conformance suite translated (first shim contact). Found and fixed two runtime defects no corpus reached (R-1 host-pump starvation of `pendingHostCalls`; R-2 check-then-act poisoning via `hostFailure`) — fail-on-pre-fix pins added. Translator throughput on multi-MB componentize-go artifacts: 10.5 MB in 73 ms warm, 9/9 accepted, zero rejections. Pin-bump ruling: deferred (observed drift was consumer-side WIT drift, not wasmtime drift) — staged as [#1](https://github.com/lann/deltic/issues/1). Deno capability audit: WebRTC verified via `tools/probes/webrtc-deno/`. |
2020
| C1 | Embedder conventions design — `contracts/embedder-api.md` | **DONE** (2026-08-08, v0.1). All open sub-questions decided: branded `WitError` throw model (unbranded host throw = trap — the anti-jco-footgun inversion); `{tag, val}` variant family covering nested options and results-as-values; outermost-option-as-undefined rule; exports uniformly Promise-shaped; resource classes both directions with runtime-owned identity mapping; `Stream<T>`/`Future<T>` handles over web-native producers with auto-closing pumps; **semver-canonical version resolution** matching the spec's canonical-interface-names design and wasmtime's `NameMap`/`alternate_lookup_key` (exact-first, track-alternate max-wins, prerelease/`0.0.z` exact-only; unversioned folding stays banned — corrected same-day from an initial version-exact-only ruling after reviewing the spec and wasmtime's linker); `requiredImports()` blessed. **WASI examined as ruled**: paper signatures for wasi:clocks p3, wasi:io p2 (pollable/streams — the one real friction, p2 sync-blocking, gets a three-tier strategy grounded in C0 finding #6), wasi:sockets p3 TCP, wasi:http p3 sketch, and webrtc data-channel; verdict — no new conventions needed. Superseded descriptor-ir's interim table. |

exams/wasmtime-exclusivity/RESULTS.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,22 @@
11
# wasmtime exclusivity check — is the sync-streams pass deterministic?
22

3+
> **CORRECTION (2026-08-10) — see `wasmtime-actual-semantics.md`, which
4+
> supersedes this file's wasmtime claims.** Source + trace verification
5+
> against wasmtime main (and v47.0.3) shows wasmtime does **not** release
6+
> its entry gate at resolution: `do_not_enter` is held for the whole core
7+
> invocation (same lifetime as the reference's `exclusive_thread`), across
8+
> post-`task.return` mid-frame parks included. Its sync-streams pass comes
9+
> from **deferred entry evaluation + FIFO scheduling**: the async caller
10+
> suspends until the first status event, the ready-parked `$C.get` runs to
11+
> *exit* first, and `$C.set` is admitted only after `get` is deleted — no
12+
> same-instance execution ever overlaps the parked span. Consequently: the
13+
> "STARTED while a resolved task sits parked mid-frame" reading of the
14+
> official test below is wrong for wasmtime; §"What the official test
15+
> already demonstrates" item 3 and the "one true scheduling accident"
16+
> section describe the **release-rule** (deltic/fix-patch) execution, not
17+
> wasmtime's. The determinism measurement (50/50) and the CI-provenance
18+
> analysis stand.
19+
320
Evidence backing `upstream-component-model-repo-findings.md` CM-4's
421
2026-08-09 review and the IROH-1 consumer finding. Question posed by the
522
operator: wasmtime runs the official CM test suite — is *its* pass on the

exams/wasmtime-exclusivity/root-cause.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
# CM-4 root cause: the reference's unit tests pin the semantics its wast suite contradicts
22

3+
> **CORRECTION (2026-08-10) — see `wasmtime-actual-semantics.md`.** This
4+
> file's reference-side traces are accurate, but its framing of
5+
> `cm4-reference-fix.patch` as "the wasmtime/deltic rule" is wrong:
6+
> release-at-resolution is **deltic's** rule only. wasmtime holds its gate
7+
> for the whole invocation (like pristine `definitions.py`) and passes the
8+
> wast suite via deferred entry evaluation — under wasmtime's actual
9+
> semantics `test_callback_interleaving` passes **unchanged**, so the
10+
> "irreconcilable" verdict below applies to the release-rule fix, not to
11+
> wasmtime alignment. Likewise `test_resolved_task_gates_entry`'s
12+
> shared-state assertions (`poke_saw == 1`, `pump_observed == 2`) encode
13+
> the release rule: under wasmtime's model poke is deferred until pump's
14+
> invocation exits. The wasmtime-aligned reference fix is an entry-timing
15+
> change in `canon_lower` (report STARTING only after the instance's
16+
> runnable work is exhausted), not a gate-lifetime change.
17+
318
Companion to `RESULTS.md`; produced while building the filing artifacts
419
(`cm4-run-tests.patch`, `cm4-reference-fix.patch`). Line numbers are
520
pristine `run_tests.py` / `definitions.py` at submodule `73b7ad5`.

0 commit comments

Comments
 (0)