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:
- 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.
- 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.
The gap
meld fusepreserves 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--invokeon 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.
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:analyze: func(module-bytes: list<u8>, config: analysis-config) -> result<analysis-result, analyze-error>— 2 component-level paramslist<u8>→ ptr+len and the record into scalars)So kiln can resolve
analyzebut cannot lower arguments for it: constructing alist<u8>requires allocating guest memory viacabi_reallocand 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:
component-type*custom sections. This is the standardwit-bindgenconvention for embedding WIT in a core module, sowasm-tools component witand any runtime already know how to read it. If fusion invalidates the original sections, re-emit one describing the fused module's exported interface.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.