Skip to content

Fused core modules drop WIT type info (component-type* sections) — runtimes can't invoke typed exports #400

Description

@avrabe

The gap

meld fuse preserves the export names beautifully — the fused core module exports each component export under its canonical WIT name, e.g. pulseengine:scry/analyzer@0.1.0#analyze. That's what let kiln wire up --invoke on the fused-core path with no new contract (kiln SR-58), and it's genuinely the right design.

But the fused module carries no WIT type information, so a runtime can resolve the export and still not know how to call it.

$ wasm-tools component wit scry.core.wasm
error: input is a core wasm module with no `component-type*` custom sections
       meaning that there is not WIT information

Custom sections in the fused output are only: .debug_*, producers, target_features, wsc.transformation.attestation, component-provenance (function→originating-component attribution, not types).

Why it matters

Verified with the real released scry-3.3.0-wasm32-wasip2.wasm (pulseengine/scry) fused with meld 0.41.3:

  • WIT signature: analyze: func(module-bytes: list<u8>, config: analysis-config) -> result<analysis-result, analyze-error>2 component-level params
  • What a runtime sees on the fused module: a core function taking 10 flattened i32s (the canonical ABI flattens list<u8> → ptr+len and the record into scalars)

So kiln can resolve analyze but cannot lower arguments for it: constructing a list<u8> requires allocating guest memory via cabi_realloc and writing bytes, which needs the types. Without them the only honest behaviour is to refuse (which kiln now does — it fails loud rather than zero-filling the 10 params and fabricating a result).

Concretely this blocks running pulseengine's own wasm-only tools through a layer's kilnd — scry is a library/reactor component, so "invoke a named export with typed args" is the only way to use it.

Ask

Preserve or emit the WIT types in fused output, so a runtime can lower typed arguments:

  1. Preferred — keep the component-type* custom sections. This is the standard wit-bindgen convention for embedding WIT in a core module, so wasm-tools component wit and any runtime already know how to read it. If fusion invalidates the original sections, re-emit one describing the fused module's exported interface.
  2. Or emit a compact signature manifest (custom section / sidecar) mapping each exported canonical name → its WIT signature.

Either way the contract stays where it already works well: meld owns lowering and records what it produced; the runtime consumes it.

Happy to consume whichever shape you pick on the kiln side — tracked there as SR-59.

Context: kiln issue #480; kiln SR-57/SR-58 landed by consuming meld's canonical export names, which worked exactly as hoped.

🤖 Filed per report-tool-friction from kiln v0.5.0 planning.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions