[GH-ISSUE #4674] [Bug] Ghidra profile cancellation attribution differs for returned and thrown failures #2434

Closed
opened 2026-10-17 21:04:37 +00:00 by bsakaguchi · 4 comments
Owner

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

Before submitting

  • Searched open and closed Ghidra cancellation/profile operation reports.
  • Removed sensitive target data and credentials.

Area

Provider or capability discovery

Observed behavior

Ghidra profile cancellation uses open_binary for pre-aborted/thrown outcomes but resolve_analysis_profile for a returned seed-file cancellation. The public provider owner does not normalize the returned Result error. The existing shutdown regression also incorrectly expects success after owner cancellation.

Reproduction

On unchanged production code cc2e18a265, ran the existing ghidraProfileArtifactOwnership file:15 passed,1 failed on its success expectation. Then overlaid only stronger assertions in the isolated checkout: the held realpath/shutdown control returns AnalysisCancelledError with the exact STARTUP_OWNER_CLOSED reason and operation resolve_analysis_profile instead of the owner's established open_binary operation. Restored the test; production source was unchanged.

Expected behavior

The provider boundary attributes cancellation consistently across thrown and returned failures, preserving its exact reason, completed facts and cleanup dependencies. Shutdown still joins the pending inspection before allowing another resolution.

Impact and scope

Observed inconsistent error metadata and a stale regression assertion. Public CLI/MCP incidence: NOT_ENOUGH_INFO; not reproduced. No native Ghidra launched.

REA version

6.5.0 source, cc2e18a265.

Runtime and platform

Node24.18.0/Darwin arm64; real private seed/extension files with a controlled realpath gate and recording installation host.

Target and artifact context

Synthetic executable target; temporary seed and extension files.

Interface

Other: shared provider boundary

Earliest failure stage

Profile resolution cancellation after file-path observation

Relevant output or evidence

Expected operation open_binary; received resolve_analysis_profile. GhidraProvider.resolveAnalysisProfile projects caught cancellations but directly returns failed Results from #resolveProfile.

Typed outcome or recovery expected

Operation-attributed AnalysisCancelledError, exact opaque cause and joined cleanup.

Analysis or suspected cause

Source-derived: normalization exists only in the catch path. Draft fix applies the same owner projection to returned cancellation errors; the strengthened shutdown control passes while still asserting no overlapping admission and successful later resolution.

Additional context

Found while validating #4672, adjacent to the #4561 lifecycle migration. No real-provider or cross-platform verification claim.

Originally created by @morluto on GitHub (Oct 17, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/4674 ### Before submitting - [x] Searched open and closed Ghidra cancellation/profile operation reports. - [x] Removed sensitive target data and credentials. ### Area Provider or capability discovery ### Observed behavior Ghidra profile cancellation uses open_binary for pre-aborted/thrown outcomes but resolve_analysis_profile for a returned seed-file cancellation. The public provider owner does not normalize the returned Result error. The existing shutdown regression also incorrectly expects success after owner cancellation. ### Reproduction On unchanged production code cc2e18a265198492dff1587a343bfb802d8c591b, ran the existing ghidraProfileArtifactOwnership file:15 passed,1 failed on its success expectation. Then overlaid only stronger assertions in the isolated checkout: the held realpath/shutdown control returns AnalysisCancelledError with the exact STARTUP_OWNER_CLOSED reason and operation resolve_analysis_profile instead of the owner's established open_binary operation. Restored the test; production source was unchanged. ### Expected behavior The provider boundary attributes cancellation consistently across thrown and returned failures, preserving its exact reason, completed facts and cleanup dependencies. Shutdown still joins the pending inspection before allowing another resolution. ### Impact and scope Observed inconsistent error metadata and a stale regression assertion. Public CLI/MCP incidence: NOT_ENOUGH_INFO; not reproduced. No native Ghidra launched. ### REA version 6.5.0 source, cc2e18a265198492dff1587a343bfb802d8c591b. ### Runtime and platform Node24.18.0/Darwin arm64; real private seed/extension files with a controlled realpath gate and recording installation host. ### Target and artifact context Synthetic executable target; temporary seed and extension files. ### Interface Other: shared provider boundary ### Earliest failure stage Profile resolution cancellation after file-path observation ### Relevant output or evidence Expected operation open_binary; received resolve_analysis_profile. GhidraProvider.resolveAnalysisProfile projects caught cancellations but directly returns failed Results from #resolveProfile. ### Typed outcome or recovery expected Operation-attributed AnalysisCancelledError, exact opaque cause and joined cleanup. ### Analysis or suspected cause Source-derived: normalization exists only in the catch path. Draft fix applies the same owner projection to returned cancellation errors; the strengthened shutdown control passes while still asserting no overlapping admission and successful later resolution. ### Additional context Found while validating #4672, adjacent to the #4561 lifecycle migration. No real-provider or cross-platform verification claim.
Author
Owner

@morluto commented on GitHub (Oct 17, 2026):

Published on main in c72786f289.

The provider now applies its existing owner attribution to returned cancellation Results as well as thrown failures. The exact owner-close reason and cleanup dependencies are preserved. The shutdown control now requires typed cancellation, verifies joining the held path observation, gates the next admission and checks successful later resolution.

Executed: original control failed on unchanged cc2e18a26; stronger assertions against unchanged production code separately exposed resolve_analysis_profile instead of open_binary. The repaired control passes within the focused ownership suite and the 384-test validation run; check:fast and normal hooks passed. Recording installation ports and real private files only; no native Ghidra or public cancellation-attribution reproduction claim.

<!-- gh-comment-id:6229410719 --> @morluto commented on GitHub (Oct 17, 2026): Published on main in c72786f289eb150b480f95919620f700ce2de363. The provider now applies its existing owner attribution to returned cancellation Results as well as thrown failures. The exact owner-close reason and cleanup dependencies are preserved. The shutdown control now requires typed cancellation, verifies joining the held path observation, gates the next admission and checks successful later resolution. Executed: original control failed on unchanged cc2e18a26; stronger assertions against unchanged production code separately exposed resolve_analysis_profile instead of open_binary. The repaired control passes within the focused ownership suite and the 384-test validation run; check:fast and normal hooks passed. Recording installation ports and real private files only; no native Ghidra or public cancellation-attribution reproduction claim.
Author
Owner

@XinwangTao commented on GitHub (Oct 17, 2026):

The asymmetry is real: a thrown cancellation surfaces via open_binary with STARTUP_OWNER_CLOSED, while a returned seed-file cancellation resolves through resolve_analysis_profile and never gets normalized by the public provider owner — so the same logical failure carries different reason/operation metadata depending on the path. The fix in c72786f (attribute returned cancellation at the owner) addresses exactly that. Two things worth locking in as regressions: (1) shutdown must still join the pending inspection before allowing another resolution, asserting AnalysisCancelledError rather than success after owner cancellation; (2) both thrown and returned variants should preserve the exact reason, completed facts and cleanup dependencies so CLI/MCP consumers can rely on one shape.

<!-- gh-comment-id:6229628037 --> @XinwangTao commented on GitHub (Oct 17, 2026): The asymmetry is real: a thrown cancellation surfaces via open_binary with STARTUP_OWNER_CLOSED, while a returned seed-file cancellation resolves through resolve_analysis_profile and never gets normalized by the public provider owner — so the same logical failure carries different reason/operation metadata depending on the path. The fix in c72786f (attribute returned cancellation at the owner) addresses exactly that. Two things worth locking in as regressions: (1) shutdown must still join the pending inspection before allowing another resolution, asserting AnalysisCancelledError rather than success after owner cancellation; (2) both thrown and returned variants should preserve the exact reason, completed facts and cleanup dependencies so CLI/MCP consumers can rely on one shape.
Author
Owner

@morluto commented on GitHub (Oct 18, 2026):

Closing as fixed on main after reconciling this report with the landed owner/consumer changes.

  • c72786f28: fix(ghidra): attribute returned profile cancellation at its owner. Strengthen the held-path regression to require typed cancellation instead of success. The original assertion and the stronger attribution control failed on unchanged cc2e18a26; focused validation and check:fast pass after repair. Controlled private files and recording provider ports; no native Ghidra claim.

Evidence scope: this closure uses the landed source, regression coverage and validation already recorded in the linked commits/thread. No new local tests or native-provider reproduction were run during this backlog pass; previously documented platform and real-provider gaps still apply.

<!-- gh-comment-id:6255993600 --> @morluto commented on GitHub (Oct 18, 2026): <!-- rea-backlog-reconciliation-2026-10-19-4674 --> Closing as fixed on `main` after reconciling this report with the landed owner/consumer changes. - [c72786f28](https://github.com/morluto/rea/commit/c72786f289eb150b480f95919620f700ce2de363): fix(ghidra): attribute returned profile cancellation at its owner. Strengthen the held-path regression to require typed cancellation instead of success. The original assertion and the stronger attribution control failed on unchanged cc2e18a26; focused validation and check:fast pass after repair. Controlled private files and recording provider ports; no native Ghidra claim. Evidence scope: this closure uses the landed source, regression coverage and validation already recorded in the linked commits/thread. No new local tests or native-provider reproduction were run during this backlog pass; previously documented platform and real-provider gaps still apply.
Author
Owner

@XinwangTao commented on GitHub (Oct 19, 2026):

Scope looks right — keeping it to registry-state.mjs and only adding failure classification + bounded backoff around the existing-version GET preserves the unknown-state contract. One thing to watch: after retries still time out, the job must still abort before authentication rather than proceed with a guessed state, so the backoff only heals short blips and never flips unknown into a decision.

<!-- gh-comment-id:6257602616 --> @XinwangTao commented on GitHub (Oct 19, 2026): Scope looks right — keeping it to registry-state.mjs and only adding failure classification + bounded backoff around the existing-version GET preserves the unknown-state contract. One thing to watch: after retries still time out, the job must still abort before authentication rather than proceed with a guessed state, so the backoff only heals short blips and never flips unknown into a decision.
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#2434
No description provided.