[PR #6268] [MERGED] fix(doctor): interrupt Hopper display readiness on cancel #7240

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

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/6268
Author: @mvanhorn
Created: 10/22/2026
Status: ✅ Merged
Merged: 10/22/2026
Merged by: @gensokyo-dev

Base: main ← Head: fix/doctor-hopper-display-cancel


📝 Commits (3)

  • 091bdbe fix(doctor): interrupt Hopper display readiness on cancel
  • 44f05d0 chore: integrate doctor cancellation fix with current main
  • 771780d test(doctor): guard cancellation during display finalization

📊 Changes

2 files changed (+177 additions, -0 deletions)

View changed files

📝 src/doctorRuntime.test.ts (+169 -0)
📝 src/doctorRuntime.ts (+8 -0)

📄 Description

Summary

Cancelling rea doctor --provider hopper during the Linux Hopper display readiness check left that check pending. Doctor composition passed the abort signal into Python runtime inspection but not into private-display selection, so the owned probe wait loop never observed abort.

The doctor abort signal is now passed into selectLinuxPrivateDisplayStrategy. After that selection settles, an aborted caller is rejected with AnalysisCancelledError whose cause is the caller's exact abort reason. Pre-aborted doctor entry still rejects before display work. An unaborted run still reports a healthy hopper-demo-runtime check.

Closes #6227

Changes

  • Thread the doctor AbortSignal into Linux private-display selection from createSystemDoctorHost.
  • After display selection, reject with AnalysisCancelledError and the caller's abort reason instead of continuing into Python inspection or returning a display diagnostic.
  • The probe wait loop already joined owned cleanup when it received a signal; that path is now reachable from doctor.

Testing

  • npm run test:local -- src/doctorRuntime.test.ts: 13 passed, including the in-flight display abort, unaborted healthy control, and pre-aborted control.
  • npm run check:fast: typecheck and lint passed.
  • On main, the in-flight abort case hangs until the 5s test timeout because the recording selector never receives signal. On this branch it settles with AnalysisCancelledError and the same abort reason object.

Hopper is not required: the regression uses runDoctorOwned with the recording host and a recording display selector.

Demo

demo

Current-main follow-up verification

Integrated with main e78014830; current head 771780d1d. The original fix is unchanged. Added one controlled selector-finalization regression: doctor must join that wait, retain the exact late abort reason, and not start Python inspection.

Executed on Linux, Node 24.18.0 / npm 11.16.0:

  • Unfixed behavior: active display cancellation times out and the new finalization guard starts Python incorrectly (2 failed / 12 passed).
  • Fixed: doctorRuntime.test.ts, 14 passed in each of three consecutive runs.
  • Focused compiled boundaries: linuxPrivateDisplay, doctorCancellation, doctorHopperDiscovery: 22 passed, including owned probe process termination and public CLI SIGINT/SIGTERM controls.
  • npm run check, npm run verify:test-discovery, and pre-push check:fast: passed.
  • Independent local Codex CLI source review: no definite new actionable defect; GitHub Codex review could not run because its quota was exhausted.

Scope: the late-finalization seam is controlled; the CLI interruption controls cover JADX/Kuna prerequisites, not a real Hopper engine. No real Hopper engine qualification or performance improvement is claimed. No tool/schema/output growth; the fix only propagates the existing signal and checks it after the awaited selector.


🔄 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/6268 **Author:** [@mvanhorn](https://github.com/mvanhorn) **Created:** 10/22/2026 **Status:** ✅ Merged **Merged:** 10/22/2026 **Merged by:** [@gensokyo-dev](https://github.com/gensokyo-dev) **Base:** `main` ← **Head:** `fix/doctor-hopper-display-cancel` --- ### 📝 Commits (3) - [`091bdbe`](https://github.com/morluto/rea/commit/091bdbed6c8514c9ea6f8cc10725bd1cb068de25) fix(doctor): interrupt Hopper display readiness on cancel - [`44f05d0`](https://github.com/morluto/rea/commit/44f05d0bfd5632d2d67c6451af44c4968123e6dd) chore: integrate doctor cancellation fix with current main - [`771780d`](https://github.com/morluto/rea/commit/771780d1d6c210f7e38c8cd83892e608798fb87f) test(doctor): guard cancellation during display finalization ### 📊 Changes **2 files changed** (+177 additions, -0 deletions) <details> <summary>View changed files</summary> 📝 `src/doctorRuntime.test.ts` (+169 -0) 📝 `src/doctorRuntime.ts` (+8 -0) </details> ### 📄 Description ## Summary Cancelling `rea doctor --provider hopper` during the Linux Hopper display readiness check left that check pending. Doctor composition passed the abort signal into Python runtime inspection but not into private-display selection, so the owned probe wait loop never observed abort. The doctor abort signal is now passed into `selectLinuxPrivateDisplayStrategy`. After that selection settles, an aborted caller is rejected with `AnalysisCancelledError` whose `cause` is the caller's exact abort reason. Pre-aborted doctor entry still rejects before display work. An unaborted run still reports a healthy `hopper-demo-runtime` check. Closes #6227 ## Changes - Thread the doctor `AbortSignal` into Linux private-display selection from `createSystemDoctorHost`. - After display selection, reject with `AnalysisCancelledError` and the caller's abort reason instead of continuing into Python inspection or returning a display diagnostic. - The probe wait loop already joined owned cleanup when it received a signal; that path is now reachable from doctor. ## Testing - `npm run test:local -- src/doctorRuntime.test.ts`: 13 passed, including the in-flight display abort, unaborted healthy control, and pre-aborted control. - `npm run check:fast`: typecheck and lint passed. - On `main`, the in-flight abort case hangs until the 5s test timeout because the recording selector never receives `signal`. On this branch it settles with `AnalysisCancelledError` and the same abort reason object. Hopper is not required: the regression uses `runDoctorOwned` with the recording host and a recording display selector. ## Demo ![demo](https://raw.githubusercontent.com/mvanhorn/pr-demo-assets/main/rea/doctor-hopper-display-cancel/demo.gif) <video src="https://raw.githubusercontent.com/mvanhorn/pr-demo-assets/main/rea/doctor-hopper-display-cancel/demo.mp4" controls width="720"></video> ## Current-main follow-up verification Integrated with main `e78014830`; current head `771780d1d`. The original fix is unchanged. Added one controlled selector-finalization regression: doctor must join that wait, retain the exact late abort reason, and not start Python inspection. Executed on Linux, Node 24.18.0 / npm 11.16.0: - Unfixed behavior: active display cancellation times out and the new finalization guard starts Python incorrectly (2 failed / 12 passed). - Fixed: `doctorRuntime.test.ts`, 14 passed in each of three consecutive runs. - Focused compiled boundaries: `linuxPrivateDisplay`, `doctorCancellation`, `doctorHopperDiscovery`: 22 passed, including owned probe process termination and public CLI SIGINT/SIGTERM controls. - `npm run check`, `npm run verify:test-discovery`, and pre-push `check:fast`: passed. - Independent local Codex CLI source review: no definite new actionable defect; GitHub Codex review could not run because its quota was exhausted. Scope: the late-finalization seam is controlled; the CLI interruption controls cover JADX/Kuna prerequisites, not a real Hopper engine. No real Hopper engine qualification or performance improvement is claimed. No tool/schema/output growth; the fix only propagates the existing signal and checks it after the awaited selector. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-11-01 21:46:26 +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#7240
No description provided.