Expand description
The composed component runtime — the ONLY composition surface embedding applications touch (scaffold-unification design, §5.2, finding B6).
§Why this wrapper exists (the composition story)
Before this module, every embedding host — frame-host’s runtime.rs and
every frame new scaffold in the wild — hand-wrote the same five beamr
compositions, each of which hides a trap:
- Scheduler composition. A bare
Scheduler::with_servicessilently installs an EMPTY built-in-function registry, so everyerlang:*import in hot-loaded bytecode resolves Deferred and guard-BIF dispatch kills the process at its first arithmetic instruction withInvalidOperand("guard bif native import")— the composition defect attributed inframe-host/attribution/gcbif-wedge/(Artemis’s 2026-07-18 probe report, Round 2).ComponentRuntime::composeabsorbs the fix,crate::composition::compose_scheduler: gate-1 BIF population BEFORE construction, so load-time import resolution bindserlang:*to Native entries. - Support-module hot load. A component’s FFI bytecode is hot-loaded
directly on the scheduler, outside the registry’s lifecycle — and the
registry’s deferred-BIF wall did not cover it.
ComponentRuntime::load_support_moduleapplies the same wall (the crate-internalcomposition::deferred_erlang_importsscan both paths share) and returns an opaqueSupportModuleHandleinstead of a beamr atom. - Support-module unload. The correct teardown is a dance: purge any
retained old generation, delete the current one, then VERIFY the module
is actually gone.
ComponentRuntime::unload_support_moduleperforms and verifies it; the single-use handle makes a double unload unrepresentable. - Mailbox acknowledgement values. BEAM mailbox integers must fit the
small-integer term payload, and the low integers are usually claimed by
a child’s message protocol (liveness, stop). Deriving an
acknowledgement from identifier bytes therefore means folding into
reserved_below ..= Term::SMALL_INT_MAX— previously hand-rolled againstTerm::SMALL_INT_MAXin generated code, nowmailbox_integer. - Teardown discipline.
Scheduler::shutdownis not cleanup: ordered stop must have drained every process tree first.ComponentRuntime::shutdownrefuses whileComponentRuntime::live_process_countis nonzero.
Zero beamr types appear in this module’s public signatures: bytecode is
&[u8], modules are opaque handles, mailbox messages are the i64 the
registry already speaks. The runtime’s beamr dependency (and its feature
selection) is therefore declared in exactly one place — frame-core’s own
manifest — instead of being fossilized into every generated application
(finding B6). crate::composition remains public as the wrapper’s
ground truth for embedders that need raw scheduler access; applications
and frame-host itself compose only through this module.
Structs§
- Component
Runtime - The composed component runtime: scheduler + registry, correctly assembled.
- Runtime
Policy - Stated-by-the-application runtime policy. No field has a default: frame supplies no lifecycle values, so the embedding application declares each one explicitly.
- Support
Module Handle - Opaque, single-use handle to a loaded support module.
- Support
Module Ref - A cloneable reference to a loaded support module’s NAME, for hot swaps. Carries no unload authority.
- Support
Swapper - A
Send + Synchandle for hot-swapping support modules from the management adapter’s thread (the F-7b dev reload’s FFI leg).
Enums§
- Runtime
Error - A typed refusal or failure from
crate::runtime::ComponentRuntimeorcrate::runtime::mailbox_integer.
Functions§
- mailbox_
integer - Folds identifier bytes into a valid mailbox integer above a reserved range.