11# Workflow Runtime WIT
22
3- This directory defines the canonical high-level workflow guest interface for the future WASM SDK.
3+ This directory defines ` temporal:workflow-runtime@0.1.0 ` , the high-level guest interface that
4+ workflow code targets when it is compiled to a WebAssembly component. It is intentionally separate
5+ from the core activation/completion protocol that worker SDKs speak to the Temporal cluster: core
6+ remains the worker-facing protocol, and a worker is responsible for translating core activations
7+ and completions into calls against this interface.
8+
9+ ## What's in here
10+
11+ - ` world.wit ` — the ` workflow-module ` world: imports ` workflow-host ` , exports ` workflow-guest ` .
12+ - ` guest.wit ` — ` workflow-guest ` : the entry points the guest exports for the host to drive
13+ (` list-workflows ` , ` instantiate-workflow ` , and the ` workflow-instance ` resource with ` activate `
14+ and ` poll-routine ` ).
15+ - ` host.wit ` — ` workflow-host ` : the host capabilities the guest imports (e.g. ` set-current-details ` ,
16+ ` push-command ` ).
17+ - ` types.wit ` — shared records and variants used by both sides (init/activation/completion shapes,
18+ routine kinds, terminal outcomes, etc.). Some fields are typed as ` list<u8> ` and carry encoded
19+ protobuf messages — those proto schemas are part of the ABI; see * Stability* below.
20+
21+ ## How a workflow runs against it
22+
23+ 1 . The host instantiates a workflow run by calling ` instantiate-workflow ` with ` workflow-init ` .
24+ 2 . For each activation, the host calls ` activate ` on the ` workflow-instance ` resource. The guest
25+ processes the activation's jobs and reports per-job results (started routines, query responses,
26+ update rejections).
27+ 3 . The guest drives its routines (main, signals, updates) by being polled — the host calls
28+ ` poll-routine(routine-id) ` until the routine either completes or reports it made no progress.
29+ 4 . While running, the guest invokes host functions to push commands and update execution state.
30+
31+ The guest interface is deliberately higher-level than core's activation protocol: ordering rules
32+ and worker bookkeeping live in the host translation layer, not in the guest contract.
433
5- This is intentionally ** not** the existing core activation/completion protocol. Core remains the
6- worker-facing protocol for the foreseeable future, and other language SDKs will continue to use it.
7- The Rust worker will translate core activations and completions into this higher-level interface.
8-
9- ## Why this lives in ` temporalio-workflow `
10-
11- ` temporalio-workflow ` is the crate that workflow implementations compile against. Checking the WIT
12- in here gives the Rust runtime refactor a concrete target:
13-
14- - ` temporalio_workflow::runtime::* ` should evolve toward a direct Rust mirror of these interfaces.
15- - The native Rust worker should keep calling those Rust traits directly, with no WIT serialization
16- in the hot path.
17- - A future WASM backend should expose the same interface through the component model.
18-
19- ## Layering
20-
21- The layers are:
22-
23- 1 . Core activation/completion protocol
24- 2 . Native worker translation layer
25- 3 . This WIT-shaped workflow runtime interface
26- 4 . Workflow guest code
27-
28- That translation layer is where activation ordering and other core-specific details stay hidden.
29- The guest interface here is deliberately higher level:
30-
31- - the host instantiates a workflow run
32- - the host applies activation-wide context
33- - the host notifies signals, cancellation, patches, updates, and operation resolutions
34- - the guest polls until it blocks or terminates
34+ ## Synchronous ABI and the WASIp3 future
3535
36- ## Native and WASM execution
36+ The guest interface is synchronous: ` activate ` and ` poll-routine ` return ordinary results, and a
37+ routine signals "blocked" by returning ` routine-poll-result.made-progress = false ` . The host
38+ re-enters ` poll-routine ` after the relevant activation lands. This shape is what stable Wasmtime
39+ and ` wit-bindgen ` support today.
3740
38- The runtime should support two backends behind the same worker translation logic :
41+ When component-model async (WASIp3 / Preview 3) is stable in Wasmtime, the natural evolution is :
3942
40- - a native backend that invokes Rust traits directly in-process
41- - a WASM backend that invokes a component implementing ` workflow-module `
43+ - ` activate ` and ` poll-routine ` become ` async func ` .
44+ - ` routine-poll-result.made-progress ` and the explicit ` routine-id ` -keyed polling protocol can
45+ go away — the host can ` await ` each routine directly.
4246
43- The goal is one logical execution model with two transport backends, not two independent workers .
47+ That is a breaking ABI change and will require a major-version WIT bump .
4448
4549## Stability
4650
47- The package is published as ` temporal:workflow-runtime@0.1.0 ` and is ** not yet stable** . Until
48- this is bumped to ` 1.0.0 ` any release may bump the minor version with breaking changes. Once
49- external SDKs (Python, TypeScript, Go, etc.) begin compiling guest workflows against this WIT,
50- breaking changes need to follow normal SemVer discipline: bump the package version, dual-export
51- the old and new world from the host for a deprecation window, and document the migration path.
51+ The package is published as ` temporal:workflow-runtime@0.1.0 ` and is ** not yet stable** . Until it
52+ is bumped to ` 1.0.0 ` , any release may bump the minor version with breaking changes. Once external
53+ SDKs (Python, TypeScript, Go, etc.) begin compiling guest workflows against this WIT, breaking
54+ changes need to follow normal SemVer discipline: bump the package version, dual-export the old
55+ and new world from the host for a deprecation window, and document the migration path.
5256
5357Changes that force a major bump include:
5458
@@ -57,21 +61,3 @@ Changes that force a major bump include:
5761- Reordering variant cases (the discriminant order is part of the ABI).
5862- Changing the proto messages encoded into ` list<u8> ` -typed fields (` failure ` , ` payload ` ,
5963 ` workflow-command ` , ` workflow-activation ` , ` continue-as-new-request ` ).
60-
61- ## Synchronous ABI and the WASIp3 future
62-
63- The current guest interface is intentionally synchronous: ` activate ` and ` poll-routine ` both
64- return ordinary results, and the guest is expected to suspend by returning
65- ` routine-poll-result.made-progress = false ` . The host then re-enters ` poll-routine ` after the
66- relevant activation lands.
67-
68- This shape is what stable Wasmtime + ` wit-bindgen ` support today. When component-model async
69- (WASIp3 / Preview 3) lands as stable in Wasmtime, the natural evolution is:
70-
71- - ` activate ` and ` poll-routine ` become ` async func ` .
72- - ` routine-poll-result.made-progress ` and the explicit ` routine-id ` -keyed polling protocol
73- likely go away — the host can just ` await ` each routine directly.
74-
75- That is a breaking ABI change, so it will require a major-version WIT bump. Any other-language
76- SDK that ships a guest implementation should expect to regenerate bindings against the new
77- world at that point.
0 commit comments