[GH-ISSUE #4846] [Bug] JADX archive admission drops failed reader cleanup ownership #3012

Closed
opened 2026-10-31 00:34:48 +00:00 by bsakaguchi · 1 comment
Owner

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

Before submitting

  • Searched open and closed reports for JadxConfiguration plus close; #1441 concerns a fixture process owner rather than archive descriptors.
  • No credentials or private artifact data included.

Area

Provider or capability discovery

Observed behavior

Source-only: requireEngineArchive creates a ZipArtifactReader locally and unconditionally awaits reader.close in finally. If descriptor close fails, the function loses the reader capability and does not transfer it to the caller's durable resource owner. If archive inspection had already failed, the close error also replaces that primary failure.

Reproduction

NOT_ENOUGH_INFO: no failed-close runtime injection performed yet. Inspected src/android/JadxConfiguration.ts requireEngineArchive and src/artifacts/ZipArtifactReader.ts close/NodeFileReader.closeHandle at main 3ad1032b11. The current owned Java prerequisite migration preserves this distinct archive path; its held-close control proves shutdown joining, not failed descriptor retirement.

Expected behavior

Retain the exact reader/descriptor owner after failed close, preserve the archive or cancellation primary, report cleanup incomplete and affected resources, block replacement admission as appropriate, and resolve the same errors only after exact retry succeeds. Use the existing resource scope/lease ownership contract; do not infer ownership from the pathname.

Impact and scope

Source-derived risk of unreported open descriptor ownership during JADX provider or doctor JAR admission. Actual OS close failures, frequency and affected platforms: NOT_ENOUGH_INFO. No real-provider failure reproduction claimed.

REA version

6.5.0 source, 3ad1032b11

Runtime and platform

Source review on Node24.18.0/macOS arm64; runtime defect unverified.

Target and artifact context

Caller-selected REA_JADX_MCP_JAR metadata; no APK or engine execution required.

Interface

Shared provider/doctor configuration boundary.

Earliest failure stage

Cleanup, cancellation, or lifecycle

Relevant output or evidence

requireEngineArchive: local reader, catch maps archive failure, finally awaits reader.close with no cleanup retention. ZipArtifactReader.close awaits its exact OwnedFileHandle close; failed closure leaves the owner retained inside the reader, not in the thrown plain close error.

Typed outcome or recovery expected

Primary typed failure plus independently retained descriptor cleanup, live resource attribution and exact retry binding.

Analysis or suspected cause

The outer configuration boundary drops its local owner on exceptional finalization. Resource validity and cleanup proof must remain separate.

Additional context

Separate from the Java subprocess lifecycle finding #4845. Proposed controls: physical archive failure plus failed close, completed valid/missing-class archive plus failed close, cancellation during final close, scope admission blocking, retry and partial cleanup attribution.

Originally created by @morluto on GitHub (Oct 17, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/4846 ### Before submitting - [x] Searched open and closed reports for JadxConfiguration plus close; #1441 concerns a fixture process owner rather than archive descriptors. - [x] No credentials or private artifact data included. ### Area Provider or capability discovery ### Observed behavior Source-only: requireEngineArchive creates a ZipArtifactReader locally and unconditionally awaits reader.close in finally. If descriptor close fails, the function loses the reader capability and does not transfer it to the caller's durable resource owner. If archive inspection had already failed, the close error also replaces that primary failure. ### Reproduction NOT_ENOUGH_INFO: no failed-close runtime injection performed yet. Inspected src/android/JadxConfiguration.ts requireEngineArchive and src/artifacts/ZipArtifactReader.ts close/NodeFileReader.closeHandle at main 3ad1032b11edea2dcb054e78f951cc43159ae83d. The current owned Java prerequisite migration preserves this distinct archive path; its held-close control proves shutdown joining, not failed descriptor retirement. ### Expected behavior Retain the exact reader/descriptor owner after failed close, preserve the archive or cancellation primary, report cleanup incomplete and affected resources, block replacement admission as appropriate, and resolve the same errors only after exact retry succeeds. Use the existing resource scope/lease ownership contract; do not infer ownership from the pathname. ### Impact and scope Source-derived risk of unreported open descriptor ownership during JADX provider or doctor JAR admission. Actual OS close failures, frequency and affected platforms: NOT_ENOUGH_INFO. No real-provider failure reproduction claimed. ### REA version 6.5.0 source, 3ad1032b11edea2dcb054e78f951cc43159ae83d ### Runtime and platform Source review on Node24.18.0/macOS arm64; runtime defect unverified. ### Target and artifact context Caller-selected REA_JADX_MCP_JAR metadata; no APK or engine execution required. ### Interface Shared provider/doctor configuration boundary. ### Earliest failure stage Cleanup, cancellation, or lifecycle ### Relevant output or evidence requireEngineArchive: local reader, catch maps archive failure, finally awaits reader.close with no cleanup retention. ZipArtifactReader.close awaits its exact OwnedFileHandle close; failed closure leaves the owner retained inside the reader, not in the thrown plain close error. ### Typed outcome or recovery expected Primary typed failure plus independently retained descriptor cleanup, live resource attribution and exact retry binding. ### Analysis or suspected cause The outer configuration boundary drops its local owner on exceptional finalization. Resource validity and cleanup proof must remain separate. ### Additional context Separate from the Java subprocess lifecycle finding #4845. Proposed controls: physical archive failure plus failed close, completed valid/missing-class archive plus failed close, cancellation during final close, scope admission blocking, retry and partial cleanup attribution.
bsakaguchi 2026-10-31 00:34:48 +00:00
  • closed this issue
  • added the
    triage
    bug
    labels
Author
Owner

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

Fixed on main in two semantic commits:

  • f1d18859e: preserve opaque ZIP cancellation reasons using the canonical artifact checkpoint.
  • 300905c11: retain archive admission ownership through cleanup retries.

JAR metadata enumeration now borrows a descriptor from the existing owned artifact-file workflow. That boundary retains failed close capabilities and the physical admission outcome. Missing/malformed archives preserve their primary configuration failure; completed class inventory survives cancellation or failed close. Exact cleanup leases bind originating and aggregate errors, block replacement probes until cleanup succeeds, and support provider/independent doctor shutdown. Removed the local reader/finally-close ownership path and live-signal reinterpretation.

Evidence: three failed-close controls fail on baseline 662fad907 by returning only the injected close error; both new ZIP reason controls also fail on that baseline. Candidate: 65 passing tests across seven files, including final-close cancellation, mixed-owner retry, no reclose of released peers, shutdown joining and independent doctor retention. The exact shared ZIP commit passes its eight tests independently. check:fast, docs:check, discovery of1549 test files and commit/push hooks pass. Two read-only reviews found no concrete blockers in this scope.

Real normal-path verification: nine CLI and nine MCP method inspections on the tiny authored APK pass with pinned JADX0.7.1/JDK21, preserving facts, identity, parity and input bytes. Six sequential measured MCP workflows have matching normalized facts. Two warm-repeat medians baseline/candidate: elapsed2.429/2.378s, reaped-familyCPU3.494/3.592s, sampled familyRSS862650368/850477056bytes, replycl100k estimates9634.5/9587tokens. Small sample; no speedup or whole-agent/true-cold claim. Earlier overlapping measurements are retained but excluded. Failure-path costs unmeasured.

Limits: descriptor faults were controlled injections against real file handles, not naturally occurring OS close failures. No real JVM failure, native Linux/Windows or heavy profiling/stress. All12 measured temporary roots are absent, no matching processes remain, and the owned baseline checkout was removed. Full codebase/issue audit remains ongoing.

<!-- gh-comment-id:6238463967 --> @morluto commented on GitHub (Oct 17, 2026): Fixed on main in two semantic commits: - f1d18859e: preserve opaque ZIP cancellation reasons using the canonical artifact checkpoint. - 300905c11: retain archive admission ownership through cleanup retries. JAR metadata enumeration now borrows a descriptor from the existing owned artifact-file workflow. That boundary retains failed close capabilities and the physical admission outcome. Missing/malformed archives preserve their primary configuration failure; completed class inventory survives cancellation or failed close. Exact cleanup leases bind originating and aggregate errors, block replacement probes until cleanup succeeds, and support provider/independent doctor shutdown. Removed the local reader/finally-close ownership path and live-signal reinterpretation. Evidence: three failed-close controls fail on baseline 662fad907 by returning only the injected close error; both new ZIP reason controls also fail on that baseline. Candidate: 65 passing tests across seven files, including final-close cancellation, mixed-owner retry, no reclose of released peers, shutdown joining and independent doctor retention. The exact shared ZIP commit passes its eight tests independently. check:fast, docs:check, discovery of1549 test files and commit/push hooks pass. Two read-only reviews found no concrete blockers in this scope. Real normal-path verification: nine CLI and nine MCP method inspections on the tiny authored APK pass with pinned JADX0.7.1/JDK21, preserving facts, identity, parity and input bytes. Six sequential measured MCP workflows have matching normalized facts. Two warm-repeat medians baseline/candidate: elapsed2.429/2.378s, reaped-familyCPU3.494/3.592s, sampled familyRSS862650368/850477056bytes, replycl100k estimates9634.5/9587tokens. Small sample; no speedup or whole-agent/true-cold claim. Earlier overlapping measurements are retained but excluded. Failure-path costs unmeasured. Limits: descriptor faults were controlled injections against real file handles, not naturally occurring OS close failures. No real JVM failure, native Linux/Windows or heavy profiling/stress. All12 measured temporary roots are absent, no matching processes remain, and the owned baseline checkout was removed. Full codebase/issue audit remains ongoing.
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#3012
No description provided.