The semantic member-mutation collector revisits the same nodes while it closes
alias chains, and each visit re-derived results that cannot change within the
phase:
- resolveSemanticBindingState re-walked the scope chain for the same identifier
node. Definition collection completes before this phase, and addBinding is
reachable only from it, so a scope's bindings no longer change.
- directInitializerPosition, directMutationPosition and
referenceInitializerPosition are pure functions of a node and the analysis
parent map, but were recomputed for every mutation and initializer.
- markValue re-encoded the same capture tuple with JSON.stringify and built a
fresh long key for every Set/Map lookup, so each lookup re-hashed the whole
key. The capture key is now cached per binding, origin and owner, and the
lifetime key is derived from it.
On pdfjs-dist 5.3.93 wasm/openjpeg_nowasm_fallback.js (462316 bytes, sha256
53c228428a8861035a34738966af263fc9d4cee6df25a0ad942af947469a0bd9) the semantic
phase takes 177.8 s instead of 272.9 s in-process, with a byte-identical
semantic IR. With --max-heap-mb 3072 and the default heap the base revision
exhausts the worker; with the default 300 s per-source deadline raised, the
completed CLI run takes 240.6 s instead of 396.7 s and its output is identical
apart from volatile identifiers.
Refs #2498
Co-authored-by: gongfpp <22683417+gongfpp@users.noreply.github.com>
perf(javascript): avoid quadratic temporary matching state
Repeated source groups can allocate candidates that later identity matches
discard. Retain the original ambiguous groups until all tiers finish, expand
only unmatched survivors, and append to locally owned key buckets in place.
Constraint: Preserve matching priority, full ambiguity, and public output.
Directive: Do not re-match residual groups that become unique after later tiers.
Tested: 59 relevant tests, npm run check, and test discovery on current main.
Tested: CLI benchmarks and full-suite failure comparison on the recorded base.
Not-tested: Full suite on the updated main; native Linux and Windows workflows.
* fix(javascript-semantics): keep emitted data out of dispatch listener fields
The EventEmitter operation collector read argument position 1 as the
listener for every event method, so a dispatch such as
bus.emit("ready", data) reported the data binding and its range as the
listener. Only registration and removal name a listener there; emit
passes its remaining arguments to listeners that already exist. Read the
listener argument only for register and remove operations.
Fixes#2574
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* fix(javascript-semantics): read listener arguments only for listener-taking methods
removeAllListeners accepts only an optional event name, so gating the
listener argument on operation kind still reported an ignored second
argument as a listener. Gate on the methods whose argument position 1
names a listener instead: the registration methods, off, and
removeListener.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
* feat(browser): attach passive tools to browsers without HTTP discovery
Accept a literal loopback browser WebSocket,
ws://127.0.0.1:PORT/devtools/browser/ID, as the cdp_endpoint of the six
passive browser tools. Discovery then reads Browser.getVersion and
Target.getTargets over that socket, and the target session adopts the
same socket, so a browser that asks for consent per connection prompts
once per call.
The socket identifier gates access, so Evidence records the endpoint as
ws://127.0.0.1:PORT/devtools/browser/[REDACTED], and runtime
reconciliation accepts that recorded form. HTTP endpoints and their
Evidence are unchanged. Electron, web runtime, scenario and Inspector
endpoints stay HTTP-only.
Refs #2288
* test(browser): match browser-socket captures against HTTP discovery
Check in the real Chrome lane that DevToolsActivePort names the same
browser socket as /json/version, and that inspecting the selected page
through that socket leaves DOM structure and scripts unchanged compared
with an inspection through HTTP discovery.
Refs #2288
* fix(browser): bound browser-socket handshake and report discovery timeouts
Run the browser-socket WebSocket handshake and both discovery commands
under one discovery deadline, so a port that accepts the connection but
never completes the upgrade times out instead of waiting forever.
Report a reached deadline as a timeout without carrying the internal
abort as its cause, so CLI and MCP project provider_timeout rather than
cancelled. Caller cancellation is still reported as cancelled.
Refs #2288
Squash merge of https://github.com/morluto/rea/pull/2756.
Original pull request submitted by @xu91102.
Co-authored-by: hhang <169027046+xu91102@users.noreply.github.com>
* fix(javascript): keep configuration setting reads out of endpoints
Static endpoint extraction reads the first literal argument of any call
named get as an HTTP request path unless the receiver is a provable keyed
collection. VS Code extension bundles read settings through
`workspace.getConfiguration(section).get(key)`, so every setting key
became a network endpoint: the bundled Git extension's dist/main.js
reported 173 network endpoints, nearly all of them setting names such as
`autofetchPeriod` and `blame.statusBarItem.enabled`.
The lexical receiver classifier now records a `configuration` fact for a
`.get` call whose receiver is a `getConfiguration(...)` call, inline or
through a binding whose only visible write is one unconditional
initializer. Minifiers emit `let` for these bindings, so the proof relies
on the recorded writes rather than the declaration kind, as tRPC client
root resolution already does. Endpoint extraction skips non-URL literals
for that fact in both application and web bundle analysis. Reassigned,
conditional, and shadowed receivers, URL or path literals, and other
clients such as `api.get("users")` keep their endpoints.
The receiver fact union was duplicated in three modules; consumers now
import the classifier's type.
On the Git extension bundle, network endpoints drop from 173 to 7 with
unchanged analysis time (2.1 s).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(javascript): require the workspace host for configuration receivers
A bare or differently scoped `getConfiguration(...)` may be an
application's own HTTP client factory, so `.get("users")` on its result
lost its endpoint. Only `workspace.getConfiguration(...)` and
`<x>.workspace.getConfiguration(...)` now produce the configuration fact.
Minifiers keep property names, so the bundled VS Code Git extension still
reports 7 network endpoints instead of 173.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(javascript): recognize default VS Code namespace imports
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
Node's path.join does not reset at an absolute segment, so
path.join(__dirname, '/preload.js') is <dir>/preload.js. The static path
projection skipped the __dirname anchor and joined the remaining parts,
which turned that common spelling into the root path /preload.js. In an
app whose main script lives in src/, the BrowserWindow preload was then
reported not-found, or resolved to an unrelated preload.js at the artifact
root, and the utilityProcess.fork target was never resolved. String
concatenation had the same defect: path.dirname(__filename) +
'/preload.js' projected to /preload.js, and __dirname + '/preload.js'
stayed unknown.
A source directory now contributes "." to a join, so path.join(__dirname)
projects to "." like path.resolve(__dirname). A concatenation that starts
with __dirname or the source file's dirname keeps text that begins with a
separator inside that directory; other text extends the directory's own
name and stays unknown. The empty-string projection of
path.dirname(__filename), which produced the wrong concatenation, is
removed, so a bare path.dirname(__filename) is unknown like a bare
__dirname.
Replace the implicit local-provenance fallback with explicit locally constructed values. Keep opaque results, parameters and caught values unknown; follow assignment and sequence results while retaining exact module aliases. Clarify that alias provenance does not represent transitive data taint.
Validation: 26 focused provenance/module-link tests, 135 semantic and graph-builder tests, six application module-relationship boundary tests, and the fast typecheck/lint gate.
Compare import and require outcomes for static TypeScript references when compiler options are unknown. Preserve branch facts through worker IR and both graph projections; retain declaration fallbacks as candidates without changing explicitly selected paths.
Validation: 210 focused resolver and semantic tests; 21 production-boundary and source-extension tests. A bounded 2,000-reference probe adds about 16–17 ms wall time for dual resolution; full task token costs and real compiled application behavior remain unmeasured.
Use POSIX path semantics for recorded POSIX roots when reconciling runtime Evidence on Windows. Preserve Windows mapping behavior and cover implicit and explicit file roots through the reconciliation service.
Assisted-by: OpenAI GPT-6 <noreply@openai.com>
Co-authored-by: Aurantium-47 <280805072+Aurantium-47@users.noreply.github.com>
* fix(javascript): resolve module-relative Worker URL references
* fix(javascript): validate Worker URL paths independently of suffixes
* fix(javascript): preserve directory-form Worker URL paths
* fix(javascript): unwrap type assertions in Worker URL references
* fix(javascript): validate Worker bindings before URL resolution
* fix(javascript): leave drive-letter Worker URLs unresolved
Use WHATWG file URL parsing before pathname decoding to detect drive-letter
forms whose resource identity depends on the unmodeled source URL scheme.
Preserve encoded and ordinary relative pipe paths, and cover false matches
through the compiled CLI and resolver boundary tests.
* fix(javascript): preserve Worker URL identity boundaries
Recognize known Worker bindings before filtering callee spellings so ESM
aliases and transparent constructor wrappers reach URL analysis. Keep
root-relative module URLs unknown without a modeled runtime base root.
Index direct source-local global writes with the shared mutation collector
before promoting URL and browser Worker constructors. Preserve lexical
shadowing and unrelated property identities, and exercise all three review
regressions through the compiled CLI.
* fix(javascript): invalidate mutated import.meta URL bases
Track source-local import.meta writes alongside ambient global writes so
Worker URL expressions keep an unknown base after a possible URL mutation.
Tag the identity roots independently and cover direct mutation and unrelated
property cases through the compiled CLI.
* fix(javascript): close Worker URL identity and pathname gaps
Resolve ambient object identities before appending written properties, and
retain possible source-local aliases across rebinding. Reuse intrinsic
invocation handling for aliased and bound mutators, array spreads, and
transparent TypeScript wrappers while preserving Electron write semantics.
Keep malformed-percent nested Worker URL pathnames unknown because the base
scheme is unavailable and Node rejects these file URLs. Preserve tolerant
HTML URL handling, valid escapes, and query/fragment evidence.
Cover the new cases and unrelated writes through the compiled CLI with
existing-file decoys. All 591 targeted tests and npm run check pass.
* fix(javascript): bound alias expansion and classify Worker paths
Join ambient identity projections instead of enumerating alias histories.
Memoize repeated value and provenance queries while preserving capture,
depth, and cycle-dependent uncertainty.
Keep Node Worker string arguments unresolved without filesystem or cwd
context, and admit qualified global URL constructors through identity checks.
Validate three 40-level alias branch shapes through the compiled CLI,
925 source tests, 25 CLI/boundary tests, and the full npm run check gate.
* fix(server): preserve partial Evidence target-content provenance
Pass the exact named contract returnsTargetContent flag through the shared partial-Evidence error delivery path introduced by the shortlist integration.
Exercise successful and failed recording through in-memory MCP for marked and unmarked contracts, preserving source payload and original failures. Observe both shared-handler emission and wire delivery so the SDK error-marker fallback cannot hide omissions. Suppressing the flag fails exactly the two marked cases.
Validation: check:fast, check, 736 semantic tests, 29 MCP transport/error tests and six compiled static Worker CLI journeys pass. No live target/provider execution or hosted publication.
* fix(javascript): structurally share semantic dependency proofs
---------
Co-authored-by: baron <richstyles@gmail.com>
URL.search and URL.hash are empty for both a missing component and an explicit empty one, so endpoint and origin checks were accepting URLs the callers meant to reject.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(javascript): bound value evaluation through nested closure aliases
A closure that aliases a binding from its enclosing scope evaluates that
binding once live and once at its own capture point. The capture cannot
order a binding declared in another function, so it fell back to a second
live evaluation. Only primitive results were kept, so every level of
nesting doubled the work: 20 nested closures over a non-constant value
took about 14 s, and a 443 KB generated wrapper reached the 300 s
analysis timeout.
Keep a live binding value when no caller could change it: no alias cycle
closes on or above the binding and the expression depth budget was not
reached. Bindings on a cycle are still re-evaluated, so their values and
reasons are unchanged.
Found while building a source-owned reproduction for #1847; that report's
worker heap exhaustion is a separate, already closed defect.
* fix(javascript): keep the expression depth budget for retained values
Reusing a retained composite value from any depth let a chain of wrappers
(s1 = {x: s0}, s2 = {x: s1}, ...) nest past the expression depth budget:
300 wrappers produced a 299-level value where the budget stops at 86, the
serialized IR grew quadratically, and 3,000 wrappers overflowed the stack
in JSON.stringify.
Record the expression depth at which each caller-independent value was
derived and reuse it only at that depth or shallower. A deeper reader
derives the value again and reaches the budget exactly as before. Closure
aliases read their outer binding at one depth on both paths, so nested
closures stay linear.
* fix(reference): report sloppy scripts, PHP, C# and enclosing Git facts
Importing the source/ subtree of a legacy PHP and C# checkout produced
four wrong or missing facts:
- Babel's unambiguous mode parses a module first and keeps its
strict-mode recovery errors after falling back to a script, so a valid
sloppy-mode `delete messages;` was reported as a parse failure and the
semantic IR marked the file as parser-recovered. Parsing now goes
through one owner that re-parses such a script as a script.
- .php and .cs files had no language; they are now detected as PHP and
C# (detection only, no parsing).
- A root without its own .git was reported as having no version
control even inside a checkout. The adapter now resolves the nearest
enclosing repository, as Git does, and reports `none` only when no
ancestor has one.
- The CLI recorded importer_version as null although the package
version is known.
* fix(reference): keep module strictness and classify C# and PHP as source
Review follow-up. `.mjs` and `.mts` files are modules by extension, but
the script fallback re-parsed them in sloppy mode and erased real
strict-mode errors. The parser boundary now owns the extension rule,
parses explicit modules as modules and applies the fallback only when
the mode is ambiguous; the require-binding analysis uses the same rule.
`.cs` and `.php` received a language but stayed classified as unknown,
so source-to-bundle comparison dropped them. Both are now source
extensions, like the other detected languages.
* fix(reference): honor package module scope and keep unknown-mode strict errors
Review follow-up. A `.js` file under a package.json with `"type":
"module"` is an ES module, but it went through the script fallback that
erases strict-mode errors. The import now reads each in-inventory
package.json and parses `.js` files in a module scope as modules. Other
`.js` and `.ts` sources keep an unknown mode, because bundlers treat them
as modules without that field: they are no longer forced to script, and
errors that only the module parse reports are kept as an entry limitation.
* fix(reference): bound package scopes and keep application parsing unchanged
Review follow-up.
- `.cjs` files parse as scripts, so module-only strict errors no longer
become limitations on CommonJS trees. `.cts` keeps an unknown mode
because TypeScript compiles ES import syntax there.
- An unreadable or linked package.json now bounds the module scope with
an unknown type instead of letting an outer `"type": "module"` apply.
- The application pipeline parses as on main again. Its module-only
strict errors keep a source partial; package-mode handling stays in the
reference importer.
* refactor(reference): keep unmarked module modes unknown instead of resolving package scope
Review follow-up. Resolving Node package scope for `.js` kept pulling in
more of Node's lookup semantics (require bindings, excluded or
directory-named manifests). Only extensions now select a mode: `.mjs`
and `.mts` parse as modules and `.cjs` as scripts. Every other source
keeps an unknown mode, so module-only strict errors stay visible as an
entry limitation instead of being dropped or asserted. This matches the
require-binding analysis, which also treats unmarked paths as unknown.
Identify the factory exports parameter through the existing semantic binding owner, including renamed and minified Webpack parameters. Reject nested targets, bare alias rebinding, and shadowed identifiers. Prune the duplicated source happy path after validating the public CLI workflow.
Validation: public analyze-javascript-application CLI acceptance and focused semantic traversal/module-index tests.
Fixes#2171
Share contextBridge argument ownership between direct and wrapped analysis, seed intact isolated-world calls, and preserve dynamic world IDs and conditional metadata as unknown. Keep callee evaluation scoped to each invocation.
Validation: 99 focused source tests and bundled isolated-world acceptance through dedicated and generic CLI routes. Removed duplicate literal source regression in favor of public workflow coverage. Fixes#2174.
Retain exact empty and computed literal keys in JavaScript observations. Bind CDP response bodies to request occurrences, account for late responses, and validate the target after final progress callbacks.
Distinguish an unresolved goal from an exhausted call graph and preserve provider failures through cancellation. Retain completed IDA replies and post-operation identity observations as partial Evidence without claiming a verified final binding. Remove source-wide bundler cache-name heuristics and stale expectations.
Share loader selection across static findings and module relationships: CTS static imports and re-exports use CommonJS lookup while dynamic imports retain ESM lookup. Retain runtime import-equals dependencies, bindings, and exported names; do not resolve require file-URL strings as local artifacts. Restore import-map descriptions in CLI help.
Validated resolver and semantic tests, application reconstruction boundaries, and CLI help. Installed TypeScript NodeNext emission and Node require behavior were checked independently. Refs #2056, #2057, #2058, #2053.
Keep omitted discovery attachment state as null through Node, browser, Electron, and reconciliation evidence. Report the uncertainty while retaining Node observation unless discovery explicitly marks the target attached. Reject worker TargetInfo records missing the required boolean with partial coverage.
Validate omitted and explicit states through provider, CLI, and MCP boundaries and real Node 24 Inspector workflows. Consolidate Electron regression coverage into the existing list-and-inspect workflow.
BREAKING CHANGE: attached fields in JavaScript runtime, browser, and Electron target discovery and inspection results may be null when discovery does not report attachment state.
Reconcile Mach-O UUID observations without hiding malformed or conflicting sources. Require source-map identity digests to be supported by consistent observations. Keep truncated Android manifests as partial raw evidence, validate WABT section framing, and reject missing JEB inventories or error-marked success replies.
Consolidate native UUID parsing and simplify capacity and malformed-input fixtures. Focused source and public workflow checks pass, including native arm64e inspection and real WABT framing probes; a successful real JEB GUI project opening remains unverified.
* feat(mcp): derive an API surface view from retained web network captures
* fix(mcp): fail closed on sensitive parents and budget api-surface path expansion
* fix(mcp): keep recorded api-surface paths and budget only templated segments
* fix(mcp): read api-surface paths only from canonical URLs and charge new values once
* fix(mcp): reject authority-less api-surface URLs and key groups by rule positions
* fix(mcp): label api-surface confidence from all groups and cap transient path memory
* fix(mcp): budget api-surface dedup sets and narrow detail outputs
Charge retained deduplication sets before allocation, advertise only
each analysis operation's summary from its detail output, and document
that any templated group makes every API-surface page inferred.
* fix(mcp): bound api-surface path text and record limitations
Charge retained literal path copies before allocation, publish only
valid media-type essences, and deduplicate examined record limitations
onto the view.
* fix(mcp): keep api-surface refusals and path splits inside the reply budget
Sensitive-parent refusals now use the token sensitive_values_unretained so declared literals are not echoed. A later path split is charged against bytes already retained, and the published example includes the HAR record limitation with its matching digest.
* fix(mcp): budget api-surface method text before group keys
Charge method and origin text against the reply budget before the group key is serialized. Document that samples merge only when method, origin, and exact segment rules match.
* fix(mcp): bound api-surface copies and control-character authorities
Reject authorities containing a tab or newline so WHATWG cannot move userinfo into the recorded path. Charge four path copies, two method and origin copies, and each distinct content type against bytes already retained.
* fix(mcp): preflight combined api-surface group charges
Total path, method, origin, and segment charges before retaining a new group. Track content types in a set so distinct MIME essences are not compared quadratically.
* fix(mcp): charge api-surface content-type sets on first use
Create the per-group content-type set when the first essence is retained, and charge it before allocation. Groups with no content type no longer keep an empty set.
* refactor(analysis): centralize API-surface ownership and admission
Own grouping, deduplication, and combined retained/temporary resource admission in one accumulator. Charge fixed group storage before allocation and materialize only the requested page.
Share recorded URL parsing between capture redaction and projection, preserving source paths and excluding ambiguous credential fields. Cover resource admission invariants and the compiled HAR-to-view workflow.
* fix(analysis): admit capture schema clone before parsing
* fix(javascript): share Electron mutation proof with wrapped calls
* test(mcp): align graph and catalog checks with current contracts
* fix(analysis): admit and validate portable capture views
---------
Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
Include enclosing control-flow predicates when deciding whether symbolic
wrapper facts can be reported without guards. Preserve the guarded paths
and unresolved coverage instead of inventing unconditional exposures or
channel pairing candidates.
Keep fully observed renderer transmissions singular when tracing an exposed
callback. Distinct wrapper registrations still retain invocation identities.
This fixes the Electron package baseline's doubled transmission count.
Validation: check; 43 exact source and public CLI/MCP tests; existing artifact,
extraction, Electron analysis and routed-analysis verifier against the built
CLI. Installed-package platform coverage remains with CI.
Keep direct empty bridge objects observed, reject unexecuted initializers,
invalidate modified bootstrap tables and Electron identities, and retain
selection predicates through symbolic values and wrapper paths. Track lexical
binding identity and completed activation boundaries without leaking analysis
order into earlier reads.
Separate wrapper invocation provenance from the underlying IPC source range
so repeated registrations remain ambiguous through transfer and graph joins.
Use the same offered transfer budget for module preflight and final writing.
Index static literal properties once instead of rescanning every member. Keep
the original 10,001-member capacity fixture; Flameox confirmed the repeated
lookup cost and the optimized fixture completes in under one second locally.
Prune the stale compact-schema tool inventory assertion and update the public
call-graph registration expectation to its declared result envelope.
Validation: build, check, docs:check, 83 focused tests, 10 Electron identity
acceptance cases, 2 full-scale finding-capacity cases, and 7 compact-schema
transport tests. No real Electron runtime execution is claimed.
Analyze exact selected sources in first-request order before unrelated
static scopes, preserving full artifact identity and byte verification.
Retain selection in CLI/MCP Evidence and summaries, with explicit unknowns
and partial coverage for unselected sources. Keep default full analysis.
Fixes#1848
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
* fix(javascript): size the future static reserve by remaining sources
The parent reserved 80% of its result budget for future static facts
whenever any source remained, so one tiny later file could discard an
earlier file's completed semantic graph. Reserve at most one bounded
static checkpoint's retained size per remaining source, within the same
shared pool, so many remaining sources keep the previous protection.
Parent-budget rejections now report the effective admission budget and
explain that the CLI/MCP process heap, not max_heap_mb, bounds them.
Refs #1911
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(javascript): make parent budget remediation and its test runtime-aware
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(javascript): suggest a concrete parent heap size in remediation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(javascript): let parent budget rejections state their retained facts
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Consume arguments per generic function invocation rather than property-chain
depth. Preserve the callable receiver through call/apply, Reflect.apply and
bound invocation. Cover nested mutations and fresh targets through source
analysis and inert production CLI/MCP fixtures.
Fixes#1909.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
* fix(javascript): prove Electron module namespace conversion
* refactor(javascript): share AST child field metadata
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
* fix(javascript): retain destructured intrinsic writes
Share one pattern-target walker across lexical definitions, member mutation
tracking and Electron identity writes. Keep overwritten globals unresolved
without treating property keys or shadowed locals as global replacements.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
* fix(javascript): preserve intrinsic projections and fresh target identity
Resolve known mutators through static binding projections and prove stable
identifier chains to fresh literals before widening unknown mutation targets.
Keep reassigned, uninitialized and member-projected targets conservative.
Cover both review regressions through source tests and inert CLI/MCP fixtures.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
* fix(javascript): retain fresh function and class target identity
Recognize stable local function, undecorated class and RegExp targets before
widening intrinsic mutations. Keep decorated classes opaque because their
binding value can be replaced, and preserve class-initialization writes.
Cover fresh targets and replacement decorators in inert CLI/MCP fixtures.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
* fix(javascript): preserve intrinsic alias capture timing
Validate each alias read after initialization and retain the original function capture across copies. Share declaration initializer facts with RPC and Electron analysis, including class declarations used for fresh-target identity. Accept single-statement control blocks while keeping lexical roles and added operations checked. Cover the capture regressions through inert source and public CLI/MCP workflows.
* fix(javascript): respect hoisted fresh function declarations
Function declarations provide fresh targets before their textual position. Retain initialization-order checks for variable and class values, including aliases. Cover the reviewed regression with source controls and the public CLI/MCP fixture.
* fix(javascript): preserve proven interop result projections
* fix(javascript): retain stable declarations and bound intrinsic writes
Keep repeated variable declarations with one unconditional initializer while
rejecting assignments, conditional initialization and multiple values.
Normalize known intrinsic calls, aliases and bound argument prefixes at the
semantic owner, retaining opaque targets without tainting unused bindings or
fresh local objects. Cover both regressions through source and CLI/MCP tests.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
* fix(javascript): retain bound intrinsic mutation effects
* fix(javascript): preserve bound receivers for intrinsic invocation
* fix(javascript): prove generic binding and invocation effects
* fix(javascript): retain Reflect set receiver effects
---------
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
* fix(javascript): follow bundler namespace interop for Electron APIs
Rolldown/tsdown emit `let electron = require("electron"); electron =
__toESM(electron);` and esbuild/tsc emit `__toESM(require("electron"))`
or `__importStar(require("electron"))` for namespace imports. The
reassignment or the helper call hid the Electron origin, so bundled
main processes reported zero BrowserWindows and preloads.
Locally declared, never reassigned interop helpers recognized by name
now pass the module through, and a binding's rewrap of its own value is
not treated as a reassignment. Other writes stay unresolved.
Fixes#1802
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(javascript): require emitted interop helper definitions
Only trust an interop helper name when it has a single program-scope
function definition, and state that helper bodies are not evaluated.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* fix(bun): report the real runtime and enforce worker memory budgets on Windows
Under Bun, REA recorded Node/V8 identity it did not observe and its JavaScript helper processes ran without a memory bound, because Bun ignores the V8 heap flags REA passes. Source-map trace Evidence claimed runtime node-v8 with Bun's synthetic V8 heap limit (the decoder then rejected that limit, so trace_web_source_location always failed), analysis resource failures reported heap limits Bun does not enforce, the HAR decoder claimed a fixed 192 MiB heap, and doctor reported Bun's Node.js compatibility version as the Node version.
Identify the runtime once from process.versions. Source-map reports record id bun with the Bun and Node.js compatibility versions and a null v8_heap_limit_bytes; the decoder checks the heap budget only for V8 reports and rejects a report from a runtime other than the launching one. The analysis worker reports a null heap limit under Bun, HAR limitations and failures omit heap sizes under Bun, and the doctor node check reports Bun and passes when its Node.js compatibility version is supported.
On Windows under Bun, each helper's owned Job Object now carries a commit limit of its heap budget plus a measured 512 MiB Bun runtime reserve (704 MiB for the codec and HAR decoder, 1536 MiB for the default analyzer). The native addon accepts an optional page-aligned job memory limit on process_spawn, verifies it by readback, associates a private completion port before the child is created, and reports a sticky memoryLimitReached and peak job commit on each poll; inspect reports jobMemoryLimit. A requested limit with an artifact lacking the control refuses the launch, and non-Windows launchers refuse a limit.
Reaching the limit is classified by the job notification rather than Bun's exit status: the analyzer fails the current source with a memory resource failure reporting worker_process_memory_limit_bytes, the codec returns a memory resource failure, and the HAR decoder returns its memory failure with process_memory_limit_bytes. Bun source-map Evidence records process_memory_limit_bytes, verified against the launcher. Node.js launches and outputs are unchanged.
* fix(windows): drain memory notifications after observing exit
---------
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>