[PR #5069] feat(rust): read cargo-auditable dependencies from WebAssembly modules #6768

Open
opened 2026-11-01 21:42:54 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/5069
Author: @yu0809
Created: 10/18/2026
Status: 🔄 Open

Base: main ← Head: feat/rust-wasm-auditable


📝 Commits (9)

  • 85c9f88 feat(rust): read cargo-auditable dependencies from WebAssembly modules
  • 9bac2e3 fix(rust): bound the WebAssembly section walk
  • cda31a6 Merge morluto/rea main into feat/rust-wasm-auditable
  • 162590b Merge origin/main into feat/rust-wasm-auditable
  • 345f0f4 Merge morluto/rea main into feat/rust-wasm-auditable
  • d2fd725 fix(rust): accept WebAssembly Evidence in retained dependency views
  • bdb41d2 fix(rust): name the WebAssembly section-walk allowance in recovery
  • 6ce932e Merge morluto/rea main into feat/rust-wasm-auditable
  • 084ad35 fix(rust): require WebAssembly container facts in reports

📊 Changes

22 files changed (+714 additions, -119 deletions)

View changed files

📝 .agents/skills/reverse-engineer-anything/SKILL.md (+6 -5)
📝 .agents/skills/reverse-engineer-anything/references/native-and-artifacts.md (+12 -10)
📝 README.md (+1 -1)
📝 docs/readme/README_el.md (+1 -1)
📝 docs/readme/README_ko.md (+1 -1)
📝 docs/readme/README_ml.md (+1 -1)
📝 docs/readme/README_tr.md (+1 -1)
📝 docs/rust-binaries.md (+33 -6)
📝 src/cli/rustCommands.ts (+1 -1)
📝 src/contracts/rust/rustToolContracts.ts (+1 -1)
📝 src/domain/analysisView/rustBinaryView.test.ts (+25 -2)
📝 src/domain/apple/machoTargetSelection.ts (+14 -9)
📝 src/domain/rust/rustBinary.ts (+17 -2)
📝 src/rust/RustAuditableReader.ts (+4 -0)
📝 src/rust/RustBinaryImage.ts (+104 -52)
📝 src/rust/RustBinaryProvider.ts (+36 -22)
➕ src/rust/RustWasmImage.ts (+141 -0)
📝 tests/acceptance/rustBinaryCli.test.ts (+55 -0)
📝 tests/acceptance/rustDependencyViews.test.ts (+14 -3)
📝 tests/boundary/mcp/rustBinaryMcp.test.ts (+42 -1)

...and 2 more files

📄 Description

Summary

inspect_rust_binary / inspect-rust-binary now reads the cargo-auditable
dependency list from WebAssembly core modules. cargo auditable build for a
wasm32 target stores the same zlib-compressed .dep-v0 JSON in a WebAssembly
custom section, but REA refused every .wasm input as an unsupported target
because only ELF, PE and thin Mach-O containers were recognized. The reference
reader, auditable-extract 0.3.5, reads WebAssembly through its default wasm
feature.

No issue is linked: searching issues and PRs for cargo-auditable,
inspect_rust_binary and rust wasm found nothing on WebAssembly (#3398 and
#3454 concern an unrelated ELF section).

Problem and expected behavior

Smallest trigger: cargo auditable build --release --target wasm32-wasip1,
then rea inspect-rust-binary target/wasm32-wasip1/release/<crate>.wasm --json.

  • Before (cee95b2a): exit 1, unsupported_target, reason Only ELF, PE, and thin Mach-O native images are supported.
  • After: exit 0 with the embedded packages, sources, root and dependency edges;
    file_offset and section_bytes locate the custom-section payload.

Change and scope

  • src/rust/RustWasmImage.ts (new) owns WebAssembly section framing: the
    header, u32 LEB128 section sizes bounded to five bytes, custom-section names
    (bounded and UTF-8), the .dep-v0 payload and the data section. It walks
    framing only; section contents are not validated, and nothing is
    instantiated or executed. Retention is bounded to two .dep-v0 ranges (enough
    to establish a duplicate) and one data section, and the synchronous walk to
    65,536 sections: more is a cpu resource constraint reporting
    maximum_wasm_sections (the format sets no section count; producer output
    holds a few dozen).
  • src/rust/RustBinaryImage.ts now reads one format-neutral layout built by the
    native container reader or the WebAssembly reader, so a single function owns
    the one-dependency-section rule for both, and the rustc scan receives spans
    (native read-only sections and ELF read-only load ranges, or the module's
    data section) instead of re-deriving them.
  • Contract: format adds wasm and bits becomes nullable. Refinements
    require bits: null and architecture: wasm exactly when format is
    wasm, and byte_order: little for wasm: WebAssembly declares no
    container word size (memory address types are not inspected) and is
    little-endian. The Evidence subject format is file, as for
    inspect_wasm_artifact.
  • rustc commit inference scans the module's data section, where real rustc
    output keeps its /rustc/<hash>/ paths (the native analogue is read-only
    data). Limitations name the scanned source for each format.
  • Retained dependency views (detail: "summary", view and
    inspect_analysis_view kind rust) accept WebAssembly Evidence: the shared
    metadataReportSubjectFormat owner, which the service and the view identity
    check both use, maps a wasm report to file.
  • The section-walk refusal names a fixed work allowance and is not retryable;
    each Rust resource maps to its own fixed-allowance recovery.
  • Not included: components (header layer 1, such as wasm32-wasip2 output) are
    refused as unsupported. They embed several core modules (the measured build
    carries three: the Rust module and two small generated modules), so reporting
    one .dep-v0 needs a module-selection or multi-module contract decision,
    comparable to architecture for universal Mach-O. That could be a follow-up.
  • Docs: docs/rust-binaries.md, the README support row (English and the four
    translations that list container names), skill instructions, the tool
    description and the CLI argument help.

Follow the contribution scope.
This is static format inspection inside the existing inspect_rust_binary
boundary: it reads only the selected file, with no execution, injection,
mutation or network access. A maintainer scope decision is not applicable.

Contract and boundary impact

  • Semantic owner and earliest changed stage: src/rust/RustWasmImage.ts
    (WebAssembly framing), then src/rust/RustBinaryImage.ts (Rust layout), then
    src/domain/rust/rustBinary.ts (report contract).
  • Contribution scope fit and linked maintainer decision: static inspection in an
    existing tool; not applicable.
  • CLI and MCP/tool-catalog contract: output widening only. format gains
    wasm and bits admits null only for wasm; ELF, PE and Mach-O reports are
    unchanged apart from limitation wording.
  • Provider, bridge, target-format, or platform compatibility: adds version 1
    WebAssembly core modules; components and pre-release module versions return
    unsupported_target, and more than 65,536 sections returns
    resource_constraint with resource cpu. architecture on a module is
    rejected, as on any image that is not a universal Mach-O.
  • Evidence, artifact, provenance, or reconstruction contract: offsets refer to
    the original file; the subject is file without an architecture.
  • Target selection, authority, upstream behavior, and cleanup details: unchanged
    stable artifact reader; no new resources.
  • Generated metadata (docs/public/product-catalog.json), package, or
    installation impact: the catalog changes only through the tool description and
    output schema; npm run docs:check passes. No package or installation change.

Expected effects (check known effects; use documentation-only on its own).
Unchecked items do not establish absence; leave uncertainties visible.

  • Read existing files or captured data.
  • Launch or attach to a process.
  • Inject instrumentation or run scripts/code.
  • Change process memory, registers, files, or configuration.
  • Contact network services.
  • Recover protected code or work around protections.
  • Documentation or usability only; no target interaction.
  • Not sure yet; investigation or maintainer guidance needed.

Evidence and regression coverage

  • Tests added or updated:

    • tests/boundary/rust/rustBinaryImage.test.ts: a module with .dep-v0 and a
      data-section rustc path; a module without .dep-v0; nine refusals
      (component, pre-release version, truncated header, section past the end of
      the file, size over 32 bits, custom name past its section, non-UTF-8 name,
      duplicate .dep-v0, second data section); 65,536 sections are admitted
      and 65,537 are refused with the cpu constraint.
    • tests/acceptance/rustBinaryCli.test.ts: public CLI success for a module
      (format: wasm, bits: null, subject file) and unsupported_target for a
      component.
    • tests/boundary/mcp/rustBinaryMcp.test.ts: the existing session also calls
      the tool on a module after listTools(), so the client validates
      bits: null against the advertised output schema; the resource-unit test
      checks cpu, maximum_wasm_sections, retryable: false and the named work
      allowance through the public error contract.
    • src/domain/analysisView/rustBinaryView.test.ts: imported reports whose
      container facts contradict WebAssembly are refused.
    • tests/acceptance/rustDependencyViews.test.ts: the real CLI/MCP retained
      view workflow (selected view, summary, CLI bundle, retained and portable
      pages, malformed-Evidence refusal) also runs on a WebAssembly module. With
      the view's previous Mach-O-only format mapping restored, the WebAssembly
      view call fails with Rust parent subject must identify the report's exact artifact.
    • tests/fixtures/rust/image.ts: a synthetic core module shaped like
      cargo-auditable output. During development Node 24.18.0
      WebAssembly.validate accepted it; the test does not assert this because
      the ES2023 lib does not type the WebAssembly global.
  • Base reproduction: with only the test changes on cee95b2a, all 14 new cases
    fail and every existing case passes; with the source change all pass. The two
    section-budget checks fail on 85c9f888, where the over-budget module was
    accepted, and pass on 9bac2e32.

  • Real producer (executed on Linux x64 with rustc 1.97.0 (2d8144b78 2026-07-07)
    and cargo-auditable 0.7.7): an independent Python LEB128 walker with zlib and
    JSON located each .dep-v0 section and matched REA's file_offset,
    section_bytes, format_version, every package field, the root index and the
    SHA-256.

    Build Before After
    wasm32-wasip1 binary, 10 packages (2.2 MB) unsupported_target 10 packages, 9 edges, rustc 2d8144b78…
    wasm32-unknown-unknown binary, same crate (1.6 MB) unsupported_target 10 packages, 9 edges, rustc 2d8144b78…
    wasm32-unknown-unknown cdylib, strip = true (17 KB) unsupported_target 2 packages, 1 edge, rustc 2d8144b78…
    wasm32-wasip2 component unsupported_target unsupported_target (component refusal)
  • User-visible CLI/MCP output (wasm32-wasip1, abridged):

    {
      "format": "wasm",
      "architecture": "wasm",
      "bits": null,
      "byte_order": "little",
      "auditable_metadata": {
        "section_name": ".dep-v0",
        "file_offset": 2130985,
        "section_bytes": 246,
        "uncompressed_bytes": 733,
        "format_version": 1,
        "root_package_index": 1,
        "packages": [
          {
            "name": "cc",
            "version": "1.8.0",
            "source": "crates.io",
            "kind": "build",
            "dependencies": [2, 7],
            "root": false
          },
          "…9 more"
        ]
      },
      "rustc_commit": {
        "evidence_kind": "inferred",
        "hashes": [
          {
            "hash": "2d8144b7880597b6e6d3dfd63a9a9efae3f533d3",
            "file_offset": 64960
          }
        ]
      }
    }
    
  • Remaining proof gaps: not run against wasm-bindgen or wasm-opt
    post-processed modules, wasm32-wasip1-threads, wasm64-unknown-unknown,
    macOS or Windows hosts, or third-party .wasm artifacts. Components remain
    unsupported.

For evidence-bearing changes:

  • Observed, derived, and inferred claims remain distinguishable.
  • Artifact identity, source provenance, and failed attempts remain preserved.
  • Unsupported, incomplete, unavailable, or uncertain outcomes remain visible.

Validation performed

On 6ce932ee (main bb17e90f merged) with the pinned Node 24.22.1 on Linux
x64:

  • npm run check and npm run docs:check — passed. npm run jscpd — 3.63%
    duplicated lines, as on bb17e90f (threshold 4%).
  • npm run test:focused -- 38 Rust, Go, universal Mach-O, analysis-view,
    contract, MCP schema and module-boundary files — 553 tests passed, 1
    skipped.
  • npm run test:fast — 1,022 of 1,023 files passed and 1 was skipped
    (18,595 tests passed).

On 084ad352 (the container-fact refinements): npm run check:fast,
npm run docs:check and 21 focused Rust, view and schema files — 219 tests
passed, 1 skipped.

Earlier, on 9bac2e32:

  • npm run test:focused -- the three changed test files plus
    toolSchemaValidity, outputSchemaProfile, clientCapabilities,
    RustBinaryService, RustAuditableReader, stableArtifactConsumers,
    callerPathSymlinkParentCli, toolEffects and the four Go test files
    (shared container readers) — 15 files, 237 tests passed.
  • npm run check — passed (typecheck, lint with module boundaries,
    format:check, knip, metadata:check, architecture guards).
  • npm run docs:check — passed, including the README consistency suite.
  • npm run jscpd — 3.36% duplicated lines (threshold 3.5%).
  • Base comparison and real-producer runs — as described above.
  • CLI cost, five cold runs each, medians (elapsed / CPU / peak RSS / stdout):
    ELF 4.4 MB: 1.43 s / 2.06 s / 342 MiB / 4,873 B; wasm32-wasip1 2.2 MB:
    1.23 s / 1.94 s / 337 MiB / 5,311 B; wasm32-unknown-unknown 1.6 MB:
    1.33 s / 2.11 s / 337 MiB / 5,347 B. CLI startup dominates; token counts were
    not measured. Native inputs gain one four-byte prefix comparison.
  • Hostile 256 MiB modules through the reader: 89.5 million empty-name custom
    sections took 7.4 s synchronously on 85c9f888 and are refused in 35 ms;
    134 million empty type sections took 1.9 s and are refused in 8 ms.

Compatibility, safety, and release

  • Breaking changes or migration steps: none. Output widening: format gains
    wasm, and bits admits null only for wasm reports, which were
    previously refused.
  • Real Hopper/Ghidra, browser, or OS coverage: no engine involved;
    real-producer coverage is Linux x64 only.
  • Package or release metadata impact: none; no dependency change, and the skill
    version is unchanged, as for the original Rust skill text.
  • Security, privacy, process, or containment review: reads only the selected
    file through the existing stable artifact reader; no subprocess, temporary
    file or network access. The framing walk visits at most 65,536 sections and
    retains at most three ranges, and the existing 256 MiB, 1 MiB and 8 MiB guards
    still apply.

Author readiness

Human owner: @yu0809

  • I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work.
  • I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps.
  • I declare this PR ready for initial maintainer review.

Before merge

  • This PR addresses a concrete problem or an agreed enhancement.
  • Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.
  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked, or the reason for not linking one is stated above.
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed.
  • User-visible CLI/MCP changes include representative output.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/5069 **Author:** [@yu0809](https://github.com/yu0809) **Created:** 10/18/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `feat/rust-wasm-auditable` --- ### 📝 Commits (9) - [`85c9f88`](https://github.com/morluto/rea/commit/85c9f88835a0c2e7a37976159b925d362509b88d) feat(rust): read cargo-auditable dependencies from WebAssembly modules - [`9bac2e3`](https://github.com/morluto/rea/commit/9bac2e32b10ea35c1c139f0c380329b2dc84c70b) fix(rust): bound the WebAssembly section walk - [`cda31a6`](https://github.com/morluto/rea/commit/cda31a6d588d1a3163370fec977ce5ea9a7f8b38) Merge morluto/rea main into feat/rust-wasm-auditable - [`162590b`](https://github.com/morluto/rea/commit/162590be17cc66895ea2bd8da7fd3ed3e38247c8) Merge origin/main into feat/rust-wasm-auditable - [`345f0f4`](https://github.com/morluto/rea/commit/345f0f4caee32b0cd97ae950bd3707f4408cd557) Merge morluto/rea main into feat/rust-wasm-auditable - [`d2fd725`](https://github.com/morluto/rea/commit/d2fd725235af9cf1db7e44148121a062256130b5) fix(rust): accept WebAssembly Evidence in retained dependency views - [`bdb41d2`](https://github.com/morluto/rea/commit/bdb41d26b2641fab6a6bf3e84ab9c62e76d4e4fb) fix(rust): name the WebAssembly section-walk allowance in recovery - [`6ce932e`](https://github.com/morluto/rea/commit/6ce932ee82bf7810350fb63576a42b5696bf507d) Merge morluto/rea main into feat/rust-wasm-auditable - [`084ad35`](https://github.com/morluto/rea/commit/084ad352d009a8e2832539e27bfbffc67d3cbed7) fix(rust): require WebAssembly container facts in reports ### 📊 Changes **22 files changed** (+714 additions, -119 deletions) <details> <summary>View changed files</summary> 📝 `.agents/skills/reverse-engineer-anything/SKILL.md` (+6 -5) 📝 `.agents/skills/reverse-engineer-anything/references/native-and-artifacts.md` (+12 -10) 📝 `README.md` (+1 -1) 📝 `docs/readme/README_el.md` (+1 -1) 📝 `docs/readme/README_ko.md` (+1 -1) 📝 `docs/readme/README_ml.md` (+1 -1) 📝 `docs/readme/README_tr.md` (+1 -1) 📝 `docs/rust-binaries.md` (+33 -6) 📝 `src/cli/rustCommands.ts` (+1 -1) 📝 `src/contracts/rust/rustToolContracts.ts` (+1 -1) 📝 `src/domain/analysisView/rustBinaryView.test.ts` (+25 -2) 📝 `src/domain/apple/machoTargetSelection.ts` (+14 -9) 📝 `src/domain/rust/rustBinary.ts` (+17 -2) 📝 `src/rust/RustAuditableReader.ts` (+4 -0) 📝 `src/rust/RustBinaryImage.ts` (+104 -52) 📝 `src/rust/RustBinaryProvider.ts` (+36 -22) ➕ `src/rust/RustWasmImage.ts` (+141 -0) 📝 `tests/acceptance/rustBinaryCli.test.ts` (+55 -0) 📝 `tests/acceptance/rustDependencyViews.test.ts` (+14 -3) 📝 `tests/boundary/mcp/rustBinaryMcp.test.ts` (+42 -1) _...and 2 more files_ </details> ### 📄 Description ## Summary `inspect_rust_binary` / `inspect-rust-binary` now reads the cargo-auditable dependency list from WebAssembly core modules. `cargo auditable build` for a `wasm32` target stores the same zlib-compressed `.dep-v0` JSON in a WebAssembly custom section, but REA refused every `.wasm` input as an unsupported target because only ELF, PE and thin Mach-O containers were recognized. The reference reader, `auditable-extract` 0.3.5, reads WebAssembly through its default `wasm` feature. No issue is linked: searching issues and PRs for `cargo-auditable`, `inspect_rust_binary` and `rust wasm` found nothing on WebAssembly (#3398 and #3454 concern an unrelated ELF section). ## Problem and expected behavior Smallest trigger: `cargo auditable build --release --target wasm32-wasip1`, then `rea inspect-rust-binary target/wasm32-wasip1/release/<crate>.wasm --json`. - Before (`cee95b2a`): exit 1, `unsupported_target`, reason `Only ELF, PE, and thin Mach-O native images are supported`. - After: exit 0 with the embedded packages, sources, root and dependency edges; `file_offset` and `section_bytes` locate the custom-section payload. ## Change and scope - `src/rust/RustWasmImage.ts` (new) owns WebAssembly section framing: the header, u32 LEB128 section sizes bounded to five bytes, custom-section names (bounded and UTF-8), the `.dep-v0` payload and the data section. It walks framing only; section contents are not validated, and nothing is instantiated or executed. Retention is bounded to two `.dep-v0` ranges (enough to establish a duplicate) and one data section, and the synchronous walk to 65,536 sections: more is a `cpu` resource constraint reporting `maximum_wasm_sections` (the format sets no section count; producer output holds a few dozen). - `src/rust/RustBinaryImage.ts` now reads one format-neutral layout built by the native container reader or the WebAssembly reader, so a single function owns the one-dependency-section rule for both, and the rustc scan receives spans (native read-only sections and ELF read-only load ranges, or the module's data section) instead of re-deriving them. - Contract: `format` adds `wasm` and `bits` becomes nullable. Refinements require `bits: null` and `architecture: wasm` exactly when `format` is `wasm`, and `byte_order: little` for `wasm`: WebAssembly declares no container word size (memory address types are not inspected) and is little-endian. The Evidence subject format is `file`, as for `inspect_wasm_artifact`. - rustc commit inference scans the module's data section, where real rustc output keeps its `/rustc/<hash>/` paths (the native analogue is read-only data). Limitations name the scanned source for each format. - Retained dependency views (`detail: "summary"`, `view` and `inspect_analysis_view` kind `rust`) accept WebAssembly Evidence: the shared `metadataReportSubjectFormat` owner, which the service and the view identity check both use, maps a `wasm` report to `file`. - The section-walk refusal names a fixed work allowance and is not retryable; each Rust resource maps to its own fixed-allowance recovery. - Not included: components (header layer 1, such as `wasm32-wasip2` output) are refused as `unsupported`. They embed several core modules (the measured build carries three: the Rust module and two small generated modules), so reporting one `.dep-v0` needs a module-selection or multi-module contract decision, comparable to `architecture` for universal Mach-O. That could be a follow-up. - Docs: `docs/rust-binaries.md`, the README support row (English and the four translations that list container names), skill instructions, the tool description and the CLI argument help. Follow the [contribution scope](https://github.com/morluto/rea/blob/main/CONTRIBUTING.md#contribution-scope). This is static format inspection inside the existing `inspect_rust_binary` boundary: it reads only the selected file, with no execution, injection, mutation or network access. A maintainer scope decision is not applicable. ## Contract and boundary impact - Semantic owner and earliest changed stage: `src/rust/RustWasmImage.ts` (WebAssembly framing), then `src/rust/RustBinaryImage.ts` (Rust layout), then `src/domain/rust/rustBinary.ts` (report contract). - Contribution scope fit and linked maintainer decision: static inspection in an existing tool; not applicable. - CLI and MCP/tool-catalog contract: output widening only. `format` gains `wasm` and `bits` admits `null` only for `wasm`; ELF, PE and Mach-O reports are unchanged apart from limitation wording. - Provider, bridge, target-format, or platform compatibility: adds version 1 WebAssembly core modules; components and pre-release module versions return `unsupported_target`, and more than 65,536 sections returns `resource_constraint` with resource `cpu`. `architecture` on a module is rejected, as on any image that is not a universal Mach-O. - Evidence, artifact, provenance, or reconstruction contract: offsets refer to the original file; the subject is `file` without an architecture. - Target selection, authority, upstream behavior, and cleanup details: unchanged stable artifact reader; no new resources. - Generated metadata (`docs/public/product-catalog.json`), package, or installation impact: the catalog changes only through the tool description and output schema; `npm run docs:check` passes. No package or installation change. Expected effects (check known effects; use documentation-only on its own). Unchecked items do not establish absence; leave uncertainties visible. - [x] Read existing files or captured data. - [ ] Launch or attach to a process. - [ ] Inject instrumentation or run scripts/code. - [ ] Change process memory, registers, files, or configuration. - [ ] Contact network services. - [ ] Recover protected code or work around protections. - [ ] Documentation or usability only; no target interaction. - [ ] Not sure yet; investigation or maintainer guidance needed. ## Evidence and regression coverage - Tests added or updated: - `tests/boundary/rust/rustBinaryImage.test.ts`: a module with `.dep-v0` and a data-section rustc path; a module without `.dep-v0`; nine refusals (component, pre-release version, truncated header, section past the end of the file, size over 32 bits, custom name past its section, non-UTF-8 name, duplicate `.dep-v0`, second data section); 65,536 sections are admitted and 65,537 are refused with the `cpu` constraint. - `tests/acceptance/rustBinaryCli.test.ts`: public CLI success for a module (`format: wasm`, `bits: null`, subject `file`) and `unsupported_target` for a component. - `tests/boundary/mcp/rustBinaryMcp.test.ts`: the existing session also calls the tool on a module after `listTools()`, so the client validates `bits: null` against the advertised output schema; the resource-unit test checks `cpu`, `maximum_wasm_sections`, `retryable: false` and the named work allowance through the public error contract. - `src/domain/analysisView/rustBinaryView.test.ts`: imported reports whose container facts contradict WebAssembly are refused. - `tests/acceptance/rustDependencyViews.test.ts`: the real CLI/MCP retained view workflow (selected view, summary, CLI bundle, retained and portable pages, malformed-Evidence refusal) also runs on a WebAssembly module. With the view's previous Mach-O-only format mapping restored, the WebAssembly view call fails with `Rust parent subject must identify the report's exact artifact`. - `tests/fixtures/rust/image.ts`: a synthetic core module shaped like cargo-auditable output. During development Node 24.18.0 `WebAssembly.validate` accepted it; the test does not assert this because the ES2023 lib does not type the `WebAssembly` global. - Base reproduction: with only the test changes on `cee95b2a`, all 14 new cases fail and every existing case passes; with the source change all pass. The two section-budget checks fail on `85c9f888`, where the over-budget module was accepted, and pass on `9bac2e32`. - Real producer (executed on Linux x64 with rustc 1.97.0 (2d8144b78 2026-07-07) and cargo-auditable 0.7.7): an independent Python LEB128 walker with zlib and JSON located each `.dep-v0` section and matched REA's `file_offset`, `section_bytes`, `format_version`, every package field, the root index and the SHA-256. | Build | Before | After | | ------------------------------------------------------- | -------------------- | ---------------------------------------- | | `wasm32-wasip1` binary, 10 packages (2.2 MB) | `unsupported_target` | 10 packages, 9 edges, rustc `2d8144b78…` | | `wasm32-unknown-unknown` binary, same crate (1.6 MB) | `unsupported_target` | 10 packages, 9 edges, rustc `2d8144b78…` | | `wasm32-unknown-unknown` cdylib, `strip = true` (17 KB) | `unsupported_target` | 2 packages, 1 edge, rustc `2d8144b78…` | | `wasm32-wasip2` component | `unsupported_target` | `unsupported_target` (component refusal) | - User-visible CLI/MCP output (`wasm32-wasip1`, abridged): ```json { "format": "wasm", "architecture": "wasm", "bits": null, "byte_order": "little", "auditable_metadata": { "section_name": ".dep-v0", "file_offset": 2130985, "section_bytes": 246, "uncompressed_bytes": 733, "format_version": 1, "root_package_index": 1, "packages": [ { "name": "cc", "version": "1.8.0", "source": "crates.io", "kind": "build", "dependencies": [2, 7], "root": false }, "…9 more" ] }, "rustc_commit": { "evidence_kind": "inferred", "hashes": [ { "hash": "2d8144b7880597b6e6d3dfd63a9a9efae3f533d3", "file_offset": 64960 } ] } } ``` - Remaining proof gaps: not run against wasm-bindgen or wasm-opt post-processed modules, `wasm32-wasip1-threads`, `wasm64-unknown-unknown`, macOS or Windows hosts, or third-party `.wasm` artifacts. Components remain unsupported. For evidence-bearing changes: - [x] Observed, derived, and inferred claims remain distinguishable. - [x] Artifact identity, source provenance, and failed attempts remain preserved. - [x] Unsupported, incomplete, unavailable, or uncertain outcomes remain visible. ## Validation performed On `6ce932ee` (main `bb17e90f` merged) with the pinned Node 24.22.1 on Linux x64: - `npm run check` and `npm run docs:check` — passed. `npm run jscpd` — 3.63% duplicated lines, as on `bb17e90f` (threshold 4%). - `npm run test:focused --` 38 Rust, Go, universal Mach-O, analysis-view, contract, MCP schema and module-boundary files — 553 tests passed, 1 skipped. - `npm run test:fast` — 1,022 of 1,023 files passed and 1 was skipped (18,595 tests passed). On `084ad352` (the container-fact refinements): `npm run check:fast`, `npm run docs:check` and 21 focused Rust, view and schema files — 219 tests passed, 1 skipped. Earlier, on `9bac2e32`: - `npm run test:focused --` the three changed test files plus `toolSchemaValidity`, `outputSchemaProfile`, `clientCapabilities`, `RustBinaryService`, `RustAuditableReader`, `stableArtifactConsumers`, `callerPathSymlinkParentCli`, `toolEffects` and the four Go test files (shared container readers) — 15 files, 237 tests passed. - `npm run check` — passed (typecheck, lint with module boundaries, format:check, knip, metadata:check, architecture guards). - `npm run docs:check` — passed, including the README consistency suite. - `npm run jscpd` — 3.36% duplicated lines (threshold 3.5%). - Base comparison and real-producer runs — as described above. - CLI cost, five cold runs each, medians (elapsed / CPU / peak RSS / stdout): ELF 4.4 MB: 1.43 s / 2.06 s / 342 MiB / 4,873 B; `wasm32-wasip1` 2.2 MB: 1.23 s / 1.94 s / 337 MiB / 5,311 B; `wasm32-unknown-unknown` 1.6 MB: 1.33 s / 2.11 s / 337 MiB / 5,347 B. CLI startup dominates; token counts were not measured. Native inputs gain one four-byte prefix comparison. - Hostile 256 MiB modules through the reader: 89.5 million empty-name custom sections took 7.4 s synchronously on `85c9f888` and are refused in 35 ms; 134 million empty type sections took 1.9 s and are refused in 8 ms. ## Compatibility, safety, and release - Breaking changes or migration steps: none. Output widening: `format` gains `wasm`, and `bits` admits `null` only for `wasm` reports, which were previously refused. - Real Hopper/Ghidra, browser, or OS coverage: no engine involved; real-producer coverage is Linux x64 only. - Package or release metadata impact: none; no dependency change, and the skill version is unchanged, as for the original Rust skill text. - Security, privacy, process, or containment review: reads only the selected file through the existing stable artifact reader; no subprocess, temporary file or network access. The framing walk visits at most 65,536 sections and retains at most three ranges, and the existing 256 MiB, 1 MiB and 8 MiB guards still apply. ## Author readiness <!-- The human owner completes these declarations before requesting review. The PR author is the owner by default. A different owner must explicitly accept ownership on this PR. AI agents must leave these declarations to a human to dictate to them or there could be catastrophic consequences for many users of REA. Draft PRs may leave them unchecked. These declarations record initial readiness when opening the PR for review; later pushes do not require a new human sign-off. Keep the description and validation evidence current as the work changes. See CONTRIBUTING.md#pull-request-ownership-and-readiness. --> Human owner: @yu0809 - [x] I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work. - [x] I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps. - [x] I declare this PR ready for initial maintainer review. ## Before merge <!-- Draft PRs may leave pending items unchecked. Resolve material scope and authority questions before integration. --> - [x] This PR addresses a concrete problem or an agreed enhancement. - [x] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff. - [x] The PR has one focused outcome and the title follows `type(scope): outcome`. - [x] Related issue is linked, or the reason for not linking one is stated above. - [x] Tests cover changed observable behavior and meaningful failure paths. - [x] Owning docs, contracts, and generated metadata are updated where needed. - [x] User-visible CLI/MCP changes include representative output. - [x] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
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#6768
No description provided.