[PR #1536] [MERGED] feat(jeb): add JEB engine provider over its MCP interface #2953

Closed
opened 2026-10-17 21:12:12 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/1536
Author: @3QL
Created: 10/10/2026
Status: ✅ Merged
Merged: 10/10/2026
Merged by: @morluto

Base: main ← Head: feat/jeb-provider


📝 Commits (9)

  • 7b30045 feat(jeb): add JEB engine provider over its MCP interface
  • 30e0839 fix(jeb): verify against a real signed APK and fix CLI option surface
  • 8eaae77 fix(jeb): preserve engine refusals through the real MCP boundary
  • 4cd4cda docs(jeb): record Flutter Gallery verification on the real-engine lane
  • f583746 docs(jeb): translate the README JEB row for every supported language
  • 9f50282 fix(jeb): enforce local endpoints and preserve cancellation
  • 1f2cf23 Merge remote-tracking branch 'origin/main' into HEAD
  • 5aed198 fix(jeb): refuse redirects across the local MCP boundary
  • e2aff7b Merge remote-tracking branch 'origin/main' into HEAD

📊 Changes

48 files changed (+2051 additions, -4 deletions)

View changed files

📝 README.md (+1 -0)
📝 README_ar.md (+1 -0)
📝 README_de.md (+1 -0)
📝 README_es.md (+1 -0)
📝 README_fa.md (+1 -0)
📝 README_fr.md (+1 -0)
📝 README_id.md (+1 -0)
📝 README_ja.md (+1 -0)
📝 README_ko.md (+1 -0)
📝 README_pl.md (+1 -0)
📝 README_pt-BR.md (+1 -0)
📝 README_ru.md (+1 -0)
📝 README_th.md (+1 -0)
📝 README_tr.md (+1 -0)
📝 README_uk.md (+1 -0)
📝 README_vi.md (+1 -0)
📝 README_zh-TW.md (+1 -0)
📝 README_zh.md (+1 -0)
➕ docs/jeb-analysis.md (+36 -0)
📝 docs/testing.md (+19 -0)

...and 28 more files

📄 Description

feat(jeb): add JEB engine provider over its MCP interface

Summary

  • Add a bring-your-own JEB provider that serves project, unit, and decompilation inspection from a caller-started JEB client speaking MCP (streamable HTTP, selected with REA_JEB_MCP_URL, default http://127.0.0.1:8425/mcp). REA never installs or launches JEB.
  • Expose four provider-neutral operations through the shared CLI/MCP workflows, each returning Evidence with engine identity, endpoint, caller-selected parameters, and preserved refusal reasons: inspect_jeb_client, open_jeb_project, list_jeb_units, decompile_jeb_item (CLI: inspect-jeb-client, open-jeb-project, list-jeb-units, decompile-jeb-item).
  • Keep JEB's envelope semantics at the boundary: success fields parsed format-aware, message-only refusals mapped to unsupported-target errors carrying the engine's own reason, transport failures mapped to availability failures with recovery guidance, and unit pagination deriving coverage from the engine's real 100-item page cap. Explicit unknowns (implicitly selected unit, omitted filters) are reported instead of guessed.
  • Add scripts/verify-jeb.mjs (npm run verify:jeb), a docs/jeb-analysis.md guide, capability-inventory availability with recovery guidance, catalog registration, and translated README rows.

Verification

  • npm run build:cached
  • npm run test:focused -- src/contracts/jeb/jebToolContracts.test.ts src/application/jeb/JebAnalysisService.test.ts src/jeb/JebMcpConnection.test.ts src/jeb/JebProvider.test.ts tests/boundary/cli/jebCli.test.ts tests/boundary/mcp/jebMcp.test.ts tests/boundary/cli/productCatalog.test.ts (38 tests)
  • npm run check:fast
  • npm run docs:check

Real JEB verification was performed (no real Hopper/Ghidra claims in this change): a licensed JEB 5.48.0 build serving jeb-mcp-server 1.3.0 headless over streamable HTTP, driven through the public CLI, the MCP boundary over stdio with the pinned client SDK, and npm run verify:jeb, at four target scales:

  1. Compiled Java class fixture (unit identity, decompilation marker).
  2. Locally built signed probe APK — manifest, v1/v2/v3 certificates, dex, filtered/paginated/parent-restricted unit listing, activity method decompilation (dexdec inline constant folding observed).
  3. Published Signal 8.30.3 universal release APK (109 MB, R8 Kotlin/Compose, four signature schemes, native arm64 ELF units) — MainActivity.onCreate (7 KB pseudo-code) and R8 synthetic lambdas decompiled through both adapters. This target exposed and validated the refusal-preservation fix in decodeJebToolResult.
  4. Official Flutter Gallery 2.9.2 release APK (112 MB) — per-ABI libapp.so Dart AOT snapshot images analyzed as native code (75,205 methods on arm64), snapshot internals decompiled with explicit unit selection through both adapters, thin Java wrapper, decoded manifest.

Engine coverage notes

  • JEB 5.48.0 headless instances do not advertise open_project or run_script; the target is selected when the engine client starts (--infile on the documented programmatic launcher, or the GUI). REA preserves the engine's exact refusal instead of failing opaquely, and docs/jeb-analysis.md documents the boundary. The dedicated Dart snapshot processor (IDartAotUnit) is likewise GUI-only; native libapp.so analysis is what REA serves headless.
  • The IDA-style mutation surface the engine also offers (renames, comments, save_project/close_project) is intentionally not exposed in this slice.

Sanitized MCP example

> client.callTool({ name: "decompile_jeb_item", arguments: {
    item_address: "Lorg/thoughtcrime/securesms/MainActivity;->onCreate(Landroid/os/Bundle;)V",
    item_kind: "method",
    unit_path: "signal.apk/org.thoughtcrime.securesms/Bytecode"
  } })
< { "normalized_result": { "engine": { "name": "jeb", "version": "5.48.0.202610071539",
      "endpoint": "http://127.0.0.1:8425/mcp", "gui_client": false },
      "unit_path": "signal.apk/org.thoughtcrime.securesms/Bytecode",
      "item_address": "…onCreate(Landroid/os/Bundle;)V", "item_kind": "method",
      "text": "@Override  // org.thoughtcrime.securesms.PassphraseRequiredActivity\npublic void onCreate(…" },
    "confidence": "derived",
    "limitations": ["Artifact identity is unavailable for this observation."] }

🔄 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/1536 **Author:** [@3QL](https://github.com/3QL) **Created:** 10/10/2026 **Status:** ✅ Merged **Merged:** 10/10/2026 **Merged by:** [@morluto](https://github.com/morluto) **Base:** `main` ← **Head:** `feat/jeb-provider` --- ### 📝 Commits (9) - [`7b30045`](https://github.com/morluto/rea/commit/7b300456f949c0942539ce1220495209164007c6) feat(jeb): add JEB engine provider over its MCP interface - [`30e0839`](https://github.com/morluto/rea/commit/30e08394e8cfe60984612b3f7b3a30d7671b2aaa) fix(jeb): verify against a real signed APK and fix CLI option surface - [`8eaae77`](https://github.com/morluto/rea/commit/8eaae775cb003a072ad924601d82aca8660eb414) fix(jeb): preserve engine refusals through the real MCP boundary - [`4cd4cda`](https://github.com/morluto/rea/commit/4cd4cda83219def86063a062f4f6f6a5aa84d877) docs(jeb): record Flutter Gallery verification on the real-engine lane - [`f583746`](https://github.com/morluto/rea/commit/f583746dd0d196957ab9153bf812c59bd62d28d2) docs(jeb): translate the README JEB row for every supported language - [`9f50282`](https://github.com/morluto/rea/commit/9f5028269295c0088318d19328d8c40b4f817715) fix(jeb): enforce local endpoints and preserve cancellation - [`1f2cf23`](https://github.com/morluto/rea/commit/1f2cf23c3563c2441a2a0b2151ed7d6427cf0f50) Merge remote-tracking branch 'origin/main' into HEAD - [`5aed198`](https://github.com/morluto/rea/commit/5aed1987bc40b0bdc2a003c3b4aa12c82bbe0f45) fix(jeb): refuse redirects across the local MCP boundary - [`e2aff7b`](https://github.com/morluto/rea/commit/e2aff7ba3e315dedc097f4a343414327b9222f22) Merge remote-tracking branch 'origin/main' into HEAD ### 📊 Changes **48 files changed** (+2051 additions, -4 deletions) <details> <summary>View changed files</summary> 📝 `README.md` (+1 -0) 📝 `README_ar.md` (+1 -0) 📝 `README_de.md` (+1 -0) 📝 `README_es.md` (+1 -0) 📝 `README_fa.md` (+1 -0) 📝 `README_fr.md` (+1 -0) 📝 `README_id.md` (+1 -0) 📝 `README_ja.md` (+1 -0) 📝 `README_ko.md` (+1 -0) 📝 `README_pl.md` (+1 -0) 📝 `README_pt-BR.md` (+1 -0) 📝 `README_ru.md` (+1 -0) 📝 `README_th.md` (+1 -0) 📝 `README_tr.md` (+1 -0) 📝 `README_uk.md` (+1 -0) 📝 `README_vi.md` (+1 -0) 📝 `README_zh-TW.md` (+1 -0) 📝 `README_zh.md` (+1 -0) ➕ `docs/jeb-analysis.md` (+36 -0) 📝 `docs/testing.md` (+19 -0) _...and 28 more files_ </details> ### 📄 Description # feat(jeb): add JEB engine provider over its MCP interface ## Summary - Add a bring-your-own JEB provider that serves project, unit, and decompilation inspection from a caller-started JEB client speaking MCP (streamable HTTP, selected with `REA_JEB_MCP_URL`, default `http://127.0.0.1:8425/mcp`). REA never installs or launches JEB. - Expose four provider-neutral operations through the shared CLI/MCP workflows, each returning Evidence with engine identity, endpoint, caller-selected parameters, and preserved refusal reasons: `inspect_jeb_client`, `open_jeb_project`, `list_jeb_units`, `decompile_jeb_item` (CLI: `inspect-jeb-client`, `open-jeb-project`, `list-jeb-units`, `decompile-jeb-item`). - Keep JEB's envelope semantics at the boundary: success fields parsed format-aware, message-only refusals mapped to unsupported-target errors carrying the engine's own reason, transport failures mapped to availability failures with recovery guidance, and unit pagination deriving coverage from the engine's real 100-item page cap. Explicit unknowns (implicitly selected unit, omitted filters) are reported instead of guessed. - Add `scripts/verify-jeb.mjs` (`npm run verify:jeb`), a `docs/jeb-analysis.md` guide, capability-inventory availability with recovery guidance, catalog registration, and translated README rows. ## Verification - `npm run build:cached` - `npm run test:focused -- src/contracts/jeb/jebToolContracts.test.ts src/application/jeb/JebAnalysisService.test.ts src/jeb/JebMcpConnection.test.ts src/jeb/JebProvider.test.ts tests/boundary/cli/jebCli.test.ts tests/boundary/mcp/jebMcp.test.ts tests/boundary/cli/productCatalog.test.ts` (38 tests) - `npm run check:fast` - `npm run docs:check` **Real JEB verification was performed** (no real Hopper/Ghidra claims in this change): a licensed JEB 5.48.0 build serving `jeb-mcp-server` 1.3.0 headless over streamable HTTP, driven through the public CLI, the MCP boundary over stdio with the pinned client SDK, and `npm run verify:jeb`, at four target scales: 1. Compiled Java class fixture (unit identity, decompilation marker). 2. Locally built signed probe APK — manifest, v1/v2/v3 certificates, dex, filtered/paginated/parent-restricted unit listing, activity method decompilation (dexdec inline constant folding observed). 3. Published Signal 8.30.3 universal release APK (109 MB, R8 Kotlin/Compose, four signature schemes, native arm64 ELF units) — `MainActivity.onCreate` (7 KB pseudo-code) and R8 synthetic lambdas decompiled through both adapters. This target exposed and validated the refusal-preservation fix in `decodeJebToolResult`. 4. Official Flutter Gallery 2.9.2 release APK (112 MB) — per-ABI `libapp.so` Dart AOT snapshot images analyzed as native code (75,205 methods on arm64), snapshot internals decompiled with explicit unit selection through both adapters, thin Java wrapper, decoded manifest. ## Engine coverage notes - JEB 5.48.0 headless instances do not advertise `open_project` or `run_script`; the target is selected when the engine client starts (`--infile` on the documented programmatic launcher, or the GUI). REA preserves the engine's exact refusal instead of failing opaquely, and `docs/jeb-analysis.md` documents the boundary. The dedicated Dart snapshot processor (`IDartAotUnit`) is likewise GUI-only; native `libapp.so` analysis is what REA serves headless. - The IDA-style mutation surface the engine also offers (renames, comments, `save_project`/`close_project`) is intentionally not exposed in this slice. ## Sanitized MCP example ``` > client.callTool({ name: "decompile_jeb_item", arguments: { item_address: "Lorg/thoughtcrime/securesms/MainActivity;->onCreate(Landroid/os/Bundle;)V", item_kind: "method", unit_path: "signal.apk/org.thoughtcrime.securesms/Bytecode" } }) < { "normalized_result": { "engine": { "name": "jeb", "version": "5.48.0.202610071539", "endpoint": "http://127.0.0.1:8425/mcp", "gui_client": false }, "unit_path": "signal.apk/org.thoughtcrime.securesms/Bytecode", "item_address": "…onCreate(Landroid/os/Bundle;)V", "item_kind": "method", "text": "@Override // org.thoughtcrime.securesms.PassphraseRequiredActivity\npublic void onCreate(…" }, "confidence": "derived", "limitations": ["Artifact identity is unavailable for this observation."] } ``` --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-17 21:12:12 +00:00
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#2953
No description provided.