[GH-ISSUE #5404] [Bug] list-architectures rejects universal Mach-O files without a host-compatible slice #3274

Closed
opened 2026-10-31 00:38:40 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @coygeek on GitHub (Oct 20, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/5404

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

Native analysis or decompilation

Observed behavior

On an arm64 Mac, node scripts/rea.mjs list-architectures "$work/universal-only-x86_64.bin" --format json exits 1 without an inventory for a valid universal Mach-O containing only an x86_64 slice. Apple's lipo -detailed_info reads the same container successfully. REA successfully inventories the original thin x86_64 image and a universal container containing both x86_64 and arm64.

An independent verifier ran each of the three REA invocations once. This report was prepared with AI assistance from that independently reproduced result.

Reproduction

From the source checkout with dependencies installed and the runtime built, on macOS arm64 with Apple's cc and lipo available:

work="$(mktemp -d)"
cc -O0 tests/fixtures/native-macos/native-macho-header/fixture.c -o "$work/sample-x86_64" -arch x86_64
lipo -create "$work/sample-x86_64" -output "$work/universal-only-x86_64.bin"
lipo -detailed_info "$work/universal-only-x86_64.bin"
node scripts/rea.mjs list-architectures "$work/universal-only-x86_64.bin" --format json

These commands use the repository's existing C fixture. The verifier used the existing built CLI with isolated home, XDG and temporary directories. The binaries were inspected without executing them; no external API or deep-analysis engine was used. The failing CLI call reproduced once in one independent run.

Expected behavior

Return the container's x86_64 slice with its container-relative offset, size, alignment, exhaustive coverage and native-tool provenance, regardless of whether the host has a matching slice.

This expectation follows the source contract in src/contracts/native/nativeToolContracts.ts:119, which advertises thin or universal Mach-O slice inventory, and docs/native-investigation.md:311, which identifies even one-slice FAT inputs as mach-o-universal and describes container-relative architecture offsets.

Impact and scope

P2: callers cannot obtain any REA architecture inventory for the tested valid x86_64-only FAT container on an arm64 host. Thin x86_64 and mixed x86_64/arm64 controls succeed. lipo -detailed_info is a verified workaround that preserves the original container's coordinates. Extracting the x86_64 slice and inventorying the thin copy also succeeded, but changes the coordinate context.

Other architecture combinations and the MCP interface were not replayed. No security boundary was crossed.

REA version

rea-agents 6.7.0; source commit 074768901f3cdc8205b61773fb1faf6f6c7b3ca8.

Runtime and platform

Node.js v26.12.0; macOS 27.0.1; arm64. Apple's cc and lipo were available. Hopper/Ghidra were not used.

Target and artifact context

A single-slice universal/FAT Mach-O executable produced with lipo -create from an x86_64 build of tests/fixtures/native-macos/native-macho-header/fixture.c. Controls were the original thin executable and an arm64+x86_64 universal executable built from that same fixture.

Interface

CLI

Earliest failure stage

Setup or provider admission

Relevant output or evidence

The failing CLI call returned exit 1 and these JSON fields; path-bearing details are omitted:

{
  "error": "Analysis failed",
  "code": "target_unavailable",
  "category": "unsupported_target",
  "message": "Cannot open artifact: FAT binary has no host-compatible arm64 architecture.",
  "retryable": false
}

For that exact input, lipo -detailed_info exited 0 and reported FAT magic, one x86_64 slice, offset 4096, size 4320 and alignment 4096. REA's thin x86_64 control exited 0 with one exhaustive row and subject mach-o. The mixed universal control exited 0 with two exhaustive rows and subject mach-o-universal; its x86_64 row had the same offset, size and alignment as the rejected container's slice.

The submitter fetched upstream main at e84468c0bb0476412ac0c8161f7c2ecc9a6864ca; the cited admission, inventory and contract files were unchanged from the reproduced baseline.

Typed outcome or recovery expected

The same foreign-only FAT input should exit 0 with exactly its x86_64 inventory row, coordinates matching lipo -detailed_info, exhaustive coverage, a mach-o-universal subject and native-tool provenance. Thin and mixed controls should retain their successful results. Malformed containers should remain rejected. These are proposed restoration checks, not checks of a fix.

Analysis or suspected cause

Source-derived reasoning: src/domain/binaryTarget.ts:158 rejects FAT files with no host-compatible slice during target admission, reached through src/application/binary/BinarySessionOpen.ts:81 and src/application/BinaryTargetResolver.ts:205. This happens before src/native/NativeMacOSProvider.ts:511 can run lipo -detailed_info on the container. The observed thin and mixed controls distinguish this early rejection from unsupported x86_64 data or an unavailable native utility.

Additional context

This report concerns only list-architectures. It does not claim that selected-slice inspection should ignore host compatibility.

Originally created by @coygeek on GitHub (Oct 20, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/5404 ### Before submitting - [x] I searched the open and closed issues for a related report. - [x] I removed credentials, tokens, private paths, and sensitive target data. ### Area Native analysis or decompilation ### Observed behavior On an arm64 Mac, `node scripts/rea.mjs list-architectures "$work/universal-only-x86_64.bin" --format json` exits 1 without an inventory for a valid universal Mach-O containing only an x86_64 slice. Apple's `lipo -detailed_info` reads the same container successfully. REA successfully inventories the original thin x86_64 image and a universal container containing both x86_64 and arm64. An independent verifier ran each of the three REA invocations once. This report was prepared with AI assistance from that independently reproduced result. ### Reproduction From the source checkout with dependencies installed and the runtime built, on macOS arm64 with Apple's `cc` and `lipo` available: ```sh work="$(mktemp -d)" cc -O0 tests/fixtures/native-macos/native-macho-header/fixture.c -o "$work/sample-x86_64" -arch x86_64 lipo -create "$work/sample-x86_64" -output "$work/universal-only-x86_64.bin" lipo -detailed_info "$work/universal-only-x86_64.bin" node scripts/rea.mjs list-architectures "$work/universal-only-x86_64.bin" --format json ``` These commands use the repository's existing C fixture. The verifier used the existing built CLI with isolated home, XDG and temporary directories. The binaries were inspected without executing them; no external API or deep-analysis engine was used. The failing CLI call reproduced once in one independent run. ### Expected behavior Return the container's x86_64 slice with its container-relative offset, size, alignment, exhaustive coverage and native-tool provenance, regardless of whether the host has a matching slice. This expectation follows the source contract in `src/contracts/native/nativeToolContracts.ts:119`, which advertises thin or universal Mach-O slice inventory, and `docs/native-investigation.md:311`, which identifies even one-slice FAT inputs as `mach-o-universal` and describes container-relative architecture offsets. ### Impact and scope P2: callers cannot obtain any REA architecture inventory for the tested valid x86_64-only FAT container on an arm64 host. Thin x86_64 and mixed x86_64/arm64 controls succeed. `lipo -detailed_info` is a verified workaround that preserves the original container's coordinates. Extracting the x86_64 slice and inventorying the thin copy also succeeded, but changes the coordinate context. Other architecture combinations and the MCP interface were not replayed. No security boundary was crossed. ### REA version `rea-agents` 6.7.0; source commit `074768901f3cdc8205b61773fb1faf6f6c7b3ca8`. ### Runtime and platform Node.js v26.12.0; macOS 27.0.1; arm64. Apple's `cc` and `lipo` were available. Hopper/Ghidra were not used. ### Target and artifact context A single-slice universal/FAT Mach-O executable produced with `lipo -create` from an x86_64 build of `tests/fixtures/native-macos/native-macho-header/fixture.c`. Controls were the original thin executable and an arm64+x86_64 universal executable built from that same fixture. ### Interface CLI ### Earliest failure stage Setup or provider admission ### Relevant output or evidence The failing CLI call returned exit 1 and these JSON fields; path-bearing details are omitted: ```json { "error": "Analysis failed", "code": "target_unavailable", "category": "unsupported_target", "message": "Cannot open artifact: FAT binary has no host-compatible arm64 architecture.", "retryable": false } ``` For that exact input, `lipo -detailed_info` exited 0 and reported FAT magic, one x86_64 slice, offset 4096, size 4320 and alignment 4096. REA's thin x86_64 control exited 0 with one exhaustive row and subject `mach-o`. The mixed universal control exited 0 with two exhaustive rows and subject `mach-o-universal`; its x86_64 row had the same offset, size and alignment as the rejected container's slice. The submitter fetched upstream main at `e84468c0bb0476412ac0c8161f7c2ecc9a6864ca`; the cited admission, inventory and contract files were unchanged from the reproduced baseline. ### Typed outcome or recovery expected The same foreign-only FAT input should exit 0 with exactly its x86_64 inventory row, coordinates matching `lipo -detailed_info`, exhaustive coverage, a `mach-o-universal` subject and native-tool provenance. Thin and mixed controls should retain their successful results. Malformed containers should remain rejected. These are proposed restoration checks, not checks of a fix. ### Analysis or suspected cause Source-derived reasoning: `src/domain/binaryTarget.ts:158` rejects FAT files with no host-compatible slice during target admission, reached through `src/application/binary/BinarySessionOpen.ts:81` and `src/application/BinaryTargetResolver.ts:205`. This happens before `src/native/NativeMacOSProvider.ts:511` can run `lipo -detailed_info` on the container. The observed thin and mixed controls distinguish this early rejection from unsupported x86_64 data or an unavailable native utility. ### Additional context This report concerns only `list-architectures`. It does not claim that selected-slice inspection should ignore host compatibility.
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#3274
No description provided.