[PR #5662] [MERGED] feat(ghidra): bound one procedure's decompile without closing the session #7022

Closed
opened 2026-11-01 21:44:47 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/5662
Author: @RishTheFish21
Created: 10/20/2026
Status: ✅ Merged
Merged: 10/23/2026
Merged by: @gensokyo-dev

Base: main ← Head: feat/ghidra-decompile-timeout


📝 Commits (10+)

  • e067efd feat(ghidra): bound one procedure's decompile without closing the session
  • 0f2a2e5 fix(ghidra): report decompile limit as a request timeout
  • cb754c9 fix(ghidra): budget the decompile limit and report cancellation-closed sessions
  • 8c30e4c feat(ghidra): preserve sessions after bounded decompilation
  • 043110b fix(ghidra): align deadline bounds and cancellation outcomes
  • eceaa0b refactor(ghidra): shorten deadline recovery guidance
  • 5a10db4 fix(mcp): clarify the scope of inferred decompile deadlines
  • f19acf9 test(ghidra): verify deadline workflows and document measured costs
  • 87d634e merge: retain current main owners in Ghidra timeout integration
  • 2252af3 docs(ghidra): pin integration and distinguish baseline format failures

📊 Changes

33 files changed (+1306 additions, -45 deletions)

View changed files

📝 bridge/ghidra/ReaGhidraBridge.java (+32 -5)
📝 docs/client-configuration.md (+12 -2)
📝 docs/ghidra-provider.md (+1 -1)
📝 docs/installation.md (+22 -1)
📝 docs/mcp-contracts.md (+7 -0)
📝 docs/user-visible-errors.csv (+1 -0)
➕ docs/verification/ghidra-procedure-timeout-2026-10-23.md (+269 -0)
📝 knip.json (+1 -0)
➕ scripts/verify-real-ghidra-decompile-timeout.mjs (+275 -0)
📝 scripts/verify-real-ghidra-decompiler-failure.mjs (+24 -0)
📝 src/application/ClientRegistrationEnvironment.ts (+7 -0)
📝 src/application/ClientRegistrationStatus.ts (+11 -2)
📝 src/application/SetupRegistrationEnvironment.ts (+1 -0)
📝 src/config.test.ts (+43 -0)
📝 src/config/environment.ts (+2 -0)
📝 src/config/parseConfig.ts (+6 -0)
📝 src/config/providerStartupTimeout.ts (+15 -0)
📝 src/config/types.ts (+2 -0)
📝 src/contracts/enhancedToolContracts.ts (+3 -3)
📝 src/ghidra/GhidraLauncher.ts (+7 -0)

...and 13 more files

📄 Description

Fixes #5340.

An opt-in REA_GHIDRA_DECOMPILE_TIMEOUT_SECONDS bounds each native decompile without asking Ghidra to close the session. Unset remains unbounded; 1–2,147,483 whole seconds follows Ghidra's signed-int millisecond conversion.

Function dossiers retain listing facts, mark pseudocode/native API/value flow unavailable and remain live for retry. Atomic decompiles return the existing provider_timeout contract with retryable: true, timeout_ms and remote_code: decompile_timed_out. Caller cancellation still closes the session. Queue-owned wording preserves cancellation and incomplete-cleanup facts; Java regex failures describe engine facts, with lifecycle interpreted by the same provider owner.

The function capability advertises this optional control. Derived setup deadlines are single-decompile estimates. Multi-function calls, including trace_native_values, need allowance for every attempted function and other work; callers can select fewer functions, split/resume exports or change their client deadline. Existing positive deadlines are preserved. No tool schema changes.

Validation:

  • Full npm run check and docs:check passed on the published implementation; all 42 deadline/registration cases passed. The preceding provider/queue/session selection had 236 passes and one independently reproduced main SIGKILL wording failure.
  • Real Linux Ghidra 12.1.4 / JDK 21 lane: 41 Java checks, actual one-second-configured provider capability and complete cleanup. Old production fails the new capability and trace-advice assertions. The earlier pinned natural timeout, CLI/MCP, same-session reuse, two-item batch and maximum-setting export/resume observations are retained in the report. Refreshed full-inventory verification encounters an independent main symbol schema error; it is not claimed as passing.
  • Earlier paired complete MCP task: 237.602 → 95.388 s elapsed, 232.779 → 90.945 s waited CPU, 2051.3 → 2008.8 MiB sampled family RSS; estimated context 983,317 → 989,913 tokens (+0.67%). Avoiding re-imports explains this fixture's result. Later main/capability wording costs were not measured by that pair.
  • CI 40038742775: all 13 failed/cancelled job logs, aggregation and terminal diagnostics audited. All 1,066 visible assertion markers map to independently observed main failures. The intermittent Kuna doctor case has both passing and failing exact-base controls; its cancelled CI log lacks a full diagnostic, so diagnostic equality is not claimed. PR title/readiness checks pass. See the maintenance comment for attribution and the authorized CI bypass.

Verification report. Maintenance real-provider scope is Linux; Windows/macOS, natural regex overflow, long client timers and large-batch capacity remain unverified. Targets were never executed. The verifier rejects oversized fixture overrides before allocation using a 1 MiB generated-source budget.

Contribution scope: optional resource control within the existing static Ghidra workflow, with no new provider, target execution, injection, executable mutation or attached-GUI authority.

Author readiness

Human owner: @RishTheFish21

  • 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/5662 **Author:** [@RishTheFish21](https://github.com/RishTheFish21) **Created:** 10/20/2026 **Status:** ✅ Merged **Merged:** 10/23/2026 **Merged by:** [@gensokyo-dev](https://github.com/gensokyo-dev) **Base:** `main` ← **Head:** `feat/ghidra-decompile-timeout` --- ### 📝 Commits (10+) - [`e067efd`](https://github.com/morluto/rea/commit/e067efd6ed979285abebc7805cfc9341d84af094) feat(ghidra): bound one procedure's decompile without closing the session - [`0f2a2e5`](https://github.com/morluto/rea/commit/0f2a2e5e633908b7cb18f86fa0e1c0af4a060827) fix(ghidra): report decompile limit as a request timeout - [`cb754c9`](https://github.com/morluto/rea/commit/cb754c9258de3bd6a2c9da1bf71da63085a49288) fix(ghidra): budget the decompile limit and report cancellation-closed sessions - [`8c30e4c`](https://github.com/morluto/rea/commit/8c30e4c2bed6c1f908125c54dfa1187f3f1ec1fe) feat(ghidra): preserve sessions after bounded decompilation - [`043110b`](https://github.com/morluto/rea/commit/043110b85bc5e1af9f3c7de2856733885c67046c) fix(ghidra): align deadline bounds and cancellation outcomes - [`eceaa0b`](https://github.com/morluto/rea/commit/eceaa0b51bfdfa46a3382d5021840bece8dc22e9) refactor(ghidra): shorten deadline recovery guidance - [`5a10db4`](https://github.com/morluto/rea/commit/5a10db4b27b6ce38659121ee59ec75aa5afae271) fix(mcp): clarify the scope of inferred decompile deadlines - [`f19acf9`](https://github.com/morluto/rea/commit/f19acf941b906ac431377154126af0180a57c79a) test(ghidra): verify deadline workflows and document measured costs - [`87d634e`](https://github.com/morluto/rea/commit/87d634ef7fcfc427cdc7f62db30d220e88363f29) merge: retain current main owners in Ghidra timeout integration - [`2252af3`](https://github.com/morluto/rea/commit/2252af3b40760005fc3a52a5067c5189b0e409bd) docs(ghidra): pin integration and distinguish baseline format failures ### 📊 Changes **33 files changed** (+1306 additions, -45 deletions) <details> <summary>View changed files</summary> 📝 `bridge/ghidra/ReaGhidraBridge.java` (+32 -5) 📝 `docs/client-configuration.md` (+12 -2) 📝 `docs/ghidra-provider.md` (+1 -1) 📝 `docs/installation.md` (+22 -1) 📝 `docs/mcp-contracts.md` (+7 -0) 📝 `docs/user-visible-errors.csv` (+1 -0) ➕ `docs/verification/ghidra-procedure-timeout-2026-10-23.md` (+269 -0) 📝 `knip.json` (+1 -0) ➕ `scripts/verify-real-ghidra-decompile-timeout.mjs` (+275 -0) 📝 `scripts/verify-real-ghidra-decompiler-failure.mjs` (+24 -0) 📝 `src/application/ClientRegistrationEnvironment.ts` (+7 -0) 📝 `src/application/ClientRegistrationStatus.ts` (+11 -2) 📝 `src/application/SetupRegistrationEnvironment.ts` (+1 -0) 📝 `src/config.test.ts` (+43 -0) 📝 `src/config/environment.ts` (+2 -0) 📝 `src/config/parseConfig.ts` (+6 -0) 📝 `src/config/providerStartupTimeout.ts` (+15 -0) 📝 `src/config/types.ts` (+2 -0) 📝 `src/contracts/enhancedToolContracts.ts` (+3 -3) 📝 `src/ghidra/GhidraLauncher.ts` (+7 -0) _...and 13 more files_ </details> ### 📄 Description Fixes #5340. An opt-in `REA_GHIDRA_DECOMPILE_TIMEOUT_SECONDS` bounds each native decompile without asking Ghidra to close the session. Unset remains unbounded; 1–2,147,483 whole seconds follows Ghidra's signed-int millisecond conversion. Function dossiers retain listing facts, mark pseudocode/native API/value flow unavailable and remain live for retry. Atomic decompiles return the existing `provider_timeout` contract with `retryable: true`, `timeout_ms` and `remote_code: decompile_timed_out`. Caller cancellation still closes the session. Queue-owned wording preserves cancellation and incomplete-cleanup facts; Java regex failures describe engine facts, with lifecycle interpreted by the same provider owner. The function capability advertises this optional control. Derived setup deadlines are single-decompile estimates. Multi-function calls, including `trace_native_values`, need allowance for every attempted function and other work; callers can select fewer functions, split/resume exports or change their client deadline. Existing positive deadlines are preserved. No tool schema changes. Validation: - Full `npm run check` and `docs:check` passed on the published implementation; all 42 deadline/registration cases passed. The preceding provider/queue/session selection had 236 passes and one independently reproduced main SIGKILL wording failure. - Real Linux Ghidra 12.1.4 / JDK 21 lane: 41 Java checks, actual one-second-configured provider capability and complete cleanup. Old production fails the new capability and trace-advice assertions. The earlier pinned natural timeout, CLI/MCP, same-session reuse, two-item batch and maximum-setting export/resume observations are retained in the report. Refreshed full-inventory verification encounters an independent main `symbol` schema error; it is not claimed as passing. - Earlier paired complete MCP task: 237.602 → 95.388 s elapsed, 232.779 → 90.945 s waited CPU, 2051.3 → 2008.8 MiB sampled family RSS; estimated context 983,317 → 989,913 tokens (+0.67%). Avoiding re-imports explains this fixture's result. Later main/capability wording costs were not measured by that pair. - CI [40038742775](https://github.com/morluto/rea/actions/runs/40038742775): all 13 failed/cancelled job logs, aggregation and terminal diagnostics audited. All 1,066 visible assertion markers map to independently observed main failures. The intermittent Kuna doctor case has both passing and failing exact-base controls; its cancelled CI log lacks a full diagnostic, so diagnostic equality is not claimed. PR title/readiness checks pass. See the maintenance comment for attribution and the authorized CI bypass. [Verification report](https://github.com/RishTheFish21/rea/blob/fb6c88d518ab9b84ed396cf82dcb1c28a608c501/docs/verification/ghidra-procedure-timeout-2026-10-23.md). Maintenance real-provider scope is Linux; Windows/macOS, natural regex overflow, long client timers and large-batch capacity remain unverified. Targets were never executed. The verifier rejects oversized fixture overrides before allocation using a 1 MiB generated-source budget. Contribution scope: optional resource control within the existing static Ghidra workflow, with no new provider, target execution, injection, executable mutation or attached-GUI authority. ## Author readiness Human owner: @RishTheFish21 - [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 - [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>
bsakaguchi 2026-11-01 21:44:47 +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#7022
No description provided.