Dev.to Security 🔐 Cybersecurity 👁 0 📖 7 min read

REA Evidence IDs Changed Between 6.7 and 6.8 — I Measured Exactly What Survives

If your analysis tool hands you receipts — input hashes, pinned library versions, content-addressed IDs — then a version upgrade is not just a changelog event. Every proof you attached to a report last month was minted b

If your analysis tool hands you receipts — input hashes, pinned library versions, content-addressed IDs — then a version upgrade is not just a changelog event. Every proof you attached to a report last month was minted by a specific version of the tool, and the quiet question nobody answers in release notes is: what happens to those proofs when the tool moves?

So before I let REA 6.8.0 anywhere near my working notes, I re-ran the same artifacts through 6.7.0 and 6.8.0 on the same machine, same day, and compared the receipts line by line.

Short version: the evidence IDs are version-scoped — same input bytes, different tool version, different ID. The read side of the contract held: a bundle exported under 6.7.0 re-exported cleanly under 6.8.0. And the fail-closed refusals — errors that name their cause instead of guessing — carried over as the best part of the design.

Disclosure up front: I run an independent, non-affiliated tutorial site for REA (Reverse Engineer Anything); everything below comes from runs I executed myself on 2026-10-26, with baseline records from 2026-10-12. The single link to my site is at the end of this article. No affiliation with the REA developers, no affiliate links anywhere.

The contract in one command

For context: REA is an agent-first reverse-engineering toolkit. Every analysis it runs emits an evidence record, and the record reads like a contract — every field is a promise. Here's one from my 2026-10-12 baseline (6.7-era tooling), inspecting a self-compiled hello ELF:

$ rea inspect-binary-layout hello
ok evidence_id: ev_6e479c83fba06374c38ab8f9fa3876e561d28d3515aa68473598e9f94dcb556c
  subject: hello / sha256 36cdabb6…4207352 / elf / x86_64
  provider: pwntools-elf @ pwntools 4.15.0;pyelftools 0.33;unicorn 2.1.2
  normalized_result: 31 sections, entry_point 0x400320

Four claims, four proofs:

  • evidence_id — content-addressed: derived from the record itself, so the ID is the integrity check. Change one input byte and a different ID proves it.
  • subject sha256 — exactly which bytes were analyzed. "I analyzed this file" becomes "I analyzed the file with this hash."
  • provider + pinned versions — pwntools 4.15.0, pyelftools 0.33, Unicorn 2.1.2, to the patch number. Anyone reproducing your run knows precisely what to install.
  • normalized_result — the finding, in a form your own binutils can check. I cross-checked that 31-section count against manual readelf output on the same binary, and they agreed.

That last point is the discipline that makes the rest of this post measurable: before trusting the tool's IDs, I had my own ground truth for the same bytes.

The experiment: same bytes, two versions

The setup was deliberately boring. One Linux box (OpenCloudOS 9.4, x86_64, Node 22.22.0), two isolated installs — one pinned to 6.7.0, one to 6.8.0, separate node_modules trees so nothing could leak between them — and two analysis subjects whose bytes I fixed before starting:

  • hello — the self-compiled ELF above, sha256 36cdabb6…4207352
  • lab08-session.har — a recorded web-session capture, sha256 d2e45b8d…c88b76e

Same commands into both versions. The IDs that came out:

subject 6.7.0 evidence_id 6.8.0 evidence_id
inspect-binary-layout hello ev_79a48ab6902dcd75…9670b ev_5cad21e9933f327f…c0cec
inspect-web-network-capture lab08.har ev_a94aa7273d27a8af…cdb9e ev_d864f4a7df7c4946…ef14e

Same bytes in, different IDs out, on both subjects. That is a contract change between versions — the derivation itself was touched, not just the tool surface. (I'm showing truncated IDs here; the full strings sit in my dated lab records.)

Fresh artifacts minted under 6.8.0 behaved the same way. The capture inspection above returned ev_d864f4a7df7c4946…ef14e, and two brand-new analysis views — environment-manifest and environment-state, neither of which exists in the 6.7.0 view enumeration — each minted their own IDs (ev_a70dc817…18d396 and ev_37de4d01…c651ddf). New surface, same rule: the ID is bound to the record and the version that produced it.

What survived: the read side

Here's the part that matters more than the ID churn: backward compatibility on the verification path.

A bundle my lab had exported under 6.7.0 — hello-bundle-670.json — went through 6.8.0's rea evidence-export without complaint: validation passed, records: 1, 39,142 bytes. Contrast that with the 6.4→6.7 transition in my records, where the exporter refused older material with evidence_integrity_mismatch.

So the current behavior splits cleanly into two rules:

  • Mint is version-scoped. New evidence IDs differ per version, even for identical input bytes.
  • Read is compatible. Existing bundles stay verifiable across this particular upgrade.

The practical meaning: your old archives remain checkable, but your new claims are only comparable within one version. If a colleague's evidence_id doesn't match yours for the same artifact, check tool versions before you suspect corruption — that mismatch is exactly what my two-version table looks like.

Fail-closed carried over — and that's the feature

A contract is only worth something if it refuses to sign bad paper. The refusals I hit on 6.8.0, all by running the tool, all with named causes:

1. Summary delivery requires evidence. rea function hello main --detail summary is rejected at the schema level unless you also pass --evidence_output:

invalid_request / issues[0]: path evidence_output, invalid_value
"Summary delivery requires --evidence_output so complete source
 Evidence remains available."

Spelling trap worth flagging: the hyphenated --evidence-output is an Unknown flag; the underscore form is the real one. With the flag correctly supplied and no deep-analysis engine installed, the call then fails with provider_unavailable — a plain refusal, no silent degradation to a weaker answer.

2. JSONL wants collections. Asking inspect-binary-layout for --format jsonl doesn't emit a mangled partial record; it emits one structured error envelope:

{"$rea":"jsonl/v1","type":"error","ok":false,
 "result":{"code":"unreadable_output",
 "reason":"JSON Lines requires an array or one explicit rows, items,
 records, or occurrences collection."}}

…plus a remediation line: use --format json for the complete document, or select one record collection with --filter-output. Even the error path wears the same envelope as success paths — machine-parseable all the way down.

3. Raw records are not bundles. Feeding a single evidence record straight into evidence-export gets rejected with wrong-kind and a pointer to the right path: export a session bundle with the MCP export_evidence_bundle tool first. The CLI and MCP channels have different jobs, and the tool refuses to let you blur them.

4. Ceiling configs fail loudly. Setting REA_MCP_MAX_RESPONSE_BYTES=1 refuses at startup: "REA configuration is invalid: REA_MCP_MAX_RESPONSE_BYTES: Too small: expected number to be >=10485760." The default is 10 MiB and it's a floor, not a target — 20 MiB validates fine. Its sibling REA_BRIDGE_MAX_REQUEST_BYTES defaults to 16 MiB with a valid range of 7,464 to 536,870,887 bytes, and an invalid value surfaces as a named runtime-configuration check in rea mcp doctor.

That last command deserves its own spotlight: on 6.8.0, rea mcp doctor reported healthy with tools 229/229 expected-and-observed, prompts 6/6, and a catalog digest where expected equals observed (fe938a7c…). You can verify the tool surface itself, not just the analyses — the protocol level (2025-11-25) is part of the audited surface too.

Context: what 6.8.0 actually added

Quick orientation, because the contract narrative shouldn't hide the release. rea-agents 6.8.0 shipped on 2026-10-25 (GitHub tag 08:36 UTC, npm 09:07 UTC). Tool count went 207 → 229 (+22), and the CLI command catalog moved 170 → 175 across the same span in my doctor diffs.

The big one for agent builders: the environment toolchain — environment-serve, environment-export, environment-build, environment-compare — now ships in the npm package. I served a recorded web session as a local MCP endpoint over streamable HTTP and the replay was exact: calling get_users returned the recorded 200 response body with replay.exact_match: true; calling get_users_by_id with id 99 faithfully replayed the recorded 404. When I poked the endpoint with a malformed agentenv call, it answered -32600 invalid request — fail-closed even at the transport layer. environment-export produced a runnable directory (README, env.toml, Dockerfile, manifest, evidence bundle, verification scripts, smoke task), and environment-build did the same job in one step from the capture file.

One upgrade blocker to know first: the Node engines requirement moved to ^22.23.4 || ^24.22.1 || >=26.12.1. My box runs Node 22.22, so rea doctor flags missing_dependency — the analyses themselves ran fine, but if your pipeline gates on doctor health, upgrade Node before you upgrade REA.

What this means for your evidence hygiene

Three rules I'm adopting in my own lab after this run:

  1. Treat evidence_id as version-scoped. Never compare IDs across REA versions and call the mismatch corruption. Compare subject sha256 and normalized_result instead — those stayed stable across my two-version run.
  2. Pin the tool version in every bundle you hand off. The provider block already records exact library versions; the REA version itself belongs in your report header, next to the date.
  3. Re-baseline after upgrades. An upgrade is a contract event. One re-run of your standing artifacts, diff the old IDs against the new, note the replacements — twenty minutes of work that keeps every future claim comparable.

If you build checker scripts on top of evidence bundles: verify the envelope framing constants first, compare normalized results against your own tools (readelf agreed with every section count in my runs), and only then look at IDs — within a single version.

Verdict

The evidence contract is the reason I put up with re-baselining. A tool that mints proof per version and still verifies yesterday's bundles is behaving exactly like a versioned artifact store should: mint scoped, read compatible, refuse loudly. Most analysis tools show you an answer. This one shows you an answer plus receipts — and after watching receipts survive an upgrade with their verification path intact, I trust them more, not less.

The full walkthrough — every refusal quoted verbatim, the two-version ID table, and the bundle re-export log — lives on the evidence contract page of reaguide.online, the independent, non-affiliated REA tutorial site I run.

Facts, versions and numbers above come from lab runs dated 2026-10-26 (REA 6.8.0 baseline) and 2026-10-12 (6.7-era records). They will age.

📰 Read the original article on Dev.to Security

Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.