[PR #1390] [MERGED] fix(javascript): bound member-mutation paths through reassignment loops #2847

Closed
opened 2026-10-17 21:10:58 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

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

Base: main ← Head: fix/member-mutation-blowup


📝 Commits (5)

  • 064de09 fix(javascript): bound member-mutation paths through reassignment loops
  • 56a40a4 fix(javascript): keep member-mutation unions sound for writes
  • 8d3f28b Merge remote-tracking branch 'origin/main' into review/member-mutation-1390
  • 261114d Merge remote-tracking branch 'origin/main' into review/member-mutation-1390
  • 03a960e fix(javascript): bound mutation paths without losing member facts

📊 Changes

4 files changed (+524 additions, -14 deletions)

View changed files

📝 src/domain/javascript/javascriptSemanticAnalysis.reference_lifetimes.test.ts (+157 -0)
📝 src/domain/javascript/javascriptSemanticMemberMutations.ts (+266 -4)
📝 src/domain/javascript/javascriptSemanticPropertyPaths.ts (+86 -0)
📝 src/domain/javascript/javascriptSemanticValues.ts (+15 -10)

📄 Description

Original contribution by Marnix Pluim; both original commits and their write-depth regressions are retained.

Reassignment loops introduced by #1292 can enumerate factorially many member-reference paths. Nine members took 28.36 seconds on frozen main 7aa4d768, and the real Notion ASAR did not finish within the 180-second guard. The repaired analysis completes while preserving both affected child bindings and unrelated sibling facts.

Fixes #1401. Refs #1065. This does not establish a common cause for #1387.

The collector now visits shallower paths first and retains exact covering prefixes instead of unioning different member keys. Write coverage includes path depth because a short write to an owned slot cannot replace a longer write reaching a shared child. A field-sensitive fixed point tracks observable object/array and Array-prototype origins; suffixes are canonicalized only where those origins cannot distinguish their effects. Dynamic selections, copied references and uncertain origins remain conservative. Value evaluation stops once mutation results are terminally unknown.

Regression coverage includes both conditional alias paths, deeper writes, untouched siblings below a shared prefix, unknown-slot presence, Array-prototype aliases, and loops rooted in unobserved/scalar values. No CLI/MCP contracts, tool inventory, target execution or provider authority change.

Validation on final source 03a960ebace7ab36dd9be78e2ba4399b9f6ade39, incorporating main 4d8ef3f3, pinned Node 24.18.0/npm 11.16.0, Linux x64:

  • 61-file JavaScript semantic/application suite: 1,030 tests passed; the six additional conditional/nested-path regressions also pass through the focused lifetime suite.
  • npm run check:fast, changed-file formatting, module boundaries, whitespace checks and npm run build:cached passed. The local single-threaded compiler preserves the full checking scope under the existing two-CPU resource guard.
  • Real Notion ASAR, SHA-256 97c41bc14fc0ea8c91cd34f502660963dfdf294d5eb35165ccac9d30963069d4: actual SDK 2.3.1 stdio MCP analysis took 100.15 seconds, whole workflow 120.26 seconds, and process-family peak RSS was 1.81 GiB. The caller allowed 210 seconds; this is not a default 60-second deadline claim.
  • Default 10 MiB framing returns a typed size constraint while retaining complete Evidence. Summary, module paging, feature tracing, subsequent ping, close and expired-reference behavior passed. Public compiled CLI completed in 88.06 seconds; identical explicit ASAR inputs produced the same Evidence ID, root digest and statistics through CLI/MCP. The source digest stayed unchanged.

Large-file responsiveness/cancellation remain open in #1065: longest observed ping was 19.17 seconds, chiefly during graph validation/sealing. This proves the tested loop regression and real artifact completion, not a universal bound for all JavaScript alias graphs. Real Hopper/Ghidra verification is not applicable to this static JavaScript change.


🔄 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/1390 **Author:** [@marnixpluim](https://github.com/marnixpluim) **Created:** 10/10/2026 **Status:** ✅ Merged **Merged:** 10/10/2026 **Merged by:** [@N0zoM1z0](https://github.com/N0zoM1z0) **Base:** `main` ← **Head:** `fix/member-mutation-blowup` --- ### 📝 Commits (5) - [`064de09`](https://github.com/morluto/rea/commit/064de095a056c62ac52999cb6004e232419b8d3c) fix(javascript): bound member-mutation paths through reassignment loops - [`56a40a4`](https://github.com/morluto/rea/commit/56a40a431718def3c433d7e44aae181aa4047eb5) fix(javascript): keep member-mutation unions sound for writes - [`8d3f28b`](https://github.com/morluto/rea/commit/8d3f28baffebd820fb9ea0a9312035dae9b8f43a) Merge remote-tracking branch 'origin/main' into review/member-mutation-1390 - [`261114d`](https://github.com/morluto/rea/commit/261114dd7d4d19ed1d67b6d6868f430f415e9a5d) Merge remote-tracking branch 'origin/main' into review/member-mutation-1390 - [`03a960e`](https://github.com/morluto/rea/commit/03a960ebace7ab36dd9be78e2ba4399b9f6ade39) fix(javascript): bound mutation paths without losing member facts ### 📊 Changes **4 files changed** (+524 additions, -14 deletions) <details> <summary>View changed files</summary> 📝 `src/domain/javascript/javascriptSemanticAnalysis.reference_lifetimes.test.ts` (+157 -0) 📝 `src/domain/javascript/javascriptSemanticMemberMutations.ts` (+266 -4) 📝 `src/domain/javascript/javascriptSemanticPropertyPaths.ts` (+86 -0) 📝 `src/domain/javascript/javascriptSemanticValues.ts` (+15 -10) </details> ### 📄 Description <!-- claude-projects-attribution: {"github_login":"marnixpluim"} --> _Original contribution by **Marnix Pluim**; both original commits and their write-depth regressions are retained._ Reassignment loops introduced by #1292 can enumerate factorially many member-reference paths. Nine members took 28.36 seconds on frozen main `7aa4d768`, and the real Notion ASAR did not finish within the 180-second guard. The repaired analysis completes while preserving both affected child bindings and unrelated sibling facts. Fixes #1401. Refs #1065. This does not establish a common cause for #1387. The collector now visits shallower paths first and retains exact covering prefixes instead of unioning different member keys. Write coverage includes path depth because a short write to an owned slot cannot replace a longer write reaching a shared child. A field-sensitive fixed point tracks observable object/array and Array-prototype origins; suffixes are canonicalized only where those origins cannot distinguish their effects. Dynamic selections, copied references and uncertain origins remain conservative. Value evaluation stops once mutation results are terminally unknown. Regression coverage includes both conditional alias paths, deeper writes, untouched siblings below a shared prefix, unknown-slot presence, Array-prototype aliases, and loops rooted in unobserved/scalar values. No CLI/MCP contracts, tool inventory, target execution or provider authority change. Validation on final source `03a960ebace7ab36dd9be78e2ba4399b9f6ade39`, incorporating main `4d8ef3f3`, pinned Node 24.18.0/npm 11.16.0, Linux x64: - 61-file JavaScript semantic/application suite: 1,030 tests passed; the six additional conditional/nested-path regressions also pass through the focused lifetime suite. - `npm run check:fast`, changed-file formatting, module boundaries, whitespace checks and `npm run build:cached` passed. The local single-threaded compiler preserves the full checking scope under the existing two-CPU resource guard. - Real Notion ASAR, SHA-256 `97c41bc14fc0ea8c91cd34f502660963dfdf294d5eb35165ccac9d30963069d4`: actual SDK 2.3.1 stdio MCP analysis took 100.15 seconds, whole workflow 120.26 seconds, and process-family peak RSS was 1.81 GiB. The caller allowed 210 seconds; this is not a default 60-second deadline claim. - Default 10 MiB framing returns a typed size constraint while retaining complete Evidence. Summary, module paging, feature tracing, subsequent ping, close and expired-reference behavior passed. Public compiled CLI completed in 88.06 seconds; identical explicit ASAR inputs produced the same Evidence ID, root digest and statistics through CLI/MCP. The source digest stayed unchanged. Large-file responsiveness/cancellation remain open in #1065: longest observed ping was 19.17 seconds, chiefly during graph validation/sealing. This proves the tested loop regression and real artifact completion, not a universal bound for all JavaScript alias graphs. Real Hopper/Ghidra verification is not applicable to this static JavaScript change. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-17 21:10:58 +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#2847
No description provided.