Skip to content

refactor(actor): finish the Ffi→Wasm guest sdk rename #2090

@iamacoffeepot

Description

@iamacoffeepot

Description

Finish the Ffi→Wasm guest SDK rename. #2089 renamed the headline guest-facing types (FfiCtxWasmCtx, FfiActorWasmActor, etc.) but left a tail of Ffi-named symbols and the ffi/ module itself, leaving Wasm* types living in a module named ffi. Commit to the wasm framing: the guest binding is wasm-specific (wasm32 is the only host), so retire the issue-663 generic-host naming for the SDK surface while keeping the literal-FFI names at the actual extern "C" boundary.

Touches crates/aether-actor/src/ffi/ (the guest SDK module) and the *FfiExt traits in crates/aether-capabilities/. Concrete residue to move to Wasm:

  • ErasedFfiActorErasedWasmActor (the boxed dual of WasmActor; public, re-exported from aether-actor/src/lib.rs).
  • ComponentHostFfiExtComponentHostWasmExt (aether-capabilities/src/component.rs), TcpFfiExtTcpWasmExt (aether-capabilities/src/tcp/mod.rs).
  • Module aether-actor/src/ffi/src/wasm/, plus every crate::ffi:: path and the module-doc framing in ffi/mod.rs.
  • Dead FfiTransport doc comments (the ZST was deleted in issue 665) — ffi/mod.rs, ffi/ctx.rs, ffi/bridge/mod.rs.
  • trybuild UI fixtures aether-actor-derive/tests/ui/*_ffi.rs (+ .stderr) and the ui.rs references.

Explicitly keep the literal-FFI names: ffi/raw.rs's extern "C" imports, the _p32 ABI suffix, the "Raw FFI boundary" comments, and the on-the-wire ABI symbol names (receive_p32, aether.kinds.inputs, aether.namespace) — that boundary is genuinely a foreign-function interface and is an on-the-wire contract the substrate's wasm runtime expects.

Mechanical, no behavior change. Spans aether-actor (primary), aether-actor-derive, and aether-capabilities; ADR/guide mentions of the old names update alongside.

Problem statement

#2089 renamed the headline guest-SDK types to Wasm* (WasmCtx, WasmInitCtx, WasmDropCtx, WasmActorMailbox, and the WasmActor trait) but stopped short of the tail: ErasedFfiActor, the *FfiExt extension traits, the aether-actor/src/ffi/ module itself, dead FfiTransport doc comments, and *_ffi.rs trybuild fixtures still carry the old prefix. The result is incoherent — Wasm* types live in a pub mod ffi whose own header documents ffi as a deliberately generic-over-hosts name (issue 663), directly contradicting the wasm-specific direction #2089 chose.

Done means: the guest-SDK surface is uniformly Wasm* and lives in aether_actor::wasm; the only remaining Ffi/FFI names are the ones that describe the literal extern "C"/_p32 foreign-function boundary in wasm/raw.rs, which are accurate and an on-the-wire contract. No behavior change — cargo nextest, clippy, and the wasm32 component cross-build stay green, and the wire ABI symbol names (receive_p32, init, aether.kinds.inputs, aether.namespace) are untouched.

Design notes

Chosen approach

Commit to the wasm framing for the guest binding (decided with the user): wasm32 is the only host today, so the SDK module and its types name that reality. Three symbol renames plus one module rename, driven by RustRover rename_refactoring so cross-crate references move atomically:

  • ErasedFfiActorErasedWasmActor — the object-safe boxed dual of WasmActor; public (re-exported from aether-actor/src/lib.rs) and emitted by the #[actor] macro in aether-actor-derive, so the derive output moves in the same change.
  • ComponentHostFfiExtComponentHostWasmExt, TcpFfiExtTcpWasmExt — these pair with existing *NativeExt duals, so WasmExt/NativeExt keeps the same wasm-vs-native transport axis the WasmActorMailbox/NativeActorMailbox split already uses.
  • Module aether-actor/src/ffi/src/wasm/ (pub mod ffipub mod wasm), updating every crate::ffi:: path and the cross-crate aether_actor::ffi:: references in aether-capabilities and aether-substrate. aether_actor::wasm does not collide with aether_substrate::actor::wasm — different crates, and both naming the wasm side is the intended outcome.

Rewrite the wasm/mod.rs header to state the present design (the wasm guest binding) with no "used to be ffi/wasm" narrative. Keep every literal-FFI name in wasm/raw.rs (the extern "C" imports, _p32 suffix, "Raw FFI boundary" comments) and the wire ABI symbol names — that boundary genuinely is FFI. Delete the three stale FfiTransport doc comments (the ZST died in issue 665). Rename the six *_ffi.rs trybuild fixtures + .stderr siblings to *_wasm.rs and update ui.rs (lowest-priority cosmetic tail; fold in for uniformity).

Rejected options

  • Keep ffi as a generic-host binding layer (issue-663 stance) — would make ErasedFfiActor/*FfiExt correct again and reframe refactor(actor): rename the Ffi guest sdk types to Wasm #2089 as the regression. Rejected: the user explicitly chose the wasm direction; the only host is wasm32.
  • Split into two PRs (symbol renames vs module rename) — each compiles independently, so it is technically separable. Rejected: both are small, mechanical, and tightly related; one atomic rename is the cleaner review unit and avoids a transient half-renamed main.
  • Also rename wasm/raw.rs's FFI names — rejected: that boundary is a literal foreign-function interface and the _p32/symbol names are an on-the-wire contract the substrate's wasm runtime expects.

Affected surfaces

  • aether-actor (primary): pub mod ffiwasm, ErasedFfiActor trait + all internal crate::ffi:: paths, lib.rs re-exports and module docs.
  • aether-actor-derive: #[actor] macro output emitting ErasedFfiActor + the six tests/ui/*_ffi.rs fixtures/.stderr/ui.rs.
  • aether-capabilities: ComponentHostFfiExt/TcpFfiExt traits + the use aether_actor::ffi::inline::InlineRegistry path.
  • aether-substrate: doc-comment references to aether_actor::ffi::*.
  • Docs: ADR/guide mentions of the old module path and ErasedFfiActor.
  • No wire-format, no public-behavior, no ABI-symbol change.

Implementation plan

Drive the renames with RustRover rename_refactoring (per [[feedback_use_rustrover_mcp_for_code_work]]) so cross-crate references update atomically; do the module/file moves with git mv.

  1. Rename ErasedFfiActorErasedWasmActor — RustRover rename on the trait def in aether-actor/src/ffi/mod.rs; propagates to the lib.rs re-export, the #[actor] macro emission in aether-actor-derive/src/lib.rs, all impl ErasedFfiActor sites, and doc-comment mentions (incl. the two in aether-test-fixtures/bundle/src/stateful_replace.rs and tests/test_bench_scenario.rs). — coverage: existing cargo nextest run --workspace + the trybuild UI suite.
  2. Rename *FfiExt*WasmExt — RustRover rename ComponentHostFfiExtComponentHostWasmExt (aether-capabilities/src/component.rs) and TcpFfiExtTcpWasmExt (aether-capabilities/src/tcp/mod.rs), including their rustdoc intra-links and the input.rs doc reference. — coverage: aether-capabilities unit tests + clippy doc-link lint.
  3. Move module ffi/wasm/git mv crates/aether-actor/src/ffi crates/aether-actor/src/wasm; change pub mod ffipub mod wasm in lib.rs; update every crate::ffi:: path inside aether-actor and the cross-crate aether_actor::ffi:: references in aether-capabilities/src/component.rs:560 and the aether-substrate doc comments. Rewrite the wasm/mod.rs header to present-tense wasm framing (drop the issue-663 generic-host narrative per [[feedback_no_project_history_in_reader_docs]]). — coverage: cargo check --workspace + wasm32 component cross-build.
  4. Delete dead FfiTransport doc commentswasm/mod.rs:70, wasm/ctx.rs:14-15, wasm/bridge/mod.rs:5 (ZST removed in issue 665). — coverage: doc build.
  5. Rename trybuild fixturesgit mv the six aether-actor-derive/tests/ui/*_ffi.rs + their .stderr siblings to *_wasm.rs; update the six ui.rs references. Run TRYBUILD=overwrite cargo test -p aether-actor-derive only if any diagnostic text shifted (the filename change alone does not). — coverage: the trybuild UI suite itself.
  6. Sweep docs — update ADR/guide mentions of ErasedFfiActor and the aether_actor::ffi module path (grep docs/ for ffi/ErasedFfiActor). Keep ADR-0101's title slug (0101-replace-hooks-on-ffiactor.md) as-is — an ADR filename is a historical identifier. — coverage: mdbook build in CI.
  7. Preflightscripts/preflight.sh (fmt + clippy -D warnings + doc + nextest + wasm32 cross-build) per [[feedback_delegated_validation_must_be_full_preflight]].

Single PR — the renames are one atomic concept and the module rename breaks dependents unless they move together; not logically separable into shippable units.

Size: M — dominant crate is aether-actor with mechanical ripple into three others, well under 500 LOC, no architectural judgment. Model: sonnet — fully specified, tool-driven mechanical rename; the only non-trivial step is the conditional trybuild stderr regen, which the plan names explicitly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    crate:actoraether-actor (host actor framework)model:sonnetRequired dispatch model — set by /scope at Plan (fable = human pin only)size:mEstimated size — set by /scope at Plantype:refactorRestructure with no behavior change

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions