[GH-ISSUE #2350] [Feature] Inspect WebAssembly components and canonical ABI declarations offline #775

Open
opened 2026-10-15 18:28:15 +00:00 by bsakaguchi · 1 comment
Owner

Originally created by @matbrgz on GitHub (Oct 12, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/2350

Type: Feature Domain: Reverse Engineering Status: Proposed Ecosystem: REA

Analyst question and current scope

The shipped offline WASM lane is documented around WABT 1.0.42 and core-module section/WAT results. There is no declared component-model result profile or component ABI contract in src/wasm or src/contracts. Component binaries use their own layer/version and contain component/core index spaces; treating them as ordinary core modules would lose relevant structure.

Acceptance criteria

  • Define component identity, admitted binary proposal/tool versions, typed imports/exports, embedded core modules and canonical lift/lower relationships.
  • Use a pinned decoder/tool profile and report unsupported component features without claiming full validation.
  • Preserve original byte hashes, source ranges, per-facet coverage, cancellation and owned cleanup.
  • Generate original valid/malformed fixtures and verify real CLI/MCP behavior; never instantiate or execute the selected component.

This is separate from function pseudocode request #2298.

Priority: P2. The current surface was checked at upstream 1c3791430, and open/closed issues were searched before filing. Proposed file-analysis features need their own spec/plan/tasks under docs/specs/. If implementation requires a new provider or expands execution authority, obtain the maintainer scope decision required by CONTRIBUTING.md before integration; this proposal itself does not authorize that expansion.

Originally created by @matbrgz on GitHub (Oct 12, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/2350 [![Type: Feature](https://img.shields.io/badge/type-feature-blue.svg?style=flat-square)](https://github.com/morluto/rea) [![Domain: Reverse Engineering](https://img.shields.io/badge/domain-reverse_engineering-blueviolet.svg?style=flat-square)](https://github.com/morluto/rea) [![Status: Proposed](https://img.shields.io/badge/status-proposed-blue.svg?style=flat-square)](https://github.com/morluto/rea) [![Ecosystem: REA](https://img.shields.io/badge/ecosystem-morluto%2Frea-8A2BE2.svg?style=flat-square)](https://github.com/morluto/rea) ## Analyst question and current scope The shipped offline WASM lane is documented around WABT 1.0.42 and core-module section/WAT results. There is no declared component-model result profile or component ABI contract in src/wasm or src/contracts. Component binaries use their own layer/version and contain component/core index spaces; treating them as ordinary core modules would lose relevant structure. ## Acceptance criteria - [ ] Define component identity, admitted binary proposal/tool versions, typed imports/exports, embedded core modules and canonical lift/lower relationships. - [ ] Use a pinned decoder/tool profile and report unsupported component features without claiming full validation. - [ ] Preserve original byte hashes, source ranges, per-facet coverage, cancellation and owned cleanup. - [ ] Generate original valid/malformed fixtures and verify real CLI/MCP behavior; never instantiate or execute the selected component. ## Source and related work - https://github.com/WebAssembly/component-model/blob/main/design/mvp/Binary.md This is separate from function pseudocode request #2298. Priority: P2. The current surface was checked at upstream 1c3791430, and open/closed issues were searched before filing. Proposed file-analysis features need their own spec/plan/tasks under docs/specs/. If implementation requires a new provider or expands execution authority, obtain the maintainer scope decision required by CONTRIBUTING.md before integration; this proposal itself does not authorize that expansion.
Author
Owner

@all-black-493 commented on GitHub (Oct 12, 2026):

I'd like to take this on with a focused PR. Here is the proposed boundary, so it can be corrected before review.

Approach: an in-process, read-only decoder, no new external tool.
WABT 1.0.42 cannot parse component binaries, so the WABT lane cannot cover this. Like the Go build-info reader (#1363), a REA-owned decoder in src/wasm/ would read the selected file through the existing stable artifact reader. It starts no subprocess, writes no temporary files, and never instantiates or executes the component or its embedded core modules. It would be a new target-free tool, inspect_wasm_component / rea inspect-wasm-component <path>, with CLI/MCP parity and Evidence.

Pinned decoder profile

  • Admits only the component preamble 00 61 73 6D 0D 00 01 00 (version 0x0d, layer 0x01). The grammar is pinned to component-model design/mvp/Binary.md at 06e3db0 (2026-09-23).
  • Other versions or layers return unsupported_target with the observed bytes. A core module (layer 0x00) points to inspect_wasm_artifact.
  • validation is always not_performed. The decoder checks only structure (LEB128, lengths, bounds, opcodes), never typing, uniqueness or the canonical ABI.

Result facets, each with byte ranges and its own coverage

  • Identity: path, SHA-256, size, preamble, decoder profile.
  • Sections: id, payload range, SHA-256.
  • Imports and exports: names with attributes (implements, versionsuffix, external-id) and decoded extern types.
  • Types: value, function (including async), resource, component and instance types.
  • Embedded core modules: index, byte range, SHA-256 and size only; they are not decoded or run.
  • Core and component instances, and aliases.
  • Canon definitions: lift, lower, resource.* and the gated async/thread built-ins, with options, and with operands resolved through the index spaces. For example: export run ← canon lift of core func 2 ← core export alias run of core instance 0 ← instantiate core module 0.
  • Nested components (bounded depth), the component-name section, and other custom sections by name and range.
  • Gated features actually observed (🔀 🧵 📝 🔧 🗺️ 🪙 🏷️ 🔗).

Anything the decoder does not handle, for example GC core types in a core type section, is reported as not_decoded with its range. Decoding then continues with the next section, because sections are length-prefixed.

Limits and lifecycle: 8 MiB input (same as the WASM lane), a nesting-depth bound, an inline output budget, and cancellation checks between sections. Apart from the stable read there are no owned resources to clean up.

Routing: open_binary and inspect_wasm_artifact would recognize the component preamble and point to the new tool, instead of treating the file as a core module or an unknown binary.

Verification: original valid and malformed components are generated at test time by a byte builder (no committed binaries), with real CLI and MCP boundary tests, including truncation, bad lengths, unknown sections and opcodes, unsupported versions, nesting limits and cancellation.

docs/specs: that directory doesn't exist, and AGENTS.md says not to commit local planning artifacts. So the design lives here and in the PR, and user docs go in docs/wasm-artifacts.md. Please say if a spec file is wanted anyway.

Questions

  1. Is a separate tool preferred, or should inspect_wasm_artifact dispatch on the layer? I chose a separate tool because its provider needs no WABT and its result shape differs.
  2. Does this read-only in-process decoder need a separate maintainer scope decision as a new provider? I'll keep that item open in the PR until you say.
  3. Complete inline results first, with summary delivery as in #2193 as a follow-up, or both in this PR?

This stays separate from #2298 (pseudocode) and #2356 (interface comparison), though #2356 could build on these typed imports and exports.

<!-- gh-comment-id:6132735562 --> @all-black-493 commented on GitHub (Oct 12, 2026): I'd like to take this on with a focused PR. Here is the proposed boundary, so it can be corrected before review. **Approach: an in-process, read-only decoder, no new external tool.** WABT 1.0.42 cannot parse component binaries, so the WABT lane cannot cover this. Like the Go build-info reader (#1363), a REA-owned decoder in `src/wasm/` would read the selected file through the existing stable artifact reader. It starts no subprocess, writes no temporary files, and never instantiates or executes the component or its embedded core modules. It would be a new target-free tool, `inspect_wasm_component` / `rea inspect-wasm-component <path>`, with CLI/MCP parity and Evidence. **Pinned decoder profile** - Admits only the component preamble `00 61 73 6D 0D 00 01 00` (version `0x0d`, layer `0x01`). The grammar is pinned to component-model `design/mvp/Binary.md` at [`06e3db0`](https://github.com/WebAssembly/component-model/blob/06e3db039e38588e2643a9417bf5d03100feafde/design/mvp/Binary.md) (2026-09-23). - Other versions or layers return `unsupported_target` with the observed bytes. A core module (layer `0x00`) points to `inspect_wasm_artifact`. - `validation` is always `not_performed`. The decoder checks only structure (LEB128, lengths, bounds, opcodes), never typing, uniqueness or the canonical ABI. **Result facets, each with byte ranges and its own coverage** - Identity: path, SHA-256, size, preamble, decoder profile. - Sections: id, payload range, SHA-256. - Imports and exports: names with attributes (`implements`, `versionsuffix`, `external-id`) and decoded extern types. - Types: value, function (including async), resource, component and instance types. - Embedded core modules: index, byte range, SHA-256 and size only; they are not decoded or run. - Core and component instances, and aliases. - Canon definitions: lift, lower, `resource.*` and the gated async/thread built-ins, with options, and with operands resolved through the index spaces. For example: export `run` ← canon lift of core func 2 ← core export alias `run` of core instance 0 ← instantiate core module 0. - Nested components (bounded depth), the `component-name` section, and other custom sections by name and range. - Gated features actually observed (🔀 🧵 📝 🔧 🗺️ 🪙 🏷️ 🔗). Anything the decoder does not handle, for example GC core types in a core type section, is reported as `not_decoded` with its range. Decoding then continues with the next section, because sections are length-prefixed. **Limits and lifecycle:** 8 MiB input (same as the WASM lane), a nesting-depth bound, an inline output budget, and cancellation checks between sections. Apart from the stable read there are no owned resources to clean up. **Routing:** `open_binary` and `inspect_wasm_artifact` would recognize the component preamble and point to the new tool, instead of treating the file as a core module or an unknown binary. **Verification:** original valid and malformed components are generated at test time by a byte builder (no committed binaries), with real CLI and MCP boundary tests, including truncation, bad lengths, unknown sections and opcodes, unsupported versions, nesting limits and cancellation. **docs/specs:** that directory doesn't exist, and AGENTS.md says not to commit local planning artifacts. So the design lives here and in the PR, and user docs go in `docs/wasm-artifacts.md`. Please say if a spec file is wanted anyway. **Questions** 1. Is a separate tool preferred, or should `inspect_wasm_artifact` dispatch on the layer? I chose a separate tool because its provider needs no WABT and its result shape differs. 2. Does this read-only in-process decoder need a separate maintainer scope decision as a new provider? I'll keep that item open in the PR until you say. 3. Complete inline results first, with summary delivery as in #2193 as a follow-up, or both in this PR? This stays separate from #2298 (pseudocode) and #2356 (interface comparison), though #2356 could build on these typed imports and exports.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#775
No description provided.