@@ -47,7 +47,11 @@ host-import settlements are serviced by a settlement pump while no export
4747call is in flight, so background tasks parked on host-call wakeups (clocks,
4848fetches) progress without embedder traffic — embedder-never-acts operations
4949still hang (never trap) and failures still surface on the next driving
50- call.**
50+ call; amendment A12 (2026-08-12) makes result-position future sources
51+ normative for imports: an import whose WIT result type is ` future<T> `
52+ treats a thenable return as the FUTURE SOURCE (the import completes
53+ immediately; the future settles on the producer's schedule) — see
54+ §"Streams and futures".**
5155This document supersedes ` descriptor-ir.md ` 's interim
5256"host value mapping" table as the destination for host-facing value shapes.
5357The runtime's * raw* boundary (` instance.exports ` , ` HostImports ` ) keeps the
@@ -469,6 +473,26 @@ class DroppedError extends Error { … } // awaiting a dropped future rejects
469473 deadlock-masking activity-lifetime footgun — R-fix review note 2), and
470474 cross-store reuse is a runtime-asserted error, not silent misbehavior
471475 (note 3).
476+ - ** An import whose WIT result type is ` future<T> ` returns the future
477+ source** (amendment A12, 2026-08-12). A thenable returned by the host
478+ method — a ` Promise<T> ` or a ` Future<T> ` handle — is lowered as the
479+ future itself: the import call completes immediately, and the future
480+ settles on the producer's schedule. It is ** not** adopted as the call's
481+ async completion (the pre-A12 dispatch behavior, under which a sync-typed
482+ import returning a Promise was a JSPI park request — and under which a
483+ ` Future ` handle, being ` PromiseLike ` , was silently awaited and
484+ re-lowered). The natural spelling of the ` wasi:sockets@0.3 ` TCP ` send `
485+ shape — ` send: func(data: stream<u8>) -> future<result<_, error-code>> `
486+ as an ` async ` JS method whose promise resolves when transmission
487+ completes — depends on this: the future settles only after post-return
488+ guest action (the guest writes ` data ` after ` send ` returns), so adopting
489+ the thenable is a livelock, not a semantics choice. A ** rejected**
490+ future-source promise stays a producer failure on the host-failure
491+ channel (site-named, surfacing on the consuming call — same as every
492+ producer), never a guest-visible err value: a fallible payload rides
493+ * inside* the future (` future<result<…>> ` ), resolved as a result value.
494+ Executable spec: ` examples/guests/future-import ` +
495+ ` runtime/tests/embedder/future_result_test.ts ` .
472496- ** Stream values survive round trips** (amendment A5). A ` stream ` /` future `
473497 is an identity: lifting one that the host already handled — a
474498 host-created stream a guest passed back (result or import position), or
0 commit comments