1.1

rea, providers, and Evidence

rea standardizes the question, the session, and the Evidence record, and leaves import, analysis, and decompilation to the engine it binds, here Ghidra 12.1.4.

You compiled ledger.c with clang -O1, and you want to know what the machine code of percent_change does when before is 0. You can open the file in Ghidra and read the listing yourself. You can also ask rea, and rea asks Ghidra for you and returns one record that says what it found and how it knows. This section draws the line between the two programs.

When you finish this section, you can name what rea adds to Ghidra, what it never does, and which adapter to use for one question.

Three things rea standardizes

Evidence: the one record type that every successful analysis call returns. It is a strict object with 16 fields. The fields are evidence_id, subject, provider, analysis_profile, predicate_type, operation, parameters, raw_result, normalized_result, confidence, authority, environment, limitations, relationship_coverage, locations, and evidence_links.

The id is ev_ and a SHA-256 of the semantic content. The same observation of the same bytes gets the same id on any machine. The id covers relationship_coverage also when its value is null. So a record from an older rea can fail the check in a newer one (section 5.4). confidence is one of observed, derived, or inferred, and authority says what kind of source backs the fact.

The MCP docs set the rule for tools. A tool that produces evidence returns the full canonical Evidence record twice: once as text and once as structured content. Section 1.2 reads one record field by field, and Part 5 covers the record in full.

Provider: an analysis engine behind one interface. GhidraProvider implements AnalysisProviderCandidate and offers identity(), capabilities(), inspectAvailability(), inspectTargetSupport(target), resolveAnalysisProfile(...), and createClient(...). At 6.7.0 the session holds four deep providers, hopper, ghidra, ida, and kuna, plus auxiliary providers that need no engine. This manual uses only ghidra. Kuna is a program that you install yourself, its recorded coverage is on Linux, and the capture Mac reports it not_configured.

The registry sorts candidates by id and selects one without starting it. The order of registration never changes the choice or what the caller sees. Once bound, a provider stays bound: rea does not swap in another provider after a runtime failure.

Adapter: the way a caller reaches the session. The one-shot CLI has 153 commands and one alias, and the MCP server has 207 tools and 6 prompts. The capture's server_identity.catalog.counts reports those numbers (the capture). Both adapters share one BinarySession, which owns the one active target for the CLI and the MCP server. CLI names use hyphens and MCP names use _ between words. The native family breaks the rule: rea function calls analyze_function, rea decompile calls procedure_pseudo_code, and rea analyze calls binary_overview.

rea does not plan an investigation for you. The maintainers write the split in their roadmap (rea issue 32). The agent chooses the target and builds the investigation from inspection, capture, tracing, and comparison results. The same text asks tool results to keep observations, inferences, and unknowns apart. So the plan stays with you or your agent, and rea answers each question with a record that you can check.

The capture used both adapters on the same file:

four one-shot commands and their exit statustextFull log
$ rea doctor --provider ghidra --format json --filter-output healthy,environment_healthy,scope,scope_checks
[exit 0] (… s) -> 01-doctor-ghidra.json

$ rea capabilities --format json
[exit 0] (… s) -> 02-capabilities.json

$ rea inspect-artifact fixtures/ledger-arm64-O1 --format json
[exit 0] (… s) -> 03-inspect-artifact.json

$ rea inspect-binary-layout fixtures/ledger-x86_64-O1.o --format json
[exit 1] (… s) -> 04-inspect-binary-layout.json
…
Cut to the first four commands. The time of each command is cut, because it changes with every recording, and the other commands are cut.

The first three commands finish in about one second, because none of them starts Ghidra. The fourth fails, and section 3.2 explains why. Figure 1.1 places each name on its side of the line.

Fig. 1.1what rea standardizes and what it leaves to Ghidralayers
What rea standardizes and what it leaves to Ghidra Two stacks under one host band for macOS 26.2 arm64 with Node 22.22.0 and JDK 21.0.12.1. The left stack is rea 6.7.0: the CLI and MCP adapters with 153 commands, 207 tools, and 6 prompts over one BinarySession, the session with one target and one bound provider that the registry selects and never replaces, the Evidence record with 16 fields and an ev_ content hash kept in the EvidenceLedger, the Zod contracts and the error projection with code, category, message, and retryable, and the GhidraProvider and GhidraClient that send JSON lines over bridge.sock. The right stack is Ghidra 12.1.4: ReaGhidraBridge.java as the last post-script, the analyzeHeadless import with the loader chosen from the header, the FunctionManager, ReferenceManager, and BasicBlockModel that found 13 procedures and 39 strings, the DecompInterface with the native decompile binary for mac_arm_64, and the Program database deleted on close. The bottom band is the artifact ledger-arm64-O1 and its private copy target-01b5d08b08fb.bin. host · macOS 26.2 arm64 · Node 22.22.0 · JDK 21.0.12.1 · GHIDRA_INSTALL_DIR set REA 6.7.0 · WHAT IT STANDARDIZES GHIDRA 12.1.4 · WHAT REA LEAVES TO IT CLI and MCP 153 commands, 207 tools, 6 prompts one BinarySession behind both BinarySession one target, one bound provider the registry selects, never replaces Evidence 16 fields, ev_ content hash EvidenceLedger, snapshots, bundles contracts and errors Zod schemas for every tool code, category, message, retryable GhidraProvider, GhidraClient profile digest, private copy JSON lines over bridge.sock ReaGhidraBridge.java a GhidraScript, the last -postScript one Program, one socket client analyzeHeadless import loader chosen from the header -readOnly, default auto-analysis FunctionManager, ReferenceManager BasicBlockModel, Listing text 13 procedures, 39 strings here DecompInterface, decompile native binary for mac_arm_64 pseudocode and high p-code the Program database addresses, symbols, references deleted on close: -deleteProject ledger-arm64-O1 mach-o arm64, 33872 bytes sha256 starts 01b5d08b target-01b5d08b08fb.bin the private copy Ghidra imports same bytes, deleted on close
rea owns the adapters, the session, and the Evidence record, and Ghidra owns import, analysis, and decompilation, with one JSON line per question between them. Read each stack from the top down. The counts come from the capabilities and overview captures, and the file names from the fixture list. The class names come from the architecture diagram of rea at the tag.

What rea leaves to Ghidra

rea has no disassembler and no decompiler of its own. For a native executable it starts analyzeHeadless on a fresh temporary project and imports a private copy of the file. It lets Ghidra's default auto-analysis run, and then it asks questions over a socket. The answers are Ghidra's.

Every analyze_function record says in its limitations that the function dossier joins what the Ghidra FunctionManager, Listing, ReferenceManager, BasicBlockModel, and decompiler reported (the capture). The provider docs draw the same line. The pseudocode is what the Ghidra decompiler produced, and neither it nor the assembly is the original source.

Bridge: ReaGhidraBridge.java, a GhidraScript that analyzeHeadless runs as its last post-script and that then serves requests on a Unix socket. A request is one JSON line, { id, token, method, params }, and a reply is { id, ok: true, result } or { id, ok: false, error }. The bridge answers 17 inventory methods and 13 function methods through one Java switch. Part 4 follows each of them.

Ghidra also owns the cost. Each one-shot command that needs Ghidra took 7 to 9 s on the capture Mac (the captures). The import and the auto-analysis take most of that time. Inside one MCP session the first Ghidra call took 5 to 7 s (the captures). Every later call on the same file took under 100 ms.

What rea reads by itself

Before any engine runs, rea reads the file. It detects ELF from 7f 45 4c 46, MZ, and the four Mach-O magic values. It hashes every target with SHA-256 in 64 KiB chunks. It knows ten architectures: x86, x86_64, arm, arm64, mips, 6502, riscv, powerpc, m68k, and hexagon. A raw binary has no header, so the caller names its architecture. Only a raw binary can be 6502 or big-endian m68k, and its entry address must suit the processor.

Two commands show the result without Java. rea inspect-artifact walks the file with the provider rea-artifact-graph and returns an Evidence record in under a second, without Java (the capture). On macOS, rea inspect-macho runs the Xcode tools through xcrun and took about three seconds (the capture). Part 3 reads those records.

Formats beyond native code

rea has three more readers that this manual touches. inspect-wasm-artifact reads a WebAssembly module through the WABT tools. inspect-go-binary reads Go build information. The raw-binary format opens a file that has no header, at an architecture and an entry address that you name. The capture ran inspect-wasm-artifact on the fixture module, and the command exited 0 (the capture). Section 6.2 reads that record.

rea (rea-agents) with the Ghidra provider rea-agents 6.7.0, Ghidra 12.1.4 · 27dc42d · 2026-10-18 · Edition 2026.10