[PR #4334] test(ghidra): align fixtures with Windows host boundaries #6179

Open
opened 2026-10-31 01:12:28 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/4334
Author: @siegfly
Created: 10/16/2026
Status: 🔄 Open

Base: main ← Head: codex/windows-ghidra-endpoint-fix


📝 Commits (10+)

  • a4791ed test(ghidra): align socket fixtures with Windows host boundaries
  • 170206c test(ghidra): gate endpoint discovery and cover Windows fixtures in CI
  • 3c64161 test(ghidra): reach replacement and launch checkpoints on Windows
  • 70198f9 test(ci): cover Ghidra file and launch host fixtures on Windows
  • 2b86d08 test(ghidra): create fixture endpoints with the owned Windows writer
  • 6bf1ac7 test(ci): select Windows lane for Ghidra runtime helper
  • 944f283 chore: sync Windows Ghidra fixtures with latest main
  • cb91029 chore: sync Windows Ghidra fixtures with latest main
  • c1aae16 chore: sync Windows Ghidra fixtures with latest main
  • 7a5681c chore: include latest Electron ownership fix from main

📊 Changes

15 files changed (+291 additions, -82 deletions)

View changed files

📝 .github/workflows/ci.yml (+7 -0)
📝 scripts/ci/scopes.mjs (+10 -0)
📝 tests/boundary/filesystem/ciChangeScope.test.ts (+22 -0)
📝 tests/boundary/filesystem/ghidraExecutableHeader.test.ts (+6 -2)
📝 tests/boundary/filesystem/ghidraInstallationProperties.test.ts (+6 -2)
📝 tests/boundary/mcp/ghidraInventoryMcp.test.ts (+14 -50)
📝 tests/boundary/mcp/ghidraReopen.test.ts (+3 -0)
📝 tests/boundary/mcp/ghidraStartupCancellationMcp.test.ts (+27 -4)
📝 tests/boundary/providers/ghidra/ghidraClient.fixture.ts (+63 -1)
📝 tests/boundary/providers/ghidra/ghidraClient.test.ts (+65 -3)
📝 tests/boundary/providers/ghidra/ghidraLaunchOutcome.test.ts (+6 -2)
📝 tests/boundary/providers/startupCloseWaiters.test.ts (+6 -2)
📝 tests/fixtures/fakeGhidra.mjs (+42 -15)
📝 tests/fixtures/ghidraRuntime.ts (+1 -1)
📝 tests/process-global/curatedWindowsLane.test.ts (+13 -0)

📄 Description

Summary

Fix the Windows fake-Ghidra host fixtures by aligning endpoint publication, child ownership and test-host selection with the existing production boundaries. Include the affected tests in Windows CI. This is an independent follow-up to verification gaps found on #3075/#3076; it changes tests and CI, not production runtime authority.

Problem and expected behavior

Two original causes were isolated on main 1bd5c5c87 without either documentation patch:

  1. 34 failures: the fake producer renamed a pending endpoint into a private directory whose retained Windows guard forbids rename (EBUSY). Ordinary-directory rename succeeds on both C: and E: NTFS, while guarded-directory rename fails and exclusive direct creation succeeds. The Java bridge already directly creates the Windows endpoint.
  2. 2 timeouts: selecting process.execPath selects PE on Windows; session attestation starts before callTool, while the test waits for callTool admission before opening its startup gate. Fixed self-owned ELF samples remove that circular wait. Simulated installation metadata must also not select Unix sockets for actual Windows child processes.

Review identified two remaining gaps: a synchronous direct write is still visible to another process before close, and the changed fixture paths did not select the Windows CI lane.

Change and scope

  • Use the existing owned Windows writer to exclusively create an empty endpoint with the current-user owner, then have the fake bridge reopen that same file and acknowledge publication over IPC after its writer closes. The shared launcher waits for that explicit acknowledgement before returning the child to endpoint discovery. Unix socket listeners also acknowledge readiness; intentional silent/exit modes preserve their failure semantics.
  • Cancellation or child exit releases the wait while returning the owned child to the production client's supervisor and cleanup. Do not treat cancellation/exit as publication success, relax the native guard, or suppress malformed endpoint errors downstream.
  • Use fixed, never-executed ELF headers and one shared actual-host platform/transport owner. Reuse the existing launcher in inventory tests instead of duplicating process cleanup. Make premature MCP settlement fail the admission wait explicitly.
  • Add the affected fixture/test paths to package/runtime selection and seven actual test files to windows-curated. Keep existing mainline native-artifact-before-build and runner-cancellation coverage intact.
  • Skip only the unsupported Hopper-on-Windows restart case in addition to pre-existing platform skips; the original 36 failing cases remain enabled and pass.

Current-main supplemental verification exposed three more Windows fixtures that fail before their intended boundary. The two file-replacement tests now rename the open original aside before publishing its replacement, preserving real identity-change assertions. The launch-cancellation test uses the shared production-owned private runtime root, reaching the actual preparation checkpoint while retaining foreign-reason and cleanup assertions. No production guard or error oracle is weakened.

No new provider capability, target execution, installation change or maintainer scope decision is needed. No generated artifacts, native binaries or provider databases are committed.

The fixture also uses the existing Windows owned writer to preserve the current-user file owner under elevated runner tokens. Its gated regression reads the still-empty endpoint through the real private-runtime owner check before releasing publication. Production guards, caller token and cleanup policy remain unchanged.

Validation

Current head 0a07c2a70 includes main 3ea0d9489 / 6.7.0. Verification uses Node 24.18.0 / npm 11.16.0.

Fresh local Windows CI selection: 47 files / 640 pass / 41 existing skips. Conflict-focused Ghidra/client/MCP selection: Windows 101 pass / 11 existing skips; Linux 110 pass / 2 existing skips across the same six files. The upstream budget-exhausting-output startup-timeout case executes and passes on Linux. Full check, docs:check (5 README cases) and normal pre-push checks pass. Final-tree Windows package verification passes: 207 tools, packaged bridge, idempotent client setup, uninstall and exact-release update.

Synchronization and CI diagnosis

Resolved the shared fake-Ghidra conflict by preserving main’s flood_silent producer and this PR’s Windows endpoint ownership. The silent/flood producer acknowledges fixture readiness without publishing an endpoint; flood output can then drain before the unchanged production startup timeout. The launcher does not precreate an endpoint for either silent mode. No production behavior or timeout changes.

A commit-hook autofix touched an unrelated upstream Flutter regex during the merge. The follow-up restoration commit returns that file byte-for-byte to main. The final tree matches the tree used by all verification above and retains exactly the original 15 test/CI files relative to main; no unrelated runtime change remains.

Independent fixes and limitations

Main #5224 and the later native-preparation regression update cover most of the earlier independent fixes. Two Windows test gaps remain outside these PRs: a slash-only expected snapshot path and an MCP test expecting native Windows PTY capture to open a snapshot despite the documented unsupported-capability gate. A separate minimal two-file validation copy passes 15 tests on Windows and 15 on Linux. The published independent branch remains at 5453f3cbb; no independent-fix PR is opened, and none of its commits is merged/cherry-picked into these PRs. Its older full diff must not be replayed over newer upstream assertions, particularly the Darwin/Linux preparation distinction.

The old inherited fallback-cancellation CI failures are removed by this main synchronization. Current-head CI and review results are pending after the push; local Windows/package passes are not hosted CI passes. Controlled fixtures do not establish new real Ghidra/JDK qualification.

Hopper remains local-only and unpublished.

New-head CI follow-up

The new run is not green: Apple artifact E2E fails while cleaning the Java availability probe (Java exits 0; process identity cannot be revalidated), and both Linux recorded-crash container lanes fail the historical-PID trace oracle (Ubuntu log). The latter flags an attempted /proc/<sentinel>/stat read in a Node trace. These are different from the old fallback-cancellation assertions.

The affected verification scripts and production cleanup/recorded-crash sources are identical to main 3ea0d9489; this PR's diff remains limited to its original tests/CI scope. This is a source comparison, not clean-main runtime reproduction on macOS or those containers. The recorded-crash oracle currently classifies allowed ownership observations only in a trace containing the exact ps execution; Node-side native ownership reads are a possible explanation, not a proven root cause. No trace allowance, ownership check or test deadline was weakened. Local Windows passes do not qualify macOS or the recorded-crash lane.

Hosted Windows native-controls and NativeAOT builds pass; the Windows capability/package lane is still in progress at the follow-up check.

Completed CI and main controls (2026-10-19)

Hosted Windows capability/package finishes successfully (job 118086594104), together with native controls and NativeAOT. Overall CI is complete and red in Linux shard 2, Apple E2E and both recorded-crash containers. Current-head Codex and Greptile complete with no findings; the latest readiness workflow succeeds.

The new Linux shard failures include Java prerequisite cleanup and setup consumers, not the Windows endpoint fixture. No production or verification-oracle change is added to this PR.

Upstream controls now provide runtime evidence: main 3ea0d9489 CI and main 255d906e1 CI also fail both recorded-crash containers with the same historical-PID /proc//stat assertion. Main 255d906e1 Apple E2E also reports cleanup-stage process-identity-unavailable. Main has Linux cleanup failures too; this identifies a shared failure family, not the exact cause of each PR assertion.

A local main-source owned-command diagnostic, with an exact-path read observer and no production edits, records the sentinel stat read from readProcessRelationSnapshot via createOwnedCleanupPlan even for a normal Node command with no crash input. The sentinel stays alive. This supports an oracle attribution problem: the current verifier allows those reads only in the ps executable trace, while native ownership reads now occur in Node. Full local strace/recorded-crash reproduction is unavailable (strace is not installed), and neither the whitelist nor the ownership checks have been weakened.

These main issues remain separate. No independent repair PR is created; the existing independent branch remains at 5453f3cbb and Hopper remains local-only/unpublished. These heads include main 3ea0d9489; main has since advanced to 255d906e1 with base64/byte-pattern fixes, which do not change the inspected process, JADX or trace-verifier files. No new main sync is claimed.

Author readiness

Human owner: @siegfly

  • 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.

The human owner explicitly confirmed review of the final diff, validation and limitations, accepted responsibility for the complete PR, and declared initial readiness on 2026-10-16.


🔄 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/4334 **Author:** [@siegfly](https://github.com/siegfly) **Created:** 10/16/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `codex/windows-ghidra-endpoint-fix` --- ### 📝 Commits (10+) - [`a4791ed`](https://github.com/morluto/rea/commit/a4791edbae23e4d75d8d389e1300c80ae962e2eb) test(ghidra): align socket fixtures with Windows host boundaries - [`170206c`](https://github.com/morluto/rea/commit/170206c72f3457dadcd6cddc6e55522f42aff6cd) test(ghidra): gate endpoint discovery and cover Windows fixtures in CI - [`3c64161`](https://github.com/morluto/rea/commit/3c6416192191e9a03d364b69c7c06c71f3b4f560) test(ghidra): reach replacement and launch checkpoints on Windows - [`70198f9`](https://github.com/morluto/rea/commit/70198f939b486a7397af866c2775e6b004a932f5) test(ci): cover Ghidra file and launch host fixtures on Windows - [`2b86d08`](https://github.com/morluto/rea/commit/2b86d085812c47443e7d9834a1963a195ac0774e) test(ghidra): create fixture endpoints with the owned Windows writer - [`6bf1ac7`](https://github.com/morluto/rea/commit/6bf1ac732f367b1ae0fe5436eb38db3b8290206e) test(ci): select Windows lane for Ghidra runtime helper - [`944f283`](https://github.com/morluto/rea/commit/944f28358235de87e68fc23e6ed2114db99b2bff) chore: sync Windows Ghidra fixtures with latest main - [`cb91029`](https://github.com/morluto/rea/commit/cb910299c34ef46cdabe348c5c8672a9c555af91) chore: sync Windows Ghidra fixtures with latest main - [`c1aae16`](https://github.com/morluto/rea/commit/c1aae16fbb60c83100cf78b65def225b90fe7547) chore: sync Windows Ghidra fixtures with latest main - [`7a5681c`](https://github.com/morluto/rea/commit/7a5681cac70350b42853f7cb2d0d20a4910572bb) chore: include latest Electron ownership fix from main ### 📊 Changes **15 files changed** (+291 additions, -82 deletions) <details> <summary>View changed files</summary> 📝 `.github/workflows/ci.yml` (+7 -0) 📝 `scripts/ci/scopes.mjs` (+10 -0) 📝 `tests/boundary/filesystem/ciChangeScope.test.ts` (+22 -0) 📝 `tests/boundary/filesystem/ghidraExecutableHeader.test.ts` (+6 -2) 📝 `tests/boundary/filesystem/ghidraInstallationProperties.test.ts` (+6 -2) 📝 `tests/boundary/mcp/ghidraInventoryMcp.test.ts` (+14 -50) 📝 `tests/boundary/mcp/ghidraReopen.test.ts` (+3 -0) 📝 `tests/boundary/mcp/ghidraStartupCancellationMcp.test.ts` (+27 -4) 📝 `tests/boundary/providers/ghidra/ghidraClient.fixture.ts` (+63 -1) 📝 `tests/boundary/providers/ghidra/ghidraClient.test.ts` (+65 -3) 📝 `tests/boundary/providers/ghidra/ghidraLaunchOutcome.test.ts` (+6 -2) 📝 `tests/boundary/providers/startupCloseWaiters.test.ts` (+6 -2) 📝 `tests/fixtures/fakeGhidra.mjs` (+42 -15) 📝 `tests/fixtures/ghidraRuntime.ts` (+1 -1) 📝 `tests/process-global/curatedWindowsLane.test.ts` (+13 -0) </details> ### 📄 Description ## Summary Fix the Windows fake-Ghidra host fixtures by aligning endpoint publication, child ownership and test-host selection with the existing production boundaries. Include the affected tests in Windows CI. This is an independent follow-up to verification gaps found on #3075/#3076; it changes tests and CI, not production runtime authority. ## Problem and expected behavior Two original causes were isolated on main `1bd5c5c87` without either documentation patch: 1. **34 failures:** the fake producer renamed a pending endpoint into a private directory whose retained Windows guard forbids rename (`EBUSY`). Ordinary-directory rename succeeds on both C: and E: NTFS, while guarded-directory rename fails and exclusive direct creation succeeds. The Java bridge already directly creates the Windows endpoint. 2. **2 timeouts:** selecting `process.execPath` selects PE on Windows; session attestation starts before `callTool`, while the test waits for `callTool` admission before opening its startup gate. Fixed self-owned ELF samples remove that circular wait. Simulated installation metadata must also not select Unix sockets for actual Windows child processes. Review identified two remaining gaps: a synchronous direct write is still visible to another process before close, and the changed fixture paths did not select the Windows CI lane. ## Change and scope - Use the existing owned Windows writer to exclusively create an empty endpoint with the current-user owner, then have the fake bridge reopen that same file and acknowledge publication over IPC **after** its writer closes. The shared launcher waits for that explicit acknowledgement before returning the child to endpoint discovery. Unix socket listeners also acknowledge readiness; intentional silent/exit modes preserve their failure semantics. - Cancellation or child exit releases the wait while returning the owned child to the production client's supervisor and cleanup. Do not treat cancellation/exit as publication success, relax the native guard, or suppress malformed endpoint errors downstream. - Use fixed, never-executed ELF headers and one shared actual-host platform/transport owner. Reuse the existing launcher in inventory tests instead of duplicating process cleanup. Make premature MCP settlement fail the admission wait explicitly. - Add the affected fixture/test paths to package/runtime selection and seven actual test files to `windows-curated`. Keep existing mainline native-artifact-before-build and runner-cancellation coverage intact. - Skip only the unsupported Hopper-on-Windows restart case in addition to pre-existing platform skips; the original 36 failing cases remain enabled and pass. Current-main supplemental verification exposed three more Windows fixtures that fail before their intended boundary. The two file-replacement tests now rename the open original aside before publishing its replacement, preserving real identity-change assertions. The launch-cancellation test uses the shared production-owned private runtime root, reaching the actual preparation checkpoint while retaining foreign-reason and cleanup assertions. No production guard or error oracle is weakened. No new provider capability, target execution, installation change or maintainer scope decision is needed. No generated artifacts, native binaries or provider databases are committed. The fixture also uses the existing Windows owned writer to preserve the current-user file owner under elevated runner tokens. Its gated regression reads the still-empty endpoint through the real private-runtime owner check before releasing publication. Production guards, caller token and cleanup policy remain unchanged. ## Validation Current head **0a07c2a70** includes main **3ea0d9489 / 6.7.0**. Verification uses Node 24.18.0 / npm 11.16.0. Fresh local Windows CI selection: **47 files / 640 pass / 41 existing skips**. Conflict-focused Ghidra/client/MCP selection: **Windows 101 pass / 11 existing skips; Linux 110 pass / 2 existing skips across the same six files**. The upstream budget-exhausting-output startup-timeout case executes and passes on Linux. Full check, docs:check (5 README cases) and normal pre-push checks pass. Final-tree Windows package verification passes: 207 tools, packaged bridge, idempotent client setup, uninstall and exact-release update. ## Synchronization and CI diagnosis Resolved the shared fake-Ghidra conflict by preserving main’s `flood_silent` producer and this PR’s Windows endpoint ownership. The silent/flood producer acknowledges fixture readiness without publishing an endpoint; flood output can then drain before the unchanged production startup timeout. The launcher does not precreate an endpoint for either silent mode. No production behavior or timeout changes. A commit-hook autofix touched an unrelated upstream Flutter regex during the merge. The follow-up restoration commit returns that file byte-for-byte to main. The final tree matches the tree used by all verification above and retains exactly the original 15 test/CI files relative to main; no unrelated runtime change remains. ## Independent fixes and limitations Main #5224 and the later native-preparation regression update cover most of the earlier independent fixes. Two Windows test gaps remain outside these PRs: a slash-only expected snapshot path and an MCP test expecting native Windows PTY capture to open a snapshot despite the documented unsupported-capability gate. A separate minimal two-file validation copy passes 15 tests on Windows and 15 on Linux. The published independent branch remains at 5453f3cbb; no independent-fix PR is opened, and none of its commits is merged/cherry-picked into these PRs. Its older full diff must not be replayed over newer upstream assertions, particularly the Darwin/Linux preparation distinction. The old inherited fallback-cancellation CI failures are removed by this main synchronization. Current-head CI and review results are pending after the push; local Windows/package passes are not hosted CI passes. Controlled fixtures do not establish new real Ghidra/JDK qualification. Hopper remains local-only and unpublished. ## New-head CI follow-up The new run is not green: [Apple artifact E2E](https://github.com/morluto/rea/actions/runs/39259351622/job/118084047547) fails while cleaning the Java availability probe (Java exits 0; process identity cannot be revalidated), and both Linux recorded-crash container lanes fail the historical-PID trace oracle ([Ubuntu log](https://github.com/morluto/rea/actions/runs/39259351622/job/118084048214)). The latter flags an attempted `/proc/<sentinel>/stat` read in a Node trace. These are different from the old fallback-cancellation assertions. The affected verification scripts and production cleanup/recorded-crash sources are identical to main 3ea0d9489; this PR's diff remains limited to its original tests/CI scope. This is a source comparison, **not clean-main runtime reproduction on macOS or those containers**. The recorded-crash oracle currently classifies allowed ownership observations only in a trace containing the exact ps execution; Node-side native ownership reads are a possible explanation, not a proven root cause. No trace allowance, ownership check or test deadline was weakened. Local Windows passes do not qualify macOS or the recorded-crash lane. Hosted Windows native-controls and NativeAOT builds pass; the Windows capability/package lane is still in progress at the follow-up check. <!-- ci-diagnosis-20261019:start --> ### Completed CI and main controls (2026-10-19) Hosted Windows capability/package finishes successfully (job 118086594104), together with native controls and NativeAOT. Overall CI is complete and red in Linux shard 2, Apple E2E and both recorded-crash containers. Current-head Codex and Greptile complete with no findings; the latest readiness workflow succeeds. The new Linux shard failures include Java prerequisite cleanup and setup consumers, not the Windows endpoint fixture. No production or verification-oracle change is added to this PR. Upstream controls now provide runtime evidence: [main 3ea0d9489 CI](https://github.com/morluto/rea/actions/runs/39261789271) and [main 255d906e1 CI](https://github.com/morluto/rea/actions/runs/39266528335) also fail both recorded-crash containers with the same historical-PID /proc/<pid>/stat assertion. Main 255d906e1 Apple E2E also reports cleanup-stage process-identity-unavailable. Main has Linux cleanup failures too; this identifies a shared failure family, not the exact cause of each PR assertion. A local main-source owned-command diagnostic, with an exact-path read observer and no production edits, records the sentinel stat read from readProcessRelationSnapshot via createOwnedCleanupPlan even for a normal Node command with no crash input. The sentinel stays alive. This supports an oracle attribution problem: the current verifier allows those reads only in the ps executable trace, while native ownership reads now occur in Node. Full local strace/recorded-crash reproduction is unavailable (strace is not installed), and neither the whitelist nor the ownership checks have been weakened. These main issues remain separate. No independent repair PR is created; the existing independent branch remains at 5453f3cbb and Hopper remains local-only/unpublished. These heads include main 3ea0d9489; main has since advanced to 255d906e1 with base64/byte-pattern fixes, which do not change the inspected process, JADX or trace-verifier files. No new main sync is claimed. <!-- ci-diagnosis-20261019:end --> ## Author readiness Human owner: @siegfly - [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. The human owner explicitly confirmed review of the final diff, validation and limitations, accepted responsibility for the complete PR, and declared initial readiness on 2026-10-16. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
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#6179
No description provided.