[GH-ISSUE #8559] [Bug] Native UI verifier can lose fixture ownership before the ready handshake #6646

Open
opened 2026-11-01 21:12:55 +00:00 by bsakaguchi · 2 comments
Owner

Originally created by @morluto on GitHub (Nov 1, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/8559

Originally assigned to: @kaoru0822-kitauji on GitHub.

Area

Native UI verifier cleanup

Observed behavior

At revision 245a581818ab13694fa438a06e39898ce03ab206, verify-native-ui.mjs records a fixture PID only after the window-ready output is parsed. If the handshake times out, cleanup signals and waits for the open launcher, then removes the fixture root without an identity for a separately launched fixture process. Launch and handshake; cleanup.

Reproduction and evidence

On macOS arm64, Node 24.22.1, a subprocess ran the actual verifier with injected compiler and open launcher, and an accelerated clock. The simulated launcher started a detached, source-owned Node fixture that never sent a ready record. After the verifier timed out and terminated its launcher, the fixture was still present as a sleeping process reparented to PID 1; it was then explicitly terminated by the test operator. An independent source review confirmed that this follows the verifier's missing-handshake cleanup path.

This simulates a separate fixture process. Actual macOS LaunchServices behavior, real GUI survival, and incidence are NOT_ENOUGH_INFO; no native compiler, GUI, or provider was run.

Expected behavior

Establish and retain ownership of the launched fixture through late or missing handshake and cleanup; do not delete the fixture root while an owned app may remain. Any fix should use process-ownership primitives and cover late handshake, startup failure, cleanup refusal and retry, without signaling a process from PID or path alone.

Originally created by @morluto on GitHub (Nov 1, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/8559 Originally assigned to: @kaoru0822-kitauji on GitHub. ### Area Native UI verifier cleanup ### Observed behavior At revision `245a581818ab13694fa438a06e39898ce03ab206`, `verify-native-ui.mjs` records a fixture PID only after the window-ready output is parsed. If the handshake times out, cleanup signals and waits for the `open` launcher, then removes the fixture root without an identity for a separately launched fixture process. [Launch and handshake](https://github.com/morluto/rea/blob/245a581818ab13694fa438a06e39898ce03ab206/scripts/verify-native-ui.mjs#L93-L120); [cleanup](https://github.com/morluto/rea/blob/245a581818ab13694fa438a06e39898ce03ab206/scripts/verify-native-ui.mjs#L262-L283). ### Reproduction and evidence On macOS arm64, Node 24.22.1, a subprocess ran the actual verifier with injected compiler and `open` launcher, and an accelerated clock. The simulated launcher started a detached, source-owned Node fixture that never sent a ready record. After the verifier timed out and terminated its launcher, the fixture was still present as a sleeping process reparented to PID 1; it was then explicitly terminated by the test operator. An independent source review confirmed that this follows the verifier's missing-handshake cleanup path. This simulates a separate fixture process. Actual macOS LaunchServices behavior, real GUI survival, and incidence are NOT_ENOUGH_INFO; no native compiler, GUI, or provider was run. ### Expected behavior Establish and retain ownership of the launched fixture through late or missing handshake and cleanup; do not delete the fixture root while an owned app may remain. Any fix should use process-ownership primitives and cover late handshake, startup failure, cleanup refusal and retry, without signaling a process from PID or path alone.
Author
Owner

@kaoru0822-kitauji commented on GitHub (Nov 2, 2026):

Reproduced on 8250bf232 with real LaunchServices, on macOS 26.7.1 arm64 and Node 24.22.1. I ran the actual verifier with only the compiler injected, real /usr/bin/open, and a never-ready AppKit binary.

It exited 1 after the 20-second budget with the fixture root deleted, and the app was still running from the deleted bundle (columns: PID, PPID, PGID):

36941     1 36941 .../rea-ui-fixture-04TTpR/Fixture.app/Contents/MacOS/fixture

Observed facts that the issue left as NOT_ENOUGH_INFO:

  • The launched app has PPID 1 and its own process group, and it survives SIGTERM to open.
  • open's environment reaches the app, so a run token set before launch is readable from the app. open's own token is withheld (platform_binary_environment_withheld).
  • Stopping open does not cancel a launch in flight. When open was killed 10 or 20 ms after spawn, the app appeared after an immediate process-table check in 6 of 6 rounds.

The fix is in #8646.

<!-- gh-comment-id:6570927656 --> @kaoru0822-kitauji commented on GitHub (Nov 2, 2026): Reproduced on `8250bf232` with real LaunchServices, on macOS 26.7.1 arm64 and Node 24.22.1. I ran the actual verifier with only the compiler injected, real `/usr/bin/open`, and a never-ready AppKit binary. It exited 1 after the 20-second budget with the fixture root deleted, and the app was still running from the deleted bundle (columns: PID, PPID, PGID): ``` 36941 1 36941 .../rea-ui-fixture-04TTpR/Fixture.app/Contents/MacOS/fixture ``` Observed facts that the issue left as `NOT_ENOUGH_INFO`: - The launched app has PPID 1 and its own process group, and it survives `SIGTERM` to `open`. - `open`'s environment reaches the app, so a run token set before launch is readable from the app. `open`'s own token is withheld (`platform_binary_environment_withheld`). - Stopping `open` does not cancel a launch in flight. When `open` was killed 10 or 20 ms after spawn, the app appeared after an immediate process-table check in 6 of 6 rounds. The fix is in #8646.
Author
Owner

@BeqaKs commented on GitHub (Nov 3, 2026):

Closing as addressed by merged verifier ownership work (#8573 / #8654). Stayed open after Refs rather than Fixes.

<!-- gh-comment-id:6599994278 --> @BeqaKs commented on GitHub (Nov 3, 2026): Closing as addressed by merged verifier ownership work (#8573 / #8654). Stayed open after Refs rather than Fixes.
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#6646
No description provided.