Retain named operations in GraphQL Source bodies with locationOffset metadata.
Use final property ownership and parsed lexical facts to suppress copies only
when a recovered document, its containers and source aliases have proven
private metadata ownership. Preserve independent observations after writes,
exports, opaque uses, classic-script global exposure or direct evaluation.
Share interpretation across application and captured-web analysis. Build
optional reference indexes once per source and checkpoint examined records,
including suppressed findings, to retain cooperative cancellation.
Fixes#3311
Co-authored-by: Kaoru0822 <[email protected]>
Co-authored-by: gensokyo-dev <[email protected]>
A release call was linked to its acquisition through the receiver's lexical
binding alone, so `stream = { destroy() {} }; stream.destroy()` still
produced a resolved `releases` edge to the original stream and entered the
default ownership trace.
A release is now complete only when every value written to the handle
binding is the linked acquisition itself (through parentheses, TypeScript
wrappers or `await`) or a nullish placeholder such as `let h = null`, which
cannot be released. Any other write, conditional replacement, or
destructuring keeps the linked release as a candidate (partial).
Fixes#3313
Co-authored-by: Claude Opus 5.5 <[email protected]>
The canonical `n.n` getter proof scanned for direct `loader.n =` assignments
and four Object methods on its own. `Reflect.set`, `Reflect.defineProperty`,
`delete`, destructuring and unknown-key writes left the proof intact, so a
replaced or deleted getter still attributed BrowserWindow calls to Electron.
Any Object method call on the loader also rejected the proof, even for an
unrelated key.
The proof now uses the shared identity-write owner
(`collectJavaScriptIdentityWritesSteps` with the module interop's intrinsic
resolution), as ambient writes already do. A write whose path may select `n`
(the key itself, an unknown key, or the whole loader) counts; exactly one
canonical assignment installed before entry dispatch remains required.
Fixes#3315
Co-authored-by: Claude Opus 5.5 <[email protected]>
semanticObjectPropertyReferences scanned every property of an object
literal on each call, and member-mutation tracking calls it once per
write, so N writes to an N-property literal cost O(N^2).
For an exact string or number key, a property with another static name
only updates override bookkeeping for that other name, which the key
never reads. Index each literal once by static name, keeping spreads,
computed keys and __proto__ data entries for every key, and walk only
the relevant members in reverse source order. Wildcard and selection
keys keep the full scan.
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(javascript): keep members unknown after a write through a local setter
Assigning to a key that a setter of the binding's own object literal
defines runs that setter, which may replace any member of its receiver.
The member-mutation collector recorded it as an ordinary write to that
one key, so sibling literals such as value: 1 stayed known and
export-shape comparisons reported complete, unchanged shapes.
Record such a write with an unknown key, which invalidates the object's
known members. A computed setter key may match any written key.
Fixes#3312
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* fix(javascript): follow nested setters, skip deletes and cache setter keys
Resolve the written receiver along nested object-literal members so a
write through a nested setter widens that receiver's members. A delete
never calls a setter, so it keeps its exact path. Setter keys are
computed once per object literal, including the no-setter result.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* fix(javascript): ignore setters replaced by a later data property
Build cached setter keys from the effective definitions: a later data
property or method with the same static name replaces the accessor, so
assigning that key no longer runs a setter.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
---------
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(javascript): keep the request endpoint on a uniquely consumed response
collectResponseConsumers always produced response-consumer operations
with endpoint null, so a json()/text() consumer that resolved to exactly
one request lost the request's literal endpoint in the semantic graph.
When the consumer resolves to one request through that request's own
result binding, the same condition that already makes it complete, it
now carries that request's endpoint. Ambiguous consumers stay null.
Fixes#3328
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* fix(javascript): drop the endpoint when another write can replace the response
Copy the request's endpoint only when the request is the binding's sole
write; any other assignment, update, loop or destructuring target can
replace the response before the consumer reads it.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
---------
Co-authored-by: Claude Opus 5.5 <[email protected]>
dataEffectLiteralString asked the literal owner for an exact value, and
when a template recovered with an invalid escape had no cooked value it
fell back to the raw spelling. Child-process commands, request endpoints
and event names then became resolved values that are not JavaScript
strings.
Use only the owner's cooked value; a template without one stays dynamic.
Fixes#3361
Co-authored-by: Claude Opus 5.5 <[email protected]>
A plain new Worker("./w.js") or navigator.serviceWorker.register("./sw.js")
resolves against the document base URL in a browser, and a Node
worker_threads string resolves against the working directory. Static
analysis was resolving browser strings against the calling script, which
recorded a resolved mapping to the wrong file.
Only new Worker(new URL(path, import.meta.url)) now produces a specifier.
Other worker and service-worker strings keep their expression and stay
unresolved, matching the existing worker_threads string handling.
Fixes#3309
Co-authored-by: Claude Opus 5.5 <[email protected]>
The endpoint index from #3779 still scanned every earlier finding at the
same endpoint and serialized each invocation location. One wrapper called
N times for one channel shares an endpoint, so duplicate checks stayed
quadratic in N.
Record per endpoint whether a directly observed send/invoke exists and the
set of serialized invocation locations. The duplicate rule is unchanged and
each check is constant time.
Refs #3670
Co-authored-by: Claude Opus 5.5 <[email protected]>
parserPluginsForPath enabled Babel's typescript plugin for .js, .jsx,
.mjs and .cjs sources. TypeScript reads some valid JavaScript
differently: a conditional whose consequent is an arrow with a
parenthesized body (c?x=>(a):y=>(b)) throws as a return-type
annotation, and a<b>(c) becomes a generic call. VS Code's 20 MB
workbench bundles therefore returned no AST at all.
Select JavaScript grammar (JSX plus legacy decorators) for explicit
JavaScript extensions. TypeScript dialects and unnamed sources keep the
existing TypeScript-capable contract.
Fixes#3780
Refs #3670
Co-authored-by: Claude Opus 5.5 <[email protected]>
Static analysis rebuilt the full lexical definitions index three times per
file (open receivers, RPC client roots, binding lookup) and the Electron
wrapper pass checked each substituted IPC registration against every prior
finding with JSON.stringify, which is quadratic in registrations.
Classify open receivers and RPC client roots in one traversal over a single
definitions-only index, then extend that same state with ambient writes for
binding lookup. Index IPC findings by side, operation, channel and location
so duplicate checks only consult same-endpoint candidates.
Static facts are byte-identical on the measured corpora.
Refs #3670
Co-authored-by: Claude Opus 5.5 <[email protected]>
Preserve uncertainty in offline passive network comparisons when request
identity, metadata, or per-kind inventory coverage is incomplete. Retain
proven HTTP/WebSocket changes without using missing information to infer
membership, duplicate counts, or equality.
Compare redirect resource types only where both observations retain them.
Keep metadata completeness with its owner, stream HTTP content digests,
and require full coverage for multiplicity and WebSocket stream inventories.
Preserve independently known metadata changes and full-inventory counts.
Keep the original JavaScript configuration-escape, JSON, cancellation,
SAZ and schema-documentation fixes compatible with current main. Split
public CLI comparisons into isolated test cases without loosening timeouts.
Validate actual Chromium/HTTP captures through CLI and real stdio SDK,
with explicit limits and unchanged source bytes.
Co-authored-by: To3akaRin <[email protected]>
Co-authored-by: N0zoM1z0 <[email protected]>
Co-authored-by: Kaoru0822 <[email protected]>
Co-authored-by: gensokyo-dev <[email protected]>
Declare fixed tuple tails and lengths at the canonical boundary so client array validation accepts every tool. Preserve nonempty candidate constraints in managed and application comparisons. Add catalog-wide client checks and parser/schema parity coverage for both dialects and projection directions.
Fixes#3576
Apply exact, contains, and case options to node IDs. Route seeds consume retained route values rather than generated display labels.
Refs: #3189, #3190, #3298
Co-authored-by: João Pedro de Faria <[email protected]>
Resolve CommonJS wrapper bindings from the parser-owned source type. Capture default identifier export values at the export statement while preserving live named bindings.
Refs: #3261, #3297
Co-authored-by: hhang <[email protected]>
Merge direct same-call nested member facts into symbolic wrapper results using canonical deduplication and ordering. Preserve unknown spread coverage rather than losing known member paths.
Validation: bounded source cases and public CLI/stdio MCP spread/no-spread controls. The existing 125,000-member stress case exceeded the 384 MiB local cap and was stopped without increasing the limit; that capacity case remains unverified locally.
Fixes#3212
Preserve missing ASAR companion occurrence identity, declared size and unknown content in graph nodes and resolution limitations. Apply URL text semantics once for ESM lookup while preserving literal CommonJS paths and original specifiers. Keep CJS wrapper var bindings and assignment history, recognizing only untouched wrapper redeclarations.
Validation: real ASAR producer workflow and CLI/MCP path/coverage cases; semantic reassignment controls. Context7 Node documentation and direct Node wrapper execution confirm wrapper behavior.
Fixes#3213Fixes#3214Fixes#3223
Related: #3278, #3254
Co-authored-by: Geronimo <[email protected]>
Co-authored-by: Paolo Valletta <[email protected]>
Normalize exact template and bigint keys at the shared AST boundary. Keep overwritten GraphQL body literals owned by their source object so they cannot resurface as standalone operations.
Reviewed-PR: #3244
Co-authored-by: Vaishnavi220506 <[email protected]>
Use shared lexical bindings and recovered bundler identities for require and chunk references. Preserve uncertain writes as unresolved evidence; remove name-only loader aliases and repeated definition scans.
Reviewed-PR: #2989
Co-authored-by: Hussnain Ahmad <[email protected]>
Give calls, captures, object operations, promises and effects one callable-owner tracker. Suspend a method while its computed key is evaluated in the enclosing callable; remove the capture-only downstream repair.
Co-authored-by: Alex Desir <[email protected]>
Retain directive literal values, including escaped strict-mode lookalikes, in semantic function fingerprints. Verify normalized duplicates and distinct directives through CLI/MCP.
Co-authored-by: To3akaRin <[email protected]>
Resolve final object writes once at the RPC endpoint producer. Unknown computed writes and spreads remain barriers; overridden properties do not invent endpoints. Source, CLI and stdio MCP regressions cover the behavior.
Co-authored-by: Vaishnavi220506 <[email protected]>
Own skipped-write interpretation at definition collection, including conditional branches, loop iterations and optional-chain arguments. Remove the narrower initializer-only representation.
Fixes#2562
Replace the whitespace-only header regex with bounded name/token scanning that consumes GraphQL comments and exact ignored characters at each boundary. Preserve anonymous, prose and incomplete input controls.
Validation: all 36 RPC endpoint tests pass. Fixes#2523.
Based on #2900.
Co-authored-by: Nikhil Jangid <[email protected]>
Use the parsed semantic property key instead of treating all bracketed keys as dynamic. Preserve empty and numeric literal keys; unresolved computed expressions remain unknown.
Validation: exact named preference and dynamic coverage regressions pass. Fixes#2521.
Based on #3105.
Co-authored-by: ShuaixinHuang <[email protected]>
Decode known literal file URLs with explicit path semantics before assigning filesystem-expression context. Preserve unknown drive, UNC, dynamic and malformed inputs and existing source-relative projection.
Validation: 64 path-owner and 26 filesystem application tests pass. Fixes#2561.
Based on #3147.
Co-authored-by: João Pedro de Faria <[email protected]>
Restore source-position-aware ambient aliases, scalar env/argv reads, candidate
endpoint worker data, Chrome DOMSnapshot empty strings, and accumulated Ghidra
LaunchSupport diagnostics. Align regression fixtures with declared current
contracts, while preserving identity, provenance, cancellation, and cleanup
checks. Assert workflow caveats independently at both established locations.
Validation: original five source failures reproduced on main; 307 focused tests
passed with one platform skip, 22 fixture follow-up tests and 22 workflow/MCP
tests passed; full static and docs checks passed. Real public http-server CLI
analyses preserve identical artifact identity, statistics, and 581-token selected
output. Real Chromium confirms restored DOM form destinations; isolated real
service-worker verification passes on main and the change. The complete local
browser run retained an unclassified later marker timeout; current-head CI
provides complete real-browser and recovery lane results. Native IDA/Ghidra
execution and complete local suite execution are not claimed.
Co-authored-by: Kaoru0822 <[email protected]>
Co-authored-by: N0zoM1z0 <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
Remove the separate Vite walker and raw visitor-key require scan. Keep subtree selection at the shared traversal owner. All 103 focused builtin/Vite tests and the complete static and architecture checks pass.
Preserve CommonJS literal paths and confined ESM URL semantics, including package main fallback, directory intent, Unicode identity, and present opaque modules. Parse extraction inputs at their AST/source owner, retain skipped HTML and source-map coverage, and distinguish endpoint candidates from proven receiver facts. Version structural fingerprints with computed literal contents and propagate them through worker contracts.
Reviewed fixes include #1810, #1840, #2642, #2700, #2702, #2714, #2803, #2960, #2968, #2986, #3035, and #3036.
Validation: 158 resolver tests passed; public CLI/MCP module lookup controls, package-main/Unicode workflows, and six builtin workflows passed in the current compiled lane. Worker schema/fingerprint regressions passed. Large public pdf.js completion and real Electron analysis remain unverified.
Track module writes and escapes at their owner, preserve capture and reassignment ordering, and share CommonJS/default namespace identity without erasing parent-slot changes. Carry write sites into ambient alias resolution and use parsed write targets across consumers. Deduplicate returned-reference work with cycle context; retain unchanged temporal selection identity so provenance memoization stays effective.
Reviewed fixes include #2041, #2465, #2830, #2881, and #2948. Remove superseded mutation representations and the ineffective per-markValue dedup layer.
Validation: 380 focused JavaScript tests passed under a 384 MiB heap cap, including the previously aborting 30-level/128-call alias regression. Six public CLI/MCP builtin tests passed. Exact pdf.js completed-workflow performance remains unmeasured.
* fix(javascript): exclude TypeScript this annotations from runtime parameters
* test(javascript): assert exact typed argument bindings
* test(apple): keep dyld slice regression portable
* fix(process): report no remaining time after a provider deadline fires
Node timers can fire while performance.now() is still a fraction of a
millisecond short of the monotonic deadline. ProviderStartupDeadline then
reported interruption "timeout" and an aborted signal while remainingMs()
returned ceil(0.x) = 1, so polling loops guarded by remainingMs() > 0
(Hopper and Ghidra startup) could run past an elapsed deadline, and the
real-timer test "aborts a bounded wait when its real monotonic deadline
expires" failed intermittently in CI (expected 1 to be 0).
Once the deadline's own timer has classified a timeout, report zero
remaining time. A deterministic regression test fires the timer with the
monotonic clock 0.4 ms short of the deadline.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* fix(ci): restore descriptor and fixture validation
* test(ci): retain verification coverage within lint limits
* fix(test): share admitted Ghidra profile installation fixtures
* fix(ci): isolate timing report fixtures from workflow state
---------
Co-authored-by: hhang <[email protected]>
Co-authored-by: Kaoru0822 <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: morluto <[email protected]>
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 <[email protected]>
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 <[email protected]>
* 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 <[email protected]>
---------
Co-authored-by: Claude Fable 5.1 <[email protected]>
* 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