From 2a66d67f56366d68f479f3835f736aa1016c36ff Mon Sep 17 00:00:00 2001 From: Lann Martin Date: Thu, 20 Aug 2026 19:53:40 -0400 Subject: [PATCH] =?UTF-8?q?docs:=20adjudicate=20#165=20=E2=80=94=20enter-s?= =?UTF-8?q?ync-call's=20unbracketed=20gate=20is=20accepted?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Named divergence recorded in architecture.md §6: the enter_from/leave_to bracket around FACT sync guest→guest calls stays omitted (host-mediated reentry admitted where the pinned reference traps). Grounds: wasmtime parity, the bracket would reintroduce the await-spanning-lock class removed by #156/#160, and upstream CM PR 705 removes the may_enter flag/trap outright — the divergence is a trailing indicator of that removal and self-resolves at the pin advance (migration map: #173). The code comment at the enter-sync-call gate now cites the adjudication instead of reporting the omission as an open hole. Comment/docs only; gate: just test-runtime (516/0). --- docs/architecture.md | 28 ++++++++++++++++++++++++++++ runtime/src/intrinsics/mod.ts | 20 ++++++++++++++------ 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/docs/architecture.md b/docs/architecture.md index fd8f34c..a456cdc 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -380,6 +380,34 @@ the site (`runtime/src/intrinsics/async_builtins.ts`, the determinacy park in `createSubtaskCancel`); regression pinned across seeds by `runtime/tests/cancel_bracket_race_test.ts`. +Named divergence (2026-08-20, [#165](https://github.com/lann/deltic/issues/165), +adjudicated-accept): **`enter-sync-call` checks the callee's reentrance gate +but does not take it.** A FACT sync guest→guest call performs the +reference's `trap_if(not may_enter_from(caller))` and stops — the +`enter_from`/`leave_to` bracket around the call body (`Store.lift`, +definitions.py:578-585) is deliberately omitted, so *host-mediated* reentry +into the callee while the call is in flight (host → A.f → C.g → host import +→ host re-enters C.g) is admitted where the pinned reference traps. Pure +guest→guest cycles remain statically impossible (FACT compile-time traps; +the instance-import DAG, [#99](https://github.com/lann/deltic/issues/99)/ +[#101](https://github.com/lann/deltic/issues/101)). Accepted on three +grounds: **wasmtime parity** (`enter_guest_sync_call` performs no reentrance +check at all, and fused adapters elide it); **architecture** — taking the +bracket would create a guest→guest lock spanning suspension points, +reintroducing the await-spanning-lock class that +[#156](https://github.com/lann/deltic/issues/156)/[#160](https://github.com/lann/deltic/issues/160) +eliminated; and **upstream trajectory** — CM PR +[#705](https://github.com/WebAssembly/component-model/pull/705) ("CABI: +remove the may_enter flag/trap") deletes the trap from the `canon lift`, +`resource.drop`, and `subtask.cancel` paths and makes previously-trapping +reentrance valid, retaining only run-to-completion serialization of async +callback turns. This divergence is therefore a trailing indicator of the +upstream removal and self-resolves when the submodule pin advances past +#705; the pin-advance migration map is +[#173](https://github.com/lann/deltic/issues/173). Until that advance the +pinned definitions.py remains the tie-breaker everywhere else — every +reentrance check deltic does enforce stays in force. + ## 7. Canonical ABI decisions Authority: [CanonicalABI.md] and its executable reference diff --git a/runtime/src/intrinsics/mod.ts b/runtime/src/intrinsics/mod.ts index ef92640..36389e7 100644 --- a/runtime/src/intrinsics/mod.ts +++ b/runtime/src/intrinsics/mod.ts @@ -514,12 +514,20 @@ function createTrampolineBody( // Deliberately *not* done here: `enter_from` / `leave_to` around the // bracket. The reference locks the callee for the duration, which // would additionally trap host-mediated reentrance (host -> A.f -> - // C.g -> host import -> host invokes C.g). Doing it needs the trap / - // capability-signal distinction that only `exec/boundary.ts` has - // (a `NeedsJspi` bail out of a sync callee skips `exit-sync-call` - // and would poison a healthy instance), and the general form of that - // hole is the missing `ComponentInstance.parent` chain already - // recorded in `task/mod.ts` `enteringSet`. Reported, not smuggled in. + // C.g -> host import -> host invokes C.g). + // + // ADJUDICATED 2026-08-20 (deltic#165; named divergence in + // docs/architecture.md section 6): accepted — the bracket stays + // omitted. Three grounds: wasmtime parity (`enter_guest_sync_call` + // checks nothing); taking the bracket would create a guest-to-guest + // lock spanning suspension points, reintroducing the await-spanning + // -lock class removed by #156/#160; and upstream is deleting the + // trap outright — CM PR #705 ("CABI: remove the may_enter + // flag/trap") makes previously-trapping reentrance valid, so this + // divergence is a trailing indicator of the removal and + // self-resolves at the submodule pin advance (migration map: + // deltic#173). Until that pin advance the reference's checks deltic + // DOES enforce stay in force. if ( typeof callerInstance === "number" && typeof calleeInstance === "number"