[PR #7031] [MERGED] fix(electron): retain scoped IPC registration provenance #7590

Closed
opened 2026-11-03 13:38:55 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/7031
Author: @WenyuChiou
Created: 10/24/2026
Status: ✅ Merged
Merged: 10/24/2026
Merged by: @morluto

Base: main ← Head: fix/5300-scoped-ipc-provenance-20261024


📝 Commits (5)

  • af89bd3 fix(electron): retain scoped IPC registration provenance
  • 07bb33b fix(electron): defer mutation analysis until scoped receiver admission
  • 74d78f3 test(managed): align summary evidence with upstream input-path provenance
  • b6ad4b4 merge: retain upstream managed provenance assertions
  • f12ef74 merge: integrate upstream Evidence sealing repair

📊 Changes

12 files changed (+546 additions, -36 deletions)

View changed files

📝 src/application/javascript/ElectronBoundaryAnalysis.ts (+5 -3)
📝 src/application/javascript/ElectronBoundaryGraphIpc.ts (+47 -11)
📝 src/domain/javascript/electronStaticAnalysisIpc.ts (+48 -1)
➕ src/domain/javascript/electronStaticAnalysisScopedIpc.test.ts (+120 -0)
📝 src/domain/javascript/electronStaticAnalysisTypes.ts (+7 -0)
➕ src/domain/javascript/electronStaticReceiverAdmission.test.ts (+80 -0)
📝 src/domain/javascript/electronStaticRenderer.ts (+75 -20)
📝 src/domain/javascript/javascriptStaticAnalysis.ts (+6 -1)
📝 src/domain/javascript/javascriptStaticAnalysisState.ts (+7 -0)
📝 src/javascript/analysis/JavaScriptAnalysisWorkerSchemas.test.ts (+29 -0)
📝 src/javascript/analysis/JavaScriptAnalysisWorkerSchemas.ts (+8 -0)
➕ tests/boundary/cli/electronScopedIpc.test.ts (+114 -0)

📄 Description

Summary

Retain static IPC registrations on proven BrowserWindow webContents.ipc and webContents.mainFrame.ipc receivers, including supported stable aliases.

Refs #5300: this addresses the scoped-IPC subset only, not the entire issue. Constructor support, arbitrary unknown receivers and child-frame traversal remain outside this change; the constructor work in #2094 is not duplicated.

Problem and expected behavior

The existing static pass recognizes global ipcMain registrations but omits supported registrations on a known window's scoped IPC surfaces. On the baseline, two production analysis tests failed to find those scoped registrations while parsing, BrowserWindow provenance, global IPC and fake/shadowed receiver controls passed.

Recognized registrations should retain their receiver scope. A shared channel name must not imply that a renderer reaches a particular frame or window.

Change and scope

  • Reuse existing BrowserWindow receiver proof, source allocation ranges and intact binding/member checks.
  • Preserve receiver metadata through the strict worker schema and graph construction.
  • Include source path, artifact, module and receiver scope in scoped channel/handler identity so distinct files or receivers do not collapse.
  • Require exact property segments; reject dotted-key lookalikes, fake/shadowed receivers and invalidated bindings.
  • Treat compatible scoped handlers, including dynamic-channel handlers, as ambiguity rather than claiming unique global dispatch.

Contract and boundary impact

  • Semantic owners: static receiver analysis, worker serialization and Electron boundary graph identity.
  • Contribution scope: static analysis of existing source inputs; no new execution or mutation capability and no separate advance maintainer scope decision required.
  • CLI/MCP: existing commands and evidence schemas; recognized scoped registrations now appear in results without asserting runtime dispatch.
  • Provider/platform support and target selection: unchanged.
  • Evidence: preserve source-allocation provenance and scope; allocation identity is not unique runtime object identity.
  • Dependencies, installation and release metadata: unchanged.

This patch reads source/captured data only. It does not execute target Electron code, install Electron, connect to CDP, inject instrumentation or introduce network/process authority.

Evidence and regression coverage

Executed baseline regressions found two missing scoped registrations with positive global/provenance and negative fake/shadowed controls passing.

Final regressions cover separate frames, identical source content in different files, dynamic scoped ambiguity, stable aliases and mutation guards, strict worker roundtrip/rejections, and existing global-pairing/renderer-load behavior. Actual compiled CLI and stdio MCP requests exercise the production worker boundary against inert source fixtures.

Independent automated static review identified exact-key conflation and identical-content-file scope identity gaps; both were corrected and re-reviewed. The reviewer found no remaining blocker but did not execute tests or providers. This is not human review.

Preserved intermediate failures include the strict worker schema initially rejecting the added receiver metadata and a combined alias test expecting more recognition than the existing escape guard permits. The schema was fixed at its owning boundary. Alias coverage now separates proven positive cases from explicit conservative omissions rather than weakening the guard.

Validation performed

Linux cloud executor, Node 24.22.1 (repository pin), npm 11.9.0 (repository pin is 11.16.0), lockfile-pinned dependencies. Checks ran serially with bounded timeouts.

  • node node_modules/vitest/vitest.mjs run src/domain/javascript/electronStaticReceiverAdmission.test.ts src/domain/javascript/electronStaticAnalysisScopedIpc.test.ts src/domain/javascript/javascriptStaticApiIdentity.test.ts src/domain/javascript/electronStaticAnalysisIdentity.test.ts src/javascript/analysis/JavaScriptAnalysisWorkerSchemas.test.ts tests/boundary/filesystem/javascript-applications/electronApplicationAnalysis.test.ts tests/boundary/cli/electronScopedIpc.test.ts --maxWorkers 1 --no-file-parallelism — 93 passed, 7 files, including compiled CLI and stdio MCP.
  • node scripts/run-typescript.mjs --noEmit --checkers 1 --maxMemory 2G — whole-project typecheck passed.
  • Build TypeScript, catalog digest recording, MCP catalog recording and runtime bundling — passed; fresh compiled CLI/MCP rerun passed.
  • Scoped module boundaries, test discovery, architecture guards, lint, format and git diff --check — passed. Lint warnings remain, including a five-parameter helper; no suppressions added.

Tested base 97194c4b4808b2a9b79277c436ba9042c58b1b70. Main 12f6e0974cc0db0b3a9b86246accc76556837222 has no touched-file overlap and a clean local merge-tree check; that combined tree was not separately executed.

Compatibility, safety, and remaining limits

No WebContentsView/BrowserView constructor changes, webFrameMain.fromId, child-frame traversal, arbitrary runtime receiver IDs or runtime dispatch proof. Destructuring/dynamic receiver cases and existing mutation/escape uncertainty remain conservative omissions.

No real Electron runtime, full npm run check, full suite/coverage or package qualification was run. Static fixture text was never executed. No performance improvement is claimed; CPU and process-family peak memory were not measured.

The API-published commit differs in metadata from reviewed local commit a72380f3f5c70e8f5d3bf9c3561efe3229adf2c9; the complete tree is identical: bb4b0e9e91951f6fcd7cc51191de1198973b1275. All original 11 public file blob hashes were verified against the frozen reviewed files. The reviewed three-file follow-up has tree cf996e953aac07965ae23ca36492cc389ce835e2, identical to local commit 1b22fa68dc239d0174125d030975381b0294111f; all three updated public file hashes were verified.

Review follow-up

Addressed both Greptile P2 findings:

  • Prove the BrowserWindow constructor and supported receiver path before requesting mutation facts. Preserve every alias's consumed path and validate mutations at the original call site. On the original helper, owner-boundary instrumentation observed unnecessary indexing for EventEmitter and unsupported BrowserWindow calls (two failures), while the scoped positive control passed; all three now pass. This verifies avoided work, not a measured whole-task speedup.
  • Add an isolated compiled CLI and stdio MCP case with exactly one scoped literal handler, one renderer invocation and no global/dynamic handler. Both assert ambiguity, zero paired transmissions and no pairing edge.

The rebuilt runtime and final seven-file suite passed 93 tests, including four compiled CLI/MCP cases. Whole-project single-checker typecheck and scoped static checks also passed. Independent automated review approved the final source-local owner-boundary instrumentation; no global mocks remain. An intermediate mock-cache failure is preserved in local evidence rather than reported as success.

CI results from the earlier head do not qualify this new revision; current-head CI is pending.

Author readiness

Human owner: @WenyuChiou

  • 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 confirmed review of the current final diff and authorized recording these declarations.

Before merge

  • Required current-head checks and relevant verification are satisfied or their gaps are explicitly resolved by maintainers.
  • The human owner has completed the readiness declarations for this PR.
  • Material scope and authority questions are resolved.

🔄 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/7031 **Author:** [@WenyuChiou](https://github.com/WenyuChiou) **Created:** 10/24/2026 **Status:** ✅ Merged **Merged:** 10/24/2026 **Merged by:** [@morluto](https://github.com/morluto) **Base:** `main` ← **Head:** `fix/5300-scoped-ipc-provenance-20261024` --- ### 📝 Commits (5) - [`af89bd3`](https://github.com/morluto/rea/commit/af89bd31fb5ab94123aa7422d77b384d421a03b5) fix(electron): retain scoped IPC registration provenance - [`07bb33b`](https://github.com/morluto/rea/commit/07bb33b857e511eb69b2e4c96a4840b50def6d64) fix(electron): defer mutation analysis until scoped receiver admission - [`74d78f3`](https://github.com/morluto/rea/commit/74d78f314e2ed9fcc513c1c72a6a8fc4ced2656e) test(managed): align summary evidence with upstream input-path provenance - [`b6ad4b4`](https://github.com/morluto/rea/commit/b6ad4b41069c4224c0307ec05613938ca234816d) merge: retain upstream managed provenance assertions - [`f12ef74`](https://github.com/morluto/rea/commit/f12ef74bec02431c41a71711507f22bdd4191241) merge: integrate upstream Evidence sealing repair ### 📊 Changes **12 files changed** (+546 additions, -36 deletions) <details> <summary>View changed files</summary> 📝 `src/application/javascript/ElectronBoundaryAnalysis.ts` (+5 -3) 📝 `src/application/javascript/ElectronBoundaryGraphIpc.ts` (+47 -11) 📝 `src/domain/javascript/electronStaticAnalysisIpc.ts` (+48 -1) ➕ `src/domain/javascript/electronStaticAnalysisScopedIpc.test.ts` (+120 -0) 📝 `src/domain/javascript/electronStaticAnalysisTypes.ts` (+7 -0) ➕ `src/domain/javascript/electronStaticReceiverAdmission.test.ts` (+80 -0) 📝 `src/domain/javascript/electronStaticRenderer.ts` (+75 -20) 📝 `src/domain/javascript/javascriptStaticAnalysis.ts` (+6 -1) 📝 `src/domain/javascript/javascriptStaticAnalysisState.ts` (+7 -0) 📝 `src/javascript/analysis/JavaScriptAnalysisWorkerSchemas.test.ts` (+29 -0) 📝 `src/javascript/analysis/JavaScriptAnalysisWorkerSchemas.ts` (+8 -0) ➕ `tests/boundary/cli/electronScopedIpc.test.ts` (+114 -0) </details> ### 📄 Description ## Summary Retain static IPC registrations on proven BrowserWindow `webContents.ipc` and `webContents.mainFrame.ipc` receivers, including supported stable aliases. Refs #5300: this addresses the scoped-IPC subset only, not the entire issue. Constructor support, arbitrary unknown receivers and child-frame traversal remain outside this change; the constructor work in #2094 is not duplicated. ## Problem and expected behavior The existing static pass recognizes global `ipcMain` registrations but omits supported registrations on a known window's scoped IPC surfaces. On the baseline, two production analysis tests failed to find those scoped registrations while parsing, BrowserWindow provenance, global IPC and fake/shadowed receiver controls passed. Recognized registrations should retain their receiver scope. A shared channel name must not imply that a renderer reaches a particular frame or window. ## Change and scope - Reuse existing BrowserWindow receiver proof, source allocation ranges and intact binding/member checks. - Preserve receiver metadata through the strict worker schema and graph construction. - Include source path, artifact, module and receiver scope in scoped channel/handler identity so distinct files or receivers do not collapse. - Require exact property segments; reject dotted-key lookalikes, fake/shadowed receivers and invalidated bindings. - Treat compatible scoped handlers, including dynamic-channel handlers, as ambiguity rather than claiming unique global dispatch. ## Contract and boundary impact - Semantic owners: static receiver analysis, worker serialization and Electron boundary graph identity. - Contribution scope: static analysis of existing source inputs; no new execution or mutation capability and no separate advance maintainer scope decision required. - CLI/MCP: existing commands and evidence schemas; recognized scoped registrations now appear in results without asserting runtime dispatch. - Provider/platform support and target selection: unchanged. - Evidence: preserve source-allocation provenance and scope; allocation identity is not unique runtime object identity. - Dependencies, installation and release metadata: unchanged. This patch reads source/captured data only. It does not execute target Electron code, install Electron, connect to CDP, inject instrumentation or introduce network/process authority. ## Evidence and regression coverage Executed baseline regressions found two missing scoped registrations with positive global/provenance and negative fake/shadowed controls passing. Final regressions cover separate frames, identical source content in different files, dynamic scoped ambiguity, stable aliases and mutation guards, strict worker roundtrip/rejections, and existing global-pairing/renderer-load behavior. Actual compiled CLI and stdio MCP requests exercise the production worker boundary against inert source fixtures. Independent automated static review identified exact-key conflation and identical-content-file scope identity gaps; both were corrected and re-reviewed. The reviewer found no remaining blocker but did not execute tests or providers. This is not human review. Preserved intermediate failures include the strict worker schema initially rejecting the added receiver metadata and a combined alias test expecting more recognition than the existing escape guard permits. The schema was fixed at its owning boundary. Alias coverage now separates proven positive cases from explicit conservative omissions rather than weakening the guard. ## Validation performed Linux cloud executor, Node 24.22.1 (repository pin), npm 11.9.0 (repository pin is 11.16.0), lockfile-pinned dependencies. Checks ran serially with bounded timeouts. - `node node_modules/vitest/vitest.mjs run src/domain/javascript/electronStaticReceiverAdmission.test.ts src/domain/javascript/electronStaticAnalysisScopedIpc.test.ts src/domain/javascript/javascriptStaticApiIdentity.test.ts src/domain/javascript/electronStaticAnalysisIdentity.test.ts src/javascript/analysis/JavaScriptAnalysisWorkerSchemas.test.ts tests/boundary/filesystem/javascript-applications/electronApplicationAnalysis.test.ts tests/boundary/cli/electronScopedIpc.test.ts --maxWorkers 1 --no-file-parallelism` — **93 passed, 7 files**, including compiled CLI and stdio MCP. - `node scripts/run-typescript.mjs --noEmit --checkers 1 --maxMemory 2G` — whole-project typecheck passed. - Build TypeScript, catalog digest recording, MCP catalog recording and runtime bundling — passed; fresh compiled CLI/MCP rerun passed. - Scoped module boundaries, test discovery, architecture guards, lint, format and `git diff --check` — passed. Lint warnings remain, including a five-parameter helper; no suppressions added. Tested base `97194c4b4808b2a9b79277c436ba9042c58b1b70`. Main `12f6e0974cc0db0b3a9b86246accc76556837222` has no touched-file overlap and a clean local merge-tree check; that combined tree was not separately executed. ## Compatibility, safety, and remaining limits No WebContentsView/BrowserView constructor changes, `webFrameMain.fromId`, child-frame traversal, arbitrary runtime receiver IDs or runtime dispatch proof. Destructuring/dynamic receiver cases and existing mutation/escape uncertainty remain conservative omissions. No real Electron runtime, full `npm run check`, full suite/coverage or package qualification was run. Static fixture text was never executed. No performance improvement is claimed; CPU and process-family peak memory were not measured. The API-published commit differs in metadata from reviewed local commit `a72380f3f5c70e8f5d3bf9c3561efe3229adf2c9`; the complete tree is identical: `bb4b0e9e91951f6fcd7cc51191de1198973b1275`. All original 11 public file blob hashes were verified against the frozen reviewed files. The reviewed three-file follow-up has tree `cf996e953aac07965ae23ca36492cc389ce835e2`, identical to local commit `1b22fa68dc239d0174125d030975381b0294111f`; all three updated public file hashes were verified. ## Review follow-up Addressed both Greptile P2 findings: - Prove the BrowserWindow constructor and supported receiver path before requesting mutation facts. Preserve every alias's consumed path and validate mutations at the original call site. On the original helper, owner-boundary instrumentation observed unnecessary indexing for EventEmitter and unsupported BrowserWindow calls (two failures), while the scoped positive control passed; all three now pass. This verifies avoided work, not a measured whole-task speedup. - Add an isolated compiled CLI and stdio MCP case with exactly one scoped literal handler, one renderer invocation and no global/dynamic handler. Both assert ambiguity, zero paired transmissions and no pairing edge. The rebuilt runtime and final seven-file suite passed **93 tests**, including four compiled CLI/MCP cases. Whole-project single-checker typecheck and scoped static checks also passed. Independent automated review approved the final source-local owner-boundary instrumentation; no global mocks remain. An intermediate mock-cache failure is preserved in local evidence rather than reported as success. CI results from the earlier head do not qualify this new revision; current-head CI is pending. ## Author readiness Human owner: @WenyuChiou - [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 confirmed review of the current final diff and authorized recording these declarations. ## Before merge - [ ] Required current-head checks and relevant verification are satisfied or their gaps are explicitly resolved by maintainers. - [ ] The human owner has completed the readiness declarations for this PR. - [ ] Material scope and authority questions are resolved. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-11-03 13:38:55 +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#7590
No description provided.