[PR #1857] [MERGED] fix(javascript): prove namespace interop before attributing Electron APIs #4855

Closed
opened 2026-10-31 00:56:03 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/1857
Author: @N0zoM1z0
Created: 10/11/2026
Status: ✅ Merged
Merged: 10/11/2026
Merged by: @morluto

Base: main ← Head: fix/1842-electron-interop-provenance


📝 Commits (10+)

  • ebaa639 fix(javascript): prove Electron module namespace conversion
  • 9788112 fix(javascript): integrate verified namespace interop with main
  • 6d470fc fix(javascript): integrate current managed and stability fixes
  • ced8778 refactor(javascript): share AST child field metadata
  • 824728d fix(javascript): retain destructured intrinsic writes
  • 47f8156 fix(javascript): integrate current provider timeout recovery
  • 5569e96 fix(javascript): preserve intrinsic projections and fresh target identity
  • b03df22 fix(javascript): retain fresh function and class target identity
  • 548a433 fix(javascript): preserve intrinsic alias capture timing
  • 6b46068 fix(javascript): respect hoisted fresh function declarations

📊 Changes

15 files changed (+2043 additions, -221 deletions)

View changed files

📝 docs/javascript-artifact-reconstruction.md (+36 -9)
➕ src/domain/javascript/electronModuleInterop.test.ts (+618 -0)
📝 src/domain/javascript/electronStaticAnalysisIdentity.test.ts (+50 -1)
📝 src/domain/javascript/javascriptAstValues.ts (+8 -4)
📝 src/domain/javascript/javascriptElectronMemberWrites.ts (+100 -13)
➕ src/domain/javascript/javascriptIntrinsicInvocation.ts (+123 -0)
➕ src/domain/javascript/javascriptModuleInterop.fixture.ts (+24 -0)
➕ src/domain/javascript/javascriptModuleInterop.ts (+774 -0)
📝 src/domain/javascript/javascriptRpcEndpoints.test.ts (+26 -0)
📝 src/domain/javascript/javascriptSemanticAnalysis.ts (+65 -112)
📝 src/domain/javascript/javascriptSemanticMemberMutations.ts (+10 -9)
📝 src/domain/javascript/javascriptSemanticRequireOrigin.ts (+0 -71)
📝 src/domain/javascript/javascriptSemanticState.ts (+24 -0)
📝 src/domain/javascript/javascriptSemanticTraversal.ts (+5 -2)
➕ tests/acceptance/applications/electronModuleInteropCli.test.ts (+180 -0)

📄 Description

Summary

A helper named __toESM that returns {BrowserWindow: FakeWindow} currently produces an Electron window observation. This follow-up to #1827 replaces emitted-name trust with structural proof while retaining the released T3 Rolldown namespace conversion. Fixes #1842; validates the original #1802 reproduction.

Problem and expected behavior

let electron = require("electron"); electron = __toESM(electron, 1) must retain origin only when the helper preserves that module. Stable names alone cannot prove this. Unproven results must remain unresolved.

Change and scope

  • One semantic owner matches the complete released Rolldown conversion/copy operations with lexical-role equivalence and captured intrinsic origins. Stable, pure parameter-return helpers also preserve identity, including fresh imports and direct call roots.
  • The existing write traversal records intrinsic effects against capture/conversion positions and callable scope. Known Object/Reflect mutators remain recognizable through static destructuring projections and bound aliases that preserve prebound targets and keys. Stable identifier chains to fresh object, array, function, undecorated class and RegExp syntax stay separate from intrinsic objects; opaque, decorated, reassigned, projected-member and not-yet-initialized targets remain conservative. Class-initialization writes are still retained. One shared pattern walker retains nested/default/rest identifier and member targets, including loop writes, while excluding keys and shadowed locals. Other callable bodies and later global-property replacements cannot invalidate an already captured function solely by source presence.
  • Remove superseded name-only normalization; reuse the shared AST owner for child fields. Keep general reassignment rules and source anchors.

Contract and boundary impact

  • Semantic owner/earliest stage: JavaScript Electron lexical identity classification.
  • CLI/MCP: same schemas and shared workflow; unproven helper results produce fewer inferred findings.
  • Provider/platform: static JavaScript only; no provider setup changes.
  • Evidence/provenance: original call-site ranges and dynamic preload expressions retained.
  • Process/authorization/cleanup: no target execution or additional processes.
  • Generated metadata/package/installation: ignored outputs regenerated; no authored package changes.

Evidence and regression coverage

  • 165 dedicated domain cases cover canonical/renamed helpers, identity helpers, fake/async/generator/fallback helpers, shadowing, reassignment, intrinsic writes, mutators, destructuring, fresh targets, class decorators, class-initialization effects and capture scope.

  • CLI and production stdio MCP fixture retains seven real construction anchors despite local-object/function/class/RegExp mutation and excludes the fake helper and eight reached modules with overwritten intrinsics, including a destructured mutator, replacement class decorator and bound mutator. All ten JavaScript files are parsed; literal preload resolves, dynamic expression stays unknown.

  • On main 0b4ce8361, public CLI reports one window for the fake helper; final tree reports zero.

  • Contributor verification on the exact public T3 nightly main producer source (SHA-256 e566055ab42d104b413575920bb62ea7f43677e014ad840fd7319d69fc83cf1f, 5.4 MB) reports four windows and zero parse failures. Dynamic preloads remain visible; resolved preload entrypoints remain zero in this subset.

  • Proof gaps: this is a boot/main source subset, not the complete ASAR. No Electron execution. Arbitrary cross-call side effects and other unverified esbuild/TypeScript/Babel helper bodies remain unresolved.

  • Observations and derived facts remain distinguishable.

  • Artifact/source identity and failed attempts remain preserved.

  • Unknown and partial outcomes remain visible.

Validation performed

  • Final review fixes — 73 interop cases, 277 adjacent source cases and four public CLI/production stdio MCP cases passed. Projected/fresh-alias regressions produced seven failures before their fix; function/class/RegExp cases produced six failures before expansion; the replacement decorator produced a false positive without the conservative class guard.
  • Main integration — 69 managed inspection and six Hopper handshake-recovery cases passed after incorporating the already merged provider timeout fix (#1866); those workflows are unchanged by the subsequent JavaScript review fixes.
  • Official facade verification and MCP schema regression coverage are recorded in #1828.
  • npm run check — passed, including architecture guards.
  • npm run docs:check — passed.
  • Public CLI T3/fake controls — four/zero windows, no parse failures.

Maintainer capture and normalization follow-up

  • Preserve the actual intrinsic function capture through initialized identifier and destructuring aliases. Reads before an alias initializer stay unresolved; the helper binding itself must initialize before conversion.
  • Share one unconditional declaration-initializer rule across RPC recognition, Electron origins, intrinsic aliases, and fresh-target checks, including class declarations. Retain the contributor follow-up for repeated variable declarations with exactly one unconditional initializer; assignments, multiple initializers and conditional initialization remain unresolved.
  • Normalize harmless single-statement if/for control blocks while retaining complete operations and lexical-role checks. Extra operations remain unresolved.
  • Recognize hoisted fresh function declarations and their stable aliases before their text; keep variable and class initialization ordering. This addresses review thread discussion_r4242170462.
  • Validation: 611 focused source tests and two public CLI/stdio MCP acceptance cases passed. The acceptance fixture preserves the latest function/class/RegExp and decorated-class controls, and now verifies an earlier captured function after global property replacement plus a hoisted function target.
  • Preserve literal member/destructuring projections at the interop owner. Omitted or literal node modes retain named exports; default projections require a truthy literal mode. Computed extra arguments remain unresolved for both namespace and identity helpers. Four projected-result regressions failed before the fix; public CLI and stdio MCP retain the two additional named-export anchors. This addresses review threads discussion_r4242217981 and discussion_r4242217985.
  • Resolve bound intrinsic mutators once at the semantic owner, including nested binding and call/apply invocation. Unknown bound arguments or replaced bind methods conservatively invalidate helper proof. Nested binding uses iterative traversal and one argument flattening pass. The public bound-mutator control produced eight windows before this fix and seven afterward in both CLI and production stdio MCP. This addresses review thread discussion_r4242268064.
  • Preserve the original bound receiver as well as arguments in the existing invocation contract. Generic Function.prototype.call/apply follow that receiver to the actual mutator; rebinding keeps the original receiver. Remove the redundant alias traversal from invocation normalization. Five valid generic-invocation controls failed before this correction; eight new cases cover generic invocation, receiver-preserving rebinding and fresh targets. The public CLI control reported eight windows before correction. Both final CLI/MCP controls retain seven windows across all ten parsed JavaScript files. This addresses review thread discussion_r4242338265.
  • Normalize generic binding creation through the same call/apply/Reflect.apply owner, including a bound generic binding helper. The invocation contract distinguishes known calls from unknown effects after visible intrinsic replacement, using actual alias-capture positions. Seven new negative controls failed before correction; five fresh/captured-alias controls preserve identity. Both public adapters include generic-bind and replaced-Reflect.apply modules. This addresses review threads discussion_r4242372178 and discussion_r4242372181.
  • Retain the explicit Reflect.set receiver as a possible write identity alongside the target. Unknown/spread receivers remain opaque; unrelated fresh receivers stay separate. Eight negative cases fail before correction and pass afterward, with two fresh-receiver positives. Public CLI/MCP include the receiver mutation module. This follows the ECMAScript Reflect.set contract and addresses discussion_r4242414414.
  • Both hoisting positives and five capture regressions failed before their respective fixes. The extra-operation and late-binding controls remain unresolved.
  • Combined revision: 613 focused tests across 17 files passed, including both public adapter regressions. Local build, full npm run check, and npm run docs:check passed. No Electron target execution or additional real-provider claim. Directly invoked local-function side effects remain explicitly unexamined.

Compatibility, safety, and release

  • No flags or schema migrations. Name-only helper inference is intentionally removed; structurally unverified variants remain unknown.
  • Linux x64 static CLI/stdio MCP coverage; no GUI, Windows/macOS runtime or deep-provider claims.
  • No package/release metadata changes, external requests from target code, or target execution.

Review checklist

  • Concrete bug, focused Conventional Commit outcome, related issue linked.
  • Observable behavior and meaningful failure paths tested.
  • Owning documentation updated; generated outputs remain ignored.
  • CLI/MCP output and limits stated.
  • Final diff checked for secrets, unrelated cleanup and unsupported claims.

🔄 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/1857 **Author:** [@N0zoM1z0](https://github.com/N0zoM1z0) **Created:** 10/11/2026 **Status:** ✅ Merged **Merged:** 10/11/2026 **Merged by:** [@morluto](https://github.com/morluto) **Base:** `main` ← **Head:** `fix/1842-electron-interop-provenance` --- ### 📝 Commits (10+) - [`ebaa639`](https://github.com/morluto/rea/commit/ebaa639cf85cb26da47146564c4bfbde862ec1f0) fix(javascript): prove Electron module namespace conversion - [`9788112`](https://github.com/morluto/rea/commit/9788112548234ee16939e0ab570386c19acd0791) fix(javascript): integrate verified namespace interop with main - [`6d470fc`](https://github.com/morluto/rea/commit/6d470fc9cb77e0974909a83e93feecaaec4c7b02) fix(javascript): integrate current managed and stability fixes - [`ced8778`](https://github.com/morluto/rea/commit/ced8778094f8c07956e3cd05b5d44080f9ee5c33) refactor(javascript): share AST child field metadata - [`824728d`](https://github.com/morluto/rea/commit/824728d7eee948eae46b7d3f1c270a33c0a6857e) fix(javascript): retain destructured intrinsic writes - [`47f8156`](https://github.com/morluto/rea/commit/47f8156efe9d92ec227432748816af6f1d0af59b) fix(javascript): integrate current provider timeout recovery - [`5569e96`](https://github.com/morluto/rea/commit/5569e96162a9705f7da8ee9a6d1e832186bd337f) fix(javascript): preserve intrinsic projections and fresh target identity - [`b03df22`](https://github.com/morluto/rea/commit/b03df22ce42f87d60f9e348888c3d9af0078ae4c) fix(javascript): retain fresh function and class target identity - [`548a433`](https://github.com/morluto/rea/commit/548a4334c488ffecaa400e4cb183d812f82ba4ad) fix(javascript): preserve intrinsic alias capture timing - [`6b46068`](https://github.com/morluto/rea/commit/6b460683d797f88adc5ee725ddac2f252f177aa0) fix(javascript): respect hoisted fresh function declarations ### 📊 Changes **15 files changed** (+2043 additions, -221 deletions) <details> <summary>View changed files</summary> 📝 `docs/javascript-artifact-reconstruction.md` (+36 -9) ➕ `src/domain/javascript/electronModuleInterop.test.ts` (+618 -0) 📝 `src/domain/javascript/electronStaticAnalysisIdentity.test.ts` (+50 -1) 📝 `src/domain/javascript/javascriptAstValues.ts` (+8 -4) 📝 `src/domain/javascript/javascriptElectronMemberWrites.ts` (+100 -13) ➕ `src/domain/javascript/javascriptIntrinsicInvocation.ts` (+123 -0) ➕ `src/domain/javascript/javascriptModuleInterop.fixture.ts` (+24 -0) ➕ `src/domain/javascript/javascriptModuleInterop.ts` (+774 -0) 📝 `src/domain/javascript/javascriptRpcEndpoints.test.ts` (+26 -0) 📝 `src/domain/javascript/javascriptSemanticAnalysis.ts` (+65 -112) 📝 `src/domain/javascript/javascriptSemanticMemberMutations.ts` (+10 -9) 📝 `src/domain/javascript/javascriptSemanticRequireOrigin.ts` (+0 -71) 📝 `src/domain/javascript/javascriptSemanticState.ts` (+24 -0) 📝 `src/domain/javascript/javascriptSemanticTraversal.ts` (+5 -2) ➕ `tests/acceptance/applications/electronModuleInteropCli.test.ts` (+180 -0) </details> ### 📄 Description ## Summary A helper named `__toESM` that returns `{BrowserWindow: FakeWindow}` currently produces an Electron window observation. This follow-up to #1827 replaces emitted-name trust with structural proof while retaining the released T3 Rolldown namespace conversion. Fixes #1842; validates the original #1802 reproduction. ## Problem and expected behavior `let electron = require("electron"); electron = __toESM(electron, 1)` must retain origin only when the helper preserves that module. Stable names alone cannot prove this. Unproven results must remain unresolved. ## Change and scope - One semantic owner matches the complete released Rolldown conversion/copy operations with lexical-role equivalence and captured intrinsic origins. Stable, pure parameter-return helpers also preserve identity, including fresh imports and direct call roots. - The existing write traversal records intrinsic effects against capture/conversion positions and callable scope. Known Object/Reflect mutators remain recognizable through static destructuring projections and bound aliases that preserve prebound targets and keys. Stable identifier chains to fresh object, array, function, undecorated class and RegExp syntax stay separate from intrinsic objects; opaque, decorated, reassigned, projected-member and not-yet-initialized targets remain conservative. Class-initialization writes are still retained. One shared pattern walker retains nested/default/rest identifier and member targets, including loop writes, while excluding keys and shadowed locals. Other callable bodies and later global-property replacements cannot invalidate an already captured function solely by source presence. - Remove superseded name-only normalization; reuse the shared AST owner for child fields. Keep general reassignment rules and source anchors. ## Contract and boundary impact - Semantic owner/earliest stage: JavaScript Electron lexical identity classification. - CLI/MCP: same schemas and shared workflow; unproven helper results produce fewer inferred findings. - Provider/platform: static JavaScript only; no provider setup changes. - Evidence/provenance: original call-site ranges and dynamic preload expressions retained. - Process/authorization/cleanup: no target execution or additional processes. - Generated metadata/package/installation: ignored outputs regenerated; no authored package changes. ## Evidence and regression coverage - 165 dedicated domain cases cover canonical/renamed helpers, identity helpers, fake/async/generator/fallback helpers, shadowing, reassignment, intrinsic writes, mutators, destructuring, fresh targets, class decorators, class-initialization effects and capture scope. - CLI and production stdio MCP fixture retains seven real construction anchors despite local-object/function/class/RegExp mutation and excludes the fake helper and eight reached modules with overwritten intrinsics, including a destructured mutator, replacement class decorator and bound mutator. All ten JavaScript files are parsed; literal preload resolves, dynamic expression stays unknown. - On main `0b4ce8361`, public CLI reports one window for the fake helper; final tree reports zero. - Contributor verification on the exact public T3 nightly main producer source (SHA-256 `e566055ab42d104b413575920bb62ea7f43677e014ad840fd7319d69fc83cf1f`, 5.4 MB) reports four windows and zero parse failures. Dynamic preloads remain visible; resolved preload entrypoints remain zero in this subset. - Proof gaps: this is a boot/main source subset, not the complete ASAR. No Electron execution. Arbitrary cross-call side effects and other unverified esbuild/TypeScript/Babel helper bodies remain unresolved. - [x] Observations and derived facts remain distinguishable. - [x] Artifact/source identity and failed attempts remain preserved. - [x] Unknown and partial outcomes remain visible. ## Validation performed - Final review fixes — 73 interop cases, 277 adjacent source cases and four public CLI/production stdio MCP cases passed. Projected/fresh-alias regressions produced seven failures before their fix; function/class/RegExp cases produced six failures before expansion; the replacement decorator produced a false positive without the conservative class guard. - Main integration — 69 managed inspection and six Hopper handshake-recovery cases passed after incorporating the already merged provider timeout fix (#1866); those workflows are unchanged by the subsequent JavaScript review fixes. - Official facade verification and MCP schema regression coverage are recorded in #1828. - `npm run check` — passed, including architecture guards. - `npm run docs:check` — passed. - Public CLI T3/fake controls — four/zero windows, no parse failures. ### Maintainer capture and normalization follow-up - Preserve the actual intrinsic function capture through initialized identifier and destructuring aliases. Reads before an alias initializer stay unresolved; the helper binding itself must initialize before conversion. - Share one unconditional declaration-initializer rule across RPC recognition, Electron origins, intrinsic aliases, and fresh-target checks, including class declarations. Retain the contributor follow-up for repeated variable declarations with exactly one unconditional initializer; assignments, multiple initializers and conditional initialization remain unresolved. - Normalize harmless single-statement if/for control blocks while retaining complete operations and lexical-role checks. Extra operations remain unresolved. - Recognize hoisted fresh function declarations and their stable aliases before their text; keep variable and class initialization ordering. This addresses review thread discussion_r4242170462. - Validation: 611 focused source tests and two public CLI/stdio MCP acceptance cases passed. The acceptance fixture preserves the latest function/class/RegExp and decorated-class controls, and now verifies an earlier captured function after global property replacement plus a hoisted function target. - Preserve literal member/destructuring projections at the interop owner. Omitted or literal node modes retain named exports; default projections require a truthy literal mode. Computed extra arguments remain unresolved for both namespace and identity helpers. Four projected-result regressions failed before the fix; public CLI and stdio MCP retain the two additional named-export anchors. This addresses review threads discussion_r4242217981 and discussion_r4242217985. - Resolve bound intrinsic mutators once at the semantic owner, including nested binding and call/apply invocation. Unknown bound arguments or replaced bind methods conservatively invalidate helper proof. Nested binding uses iterative traversal and one argument flattening pass. The public bound-mutator control produced eight windows before this fix and seven afterward in both CLI and production stdio MCP. This addresses review thread discussion_r4242268064. - Preserve the original bound receiver as well as arguments in the existing invocation contract. Generic `Function.prototype.call`/`apply` follow that receiver to the actual mutator; rebinding keeps the original receiver. Remove the redundant alias traversal from invocation normalization. Five valid generic-invocation controls failed before this correction; eight new cases cover generic invocation, receiver-preserving rebinding and fresh targets. The public CLI control reported eight windows before correction. Both final CLI/MCP controls retain seven windows across all ten parsed JavaScript files. This addresses review thread discussion_r4242338265. - Normalize generic binding creation through the same call/apply/Reflect.apply owner, including a bound generic binding helper. The invocation contract distinguishes known calls from unknown effects after visible intrinsic replacement, using actual alias-capture positions. Seven new negative controls failed before correction; five fresh/captured-alias controls preserve identity. Both public adapters include generic-bind and replaced-Reflect.apply modules. This addresses review threads discussion_r4242372178 and discussion_r4242372181. - Retain the explicit Reflect.set receiver as a possible write identity alongside the target. Unknown/spread receivers remain opaque; unrelated fresh receivers stay separate. Eight negative cases fail before correction and pass afterward, with two fresh-receiver positives. Public CLI/MCP include the receiver mutation module. This follows the [ECMAScript Reflect.set contract](https://tc39.es/ecma262/multipage/reflection.html#sec-reflect.set) and addresses discussion_r4242414414. - Both hoisting positives and five capture regressions failed before their respective fixes. The extra-operation and late-binding controls remain unresolved. - Combined revision: 613 focused tests across 17 files passed, including both public adapter regressions. Local build, full npm run check, and npm run docs:check passed. No Electron target execution or additional real-provider claim. Directly invoked local-function side effects remain explicitly unexamined. ## Compatibility, safety, and release - No flags or schema migrations. Name-only helper inference is intentionally removed; structurally unverified variants remain unknown. - Linux x64 static CLI/stdio MCP coverage; no GUI, Windows/macOS runtime or deep-provider claims. - No package/release metadata changes, external requests from target code, or target execution. ## Review checklist - [x] Concrete bug, focused Conventional Commit outcome, related issue linked. - [x] Observable behavior and meaningful failure paths tested. - [x] Owning documentation updated; generated outputs remain ignored. - [x] CLI/MCP output and limits stated. - [x] Final diff checked for secrets, unrelated cleanup and unsupported claims. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-31 00:56:03 +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#4855
No description provided.