Commit Graph

1698 Commits

Author SHA1 Message Date
Rohit Ghumare d005bd5dcd
fix(javascript): preserve CommonJS lookup and analysis provenance (#2306)
* fix(javascript): preserve CommonJS directory and ancestor lookup

* test(apple): bound cold archive fixture compilation

* test(release): scope preflight schema to selected jobs

* fix(javascript): retain requested analysis limits in Evidence

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-13 23:31:30 +08:00
Lucien 688defca0f
fix(comparison): recheck historical calls-only changes (#2223)
* fix(comparison): preserve incomplete function call evidence

Keep missing, unknown, partial and unresolved call relationships unknown in function comparisons and reconstruction claims. Aggregate IDA caller and callee coverage without overwriting uncertainty.

Validate with 144 focused tests, typecheck/lint, docs checks and test discovery. Real providers were not verified; the full headless IDA session suite requires unavailable Windows native controls.

* fix(comparison): recheck historical calls-only changes

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-13 23:30:31 +08:00
Lucien 3c39a3f536
test(adb): isolate cross-platform activity launch regressions (#2226)
* fix(adb): reject timed-out activity launches and retain observations

* test(adb): isolate cross-platform activity launch regressions

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-13 23:30:18 +08:00
Shubham Ahuja 3e7c630223
fix(mcp): count the error flag in error result budgets (#2848)
Error results reach the wire as text plus `isError: true`, but the
text-only envelope omitted the flag. An error up to 15 bytes above the
result budget passed both the delivery and transport checks and was sent
as the original diagnostic instead of taking the oversized-error recovery
path.

Rename the error representation to "error-text" and size its envelope
with the flag, so ToolResultDelivery and the error transport share the
complete delivered shape. Successful structured results are unchanged.

Fixes #2557

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 23:06:55 +08:00
Dragolone 94072364c7
fix(sqlite): keep triggers whose declaration spells the table in another case (#2807)
* fix(sqlite): keep triggers whose declaration spells the table in another case

SQLite stores a trigger's target in sqlite_schema.tbl_name exactly as
written in CREATE TRIGGER and resolves it by ASCII case folding, while an
index stores the table's own name. The selected_table scope filtered
tbl_name with COLLATE BINARY, so a trigger declared ON users for table
Users was omitted while the schema still reported complete. Match
dependents with COLLATE NOCASE, and report each trigger's table as the
stored table or view name so the selected-table contract still holds.

* fix(sqlite): refuse an inexact table before the case-folded schema scan

With the NOCASE expansion, a selection such as users for table Users
expanded the stored table's declarations before readRows reported the
missing exact name, so large trigger definitions could surface as an
output-limit failure instead of the selection error. Check the exact
table name against PRAGMA table_list first and share the selection
failure with readRows.

* fix(sqlite): fold dependent names only for a row-selectable table

An exact view, virtual or possible shadow table passed the exact-name
guard, so the NOCASE scan could still expand a differently cased trigger
past the reply budget before readRows refused the selection. Fold case
only when the selection is an ordinary table that is not a possible
shadow table, and keep the exact filter otherwise so every refused
selection fails as it did before the case-folding change.

* fix(sqlite): resolve trigger tables without folding unrelated names

The stored-name lookup case-folded every PRAGMA table_list name up front,
so a selected-table inspection of a tiny table paid for large unrelated
identifiers. A selected-table scan only returns the selected table's
dependents, so report the selected name directly; other scopes use an
exact stored name when one matches and fold the stored names once, only
when a trigger spells its target differently.

* perf(sqlite): fold each table name once when matching shadow parents

The extracted shadow-parent helper folded the table name inside the find
callback, once per unresolved virtual table, and the selected table was
checked both before and during the schema scan. Fold the name once per
call as before, and reuse the selected table's result in the scan.
2026-10-13 22:37:47 +08:00
xin zhuang e103a89889
fix(artifacts): preserve NIB key and class name identity (#2109)
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-13 22:36:06 +08:00
The one -Niu edd9939879
fix(browser): give the DevToolsActivePort wait one deadline owner (#2265)
* Single owner for the Chrome DevToolsActivePort startup deadline

Cold Chrome startup tolerance was spelled three ways for one wait: the helper
fell back to 15,000 ms, the runtime fixture lifecycle passed a literal 60,000,
and the real-browser verifier kept a local 60,000 constant. A per-caller literal
quietly changes how long a lane tolerates a cold browser before it fails, and
the failure reported only elapsed_ms, so a reader could not see which ceiling
was hit.

Export BROWSER_DEVTOOLS_STARTUP_TIMEOUT_MS as the owner, use it for the helper
fallback and both call sites, and report startup_timeout_ms in
BrowserStartupError. A source guard keeps callers from restating the number.

* Pin the DevToolsActivePort deadline guard to the startup call argument

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-13 22:35:45 +08:00
Vinícius Andrade 1e38a038c6
fix(process): release handles and close worker on incomplete cleanup (#2321)
* fix(process): unreference handles on incomplete provider process stop

Signed-off-by: Vinícius DS Andrade <95101505+viniciusdsandrade@users.noreply.github.com>

* fix(javascript): close worker and release handles on incomplete cleanup

Signed-off-by: Vinícius DS Andrade <95101505+viniciusdsandrade@users.noreply.github.com>

* fix(javascript): defer worker stdin close until incomplete cleanup

Signed-off-by: Vinícius DS Andrade <95101505+viniciusdsandrade@users.noreply.github.com>

* test(javascript): assert cleanup error instance on inspection uncertainty

Signed-off-by: Vinícius DS Andrade <95101505+viniciusdsandrade@users.noreply.github.com>

---------

Signed-off-by: Vinícius DS Andrade <95101505+viniciusdsandrade@users.noreply.github.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-13 22:34:54 +08:00
morluto 6e25cc3c76 fix(tests): clear lint and typecheck errors on main
Split two over-long test functions into module-level helpers
(max-lines-per-function): IdaSessionClient transport cases, IDA provider
composition, and function comparison identity cases keep their names and
assertions.

Also fix three typecheck errors: default omitted
direct_invokes_exhaustive to null so the result schema stays JsonValue
compatible, parse the ghidra dossier before spreading it, and delete the
optional beforeCall hook instead of assigning undefined under
exactOptionalPropertyTypes.
2026-10-13 22:32:01 +08:00
morluto 7369b5ee63
fix(ida): retain cleanup facts and let one-shot commands exit (#2814)
* fix(ida): let one-shot commands exit after retaining cleanup

When a headless IDA request outlives timeoutMs (for example idb_open on
a large binary still running auto-analysis), REA cannot prove the
worker stopped and correctly retains the upstream connection and
private workspace. The retained stdio child and its pipes stayed
referenced, so a one-shot CLI printed its cleanup_incomplete result and
then never exited, keeping the supervisor, worker and database alive.

Detach the retained connection's child process and pipes from the event
loop when cleanup fails. A long-lived MCP server can still retry
through the retained connection; a one-shot CLI exits with status 1,
and the supervisor observes end of input.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(ida): report an unverified upstream worker after failed cleanup

Upstream ida-pro-mcp spawns headless workers in their own session and
deliberately leaves them running when its supervisor exits, so neither
a retained connection nor REA exiting proves that a timed-out worker
stopped. When cleanup fails before the owned worker's release is
confirmed, the cleanup diagnostics now name its private session and
state that it may still be running until it finishes and reaches its
idle timeout. Failures after a confirmed release, or before any open
was attempted, do not report a worker.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(ida): name the inventory sessions that block worker release

When idb_close confirmed the requested worker gone but the follow-up
inventory still found a different peer on the private input, the
upstream_worker diagnostic named the released session and could
misdirect manual cleanup. Record the session ids of the inventory
entries that actually blocked release and report those; fall back to
the requested private session only when no inventory evidence exists
(an incomplete open or an unanswered request). The field becomes
session_ids, since more than one entry can block release.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(ida): keep blocker evidence and backend in cleanup diagnostics

The release diagnostic reset its observed blockers on every close, so a
retry whose inventory was unavailable fell back to the already-released
session; and it kept only session ids, describing a blocking GUI
session with detached-worker guidance.

Blocker evidence is now replaced only by a successful inventory, and
the diagnostic becomes upstream_sessions with each session's id and
backend, with guidance that distinguishes workers from GUI sessions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(ida): stop naming a worker after its close was confirmed

When idb_close confirmed the requested worker's release but the
following inventory failed, no blocker evidence existed yet and the
diagnostic fell back to the confirmed-absent worker. After a confirmed
close the diagnostic now reports an empty session list, meaning any
remaining same-input sessions are unknown.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(ida): group cleanup diagnostic cases in their own suite

The added cases pushed the reaped-worker describe block past the
150-line limit enforced by lint:built.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(ida): keep ownership and pre-close peers in cleanup diagnostics

Blocking sessions dropped the parsed ownership fact, so an external
unowned worker looked the same as REA's own; and recovery inventory
recorded same-input peers only when the requested worker was missing,
so a peer seen beside it was lost if the following close failed.

Each reported session now carries owned (null when no inventory has
reported it), and recovery records every same-input session until a
later successful inventory replaces that evidence.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(ida): drop a confirmed worker from retained cleanup blockers

Recovery inventory now records the requested worker beside any peers,
so once idb_close confirmed its release a failing follow-up inventory
still reported it as unreleased. Remove the confirmed session from the
retained blockers at close confirmation and keep the remaining peers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(ida): retry cleanup through a detached stdio connection

The retry coverage used a recording connection whose detach() only
counts calls, so it could not show that detaching keeps a retained
connection usable. Run a real stdio supervisor in a long-lived host,
fail the first post-close inventory, and require the retry through the
same detached connection to confirm release and remove the workspace.
The test fails if detach() destroys the pipes instead of unref-ing them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(ida): close the stdio supervisor in failed retry tests

Merge main and give its new IdaNativeProtocol connection double the
required detach() method. The real-stdio retry test now closes its
connection in an unconditional teardown, so a failing assertion cannot
leave the supervisor waiting on stdin.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(ida): share the cleanup diagnostic expectation in session tests

Repeated upstream_sessions assertions and the unrelated live peer
literal pushed repository duplication over the jscpd threshold. Build
the expected diagnostic with one helper and reuse one peer constant.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(ida): distinguish observed ownership from unreported input bindings

* fix(ida): keep requested-ID conflicts in recovery cleanup

Recovery inventory kept only same-input entries, unlike the startup and
post-close filters. After an explicitly rejected open, an entry under
the requested session ID on another input was dropped, so cleanup could
close the connection, remove the private workspace and report success
while that session stayed registered. Match the requested ID as well so
the entry is retained as a blocker and cleanup stays incomplete.

Also split the cleanup diagnostics suite under the lint:built function
length limit, and make two startup-inventory fixtures pass a defined
session id so the test file typechecks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(ida): preserve retained session inventory facts

---------

Co-authored-by: Xingchuan Ma <xingchuan.ma@msn.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-13 22:27:26 +08:00
Aimal Khan cbe769b504
docs: move translated READMEs under docs/readme (#2165)
Move all 18 translated READMEs into docs/readme/ and keep the English entry at the repository root. Update navigation, guide/image paths, website discovery and documentation checks together.

Preserve the contributor's work and current main content. Cover every translated command and HTML destination, and repair the verified Persian heading fragments.

Validation: 203 focused tests on the synchronized head, plus 119 tests and documentation checks on the integration with main fc0dbe7f9; 1,501 local references and 399 authored fragments verified. The complete CI workflow passes. The upstream x64 dylib fixture correction is included; an unchanged-checkout rerun cleared the earlier deadline timing assertion.

Closes #2141

Co-authored-by: Aimal Khan <94559553+aimalexe@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
2026-10-13 22:25:32 +08:00
Hifza Zafar 865c35e25a
fix(ghidra): disclose missing PDB symbol coverage (#2275)
* fix(ghidra): disclose missing PDB symbol coverage

* style: format reviewed source changes

* fix(ghidra): bound PDB handshake and retain coverage uncertainty

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
Co-authored-by: morluto <17176810+morluto@users.noreply.github.com>
2026-10-13 22:17:27 +08:00
Yann Roberto 1016c96e6b
fix(source-maps): accept omitted names during browser collection (#2831) 2026-10-13 22:17:09 +08:00
Avocado f0b8ae1fc8
fix(javascript): trace nested Electron bridge members (#2745)
* fix(javascript): trace nested Electron bridge members

* fix(javascript): preserve shallow Electron bridge paths

* fix(javascript): preserve exact Electron bridge member paths

* fix(javascript): preserve exact Electron bridge paths

* fix(javascript): preserve bridge entry ownership

* fix(javascript): preserve bridge path identity

* fix(javascript): normalize typed feature seeds before tracing

* test(javascript): normalize direct selector seed inputs

* refactor(javascript): consume normalized feature seed defaults

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-13 22:16:44 +08:00
LcokHcak c9982ad8bf
fix(browser): release scenario listeners and allow bounded Chrome close (#2441)
* fix(browser): release scenario event listeners on finish

* fix(browser): allow Chrome cleanup to complete within bounded deadline

* style(browser): format cleanup deadline regression

* test(browser): expect popup cleanup listener

---------

Co-authored-by: LcokHcak <268763621+LcokHcak@users.noreply.github.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-13 22:16:25 +08:00
Ysopwnable 21aa877e5a
fix(process): honor startup deadlines and add a CI audit skill (#2692)
* docs(skills): add CI and test correctness auditing

Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>

* 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 <noreply@anthropic.com>

* fix(process): retain the monotonic startup deadline budget

Recheck the absolute monotonic deadline when an early timer fires, and keep
polling waits pending until their own target or the shared deadline arrives.
Preserve caller cancellation, disposal and the unchanged real-timer assertion.
This replaces the earlier remainingMs workaround: an early callback must not
classify an unexpired deadline as a timeout.

Adapt the production fix and regression cases from nosmile99 PR #2793 at
546001693636f13700d86c6e93b6086abba2b7d6, including the independently reported
both-timers-early reproduction. Preserve the prior contributor's commit.

Fixes #2760

Co-authored-by: nosmile99 <147114285+nosmile99@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>

* style(tests): format the Java class fixture signature

The captured main baseline has an unformatted helper signature. Apply the
repository formatter so the required style gate can run to completion.

Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>

* test(ghidra): group expanded suites by their contracts

Split result-envelope and completeness checks, and Windows invocation and
runtime checks, into named describe groups within the existing lint limit.
Preserve every test, fixture, assertion and platform prerequisite.

Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@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>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: nosmile99 <147114285+nosmile99@users.noreply.github.com>
2026-10-13 22:15:43 +08:00
GuoJun Tang b17487f482
fix(comparison): keep unsupported function facets unknown (#2450)
* fix(comparison): keep unsupported function facets unknown

* docs(comparison): explain function facet availability

* fix(analysis): preserve unavailable facets across Evidence consumers

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-13 22:15:01 +08:00
GuoJun Tang 30e9b83a68
fix(ida): retain bounded stderr on upstream transport failures (#2449)
* fix(ida): retain bounded stderr on upstream transport failures

* fix(ida): preserve stderr through operation and cleanup boundaries

Address review findings at their producing boundaries and preserve directly affected consumers. Source inspection and git diff --check completed. Tests and automated checks were not run at the user’s explicit request.

* fix(ida): preserve cancellation and single-owner stderr diagnostics

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-13 22:14:39 +08:00
Quentin Limo e3a012d6c9
fix(flutter): reject ambiguous ELF mappings and bound note reads (#2334)
* fix(flutter): reject ambiguous mappings and bound ELF notes

Resolve PT_LOAD interpretations once for symbols and dynamic tables, including partial overlaps. Preserve equivalent mappings and leave conflicting or invalid alternate definitions unresolved.

Bound distinct nonempty ELF note ranges before retention and reads, deduplicate shared ranges, preserve observed build-ID candidates and report partial coverage on exhaustion. Correct shared verifier workspace ownership and structured Windows path assertions.

Addresses the two post-merge review findings on PR #1582. Validation: 147 focused cases across Linux, macOS Sonoma 14.8.9 and non-administrator Windows 11 build 26300.9457; real Gallery CLI/MCP checks on all three hosts; six compiler-produced ELF32/ELF64 hash-layout cases; static, docs, discovery and duplication checks. Full string-pool projections remain explicitly bounded.

* test(flutter): parse complete facts through named result schemas

---------

Co-authored-by: me <me@medz.org>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-13 22:13:22 +08:00
FeeHaard fd65e278be
fix(setup): resolve the configuration MSIX Claude Desktop reads (#2426)
* fix(setup): resolve the configuration MSIX Claude Desktop reads

On Windows, setup, doctor and uninstall always used
%APPDATA%\Claude\claude_desktop_config.json. The MSIX build of Claude
Desktop (package family Claude_pzs8sxrjxfjjc) virtualizes AppData writes
and reads its package-private copy under
%LOCALAPPDATA%\Packages\<family>\LocalCache\Roaming\Claude once it exists.
Setup from an ordinary process therefore wrote a file the app never reads,
and doctor reported that file healthy.

Resolve the Claude Desktop location once, in supportedClients(): the
private copy when it exists, else the AppData file the package still
reads, else a new private copy. An unrecognized Claude_* publisher or
unreadable package storage is reported instead of falling back to AppData.

Compare one of the package's private files with its AppData path through
realpath.native to learn whether the running package started this
process. From that redirected view, or when no file can be compared,
setup and uninstall refuse to change Claude Desktop's configuration,
because the running app rewrites it from memory. From a redirected view
they also refuse writes under %APPDATA% and %LOCALAPPDATA% for other
clients and skills, which would land in the package's private storage.

Setup refuses to register a launcher stored in any MSIX package's
private storage, discloses which file the package reads, and tells the
user to quit Claude Desktop fully on every platform. Configuration fails
with target_changed if the package switched to its private copy after
the plan was shown. Uninstall removes REA from both files.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(setup): record the verified MSIX Claude Desktop registration

On the Windows 11 host with the MSIX build 2.31226.1.0, setup from an
ordinary terminal with the app quit wrote the package-private copy. After
the app restarted, the entry persisted, doctor reported it aligned, and
Claude Desktop's MCP log showed REA starting and answering tools/list.
Uninstall against the real app remains unverified.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* style(setup): format MSIX review corrections

* fix(setup): carry the admitted legacy path through uninstall removal

clientRegistrationRemoval returned a removeLegacy boolean, and removeClient
recomputed the legacy path separately, so TypeScript could not prove the
path existed when removeLegacy was true and `tsc --noEmit` failed in
Uninstall.ts. The decision now returns the admitted legacy path itself;
preflight and removal consume that one value.

The alias regression matched new-destination children with a "/"
separator while building paths with path.join, so it failed on Windows.
It now uses path.sep.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(setup): split MSIX Claude Desktop lifecycle cases under the function length limit

The uninstall cases pushed the registration lifecycle describe past the 150-line lint limit. Group them separately, with the AppData registration case kept among the registration cases.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-13 22:04:22 +08:00
Kaoru0822 5996d8160f
fix(native): bound captured output carried by native command failures (#2764)
* fix(native): bound captured output carried by native command failures

The native command runner retains up to 64 MiB of output because
successful analysis needs it complete, and failureCapture copied all of
it into the failure. An inspect_plist whose plutil output exceeded the
budget therefore returned a 67 MB resource_constraint error whose
details.captured_output.stdout repeated the whole retained output.

Keep a 64 KiB UTF-8-safe excerpt per stream in failure diagnostics,
mark them truncated, and keep the observed stdout/stderr byte totals.
Successful captures are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(native): bound codesign failures and cover excerpt cuts

translateCodeSignExitFailure wrapped an accepted nonzero codesign capture
into a NativeCommandFailure by copying both complete streams, so
inspect_signature failures still bypassed the diagnostic bound. Route it
through the shared failureCapture builder; accepted output stays
complete until the provider decides it is a failure.

Add a focused runner test for an ordinary nonzero exit with stdout and
stderr just above the excerpt size and a two-byte character straddling
the cut, and a provider test for the codesign path.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(native): build excerpt test output inside the child process

The output strings embedded in one node -e argument totalled about 133
KB, above Linux's 128 KiB per-argument limit, so spawn failed with E2BIG
on the CI runner. Generate the repeated output in the child instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 07:03:19 -07:00
LcokHcak c938f97fb2
fix(android): clean Windows workspaces after owner termination (#2440)
* fix(android): clean Windows workspaces after owner termination

* fix(android): retain Windows workspace guardian on cleanup failure

* fix(android): preserve released guardian pipe state on cleanup retry

* fix(android): normalize extended local guardian parent paths

---------

Co-authored-by: LcokHcak <268763621+LcokHcak@users.noreply.github.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-13 22:03:16 +08:00
LcokHcak c45d912c91
feat(android): expose exact DEX descriptors and direct invoke sites (#2439)
* feat(android): expose precise method references and DEX invoke sites

* fix(android): bound invoke evidence without losing reference inventory

* perf(android): skip invoke admission for class references

---------

Co-authored-by: LcokHcak <268763621+LcokHcak@users.noreply.github.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-13 22:02:47 +08:00
Liu Jie 173da755cd
fix(reconstruction): reject contradictory function comparison status (#2798)
* fix(reconstruction): reject contradictory function comparison status

* test(reconstruction): cover imported function match precedence

---------

Co-authored-by: maxazure <405711+maxazure@users.noreply.github.com>
2026-10-13 22:01:41 +08:00
morluto 1eca600515
fix(apktool): resolve Windows PATH launchers before invocation (#2802)
* fix(apktool): resolve Windows PATH launchers before invocation

Resolve the default launcher through the selected PATH/PATHEXT before choosing native process creation or the existing conservative cmd.exe wrapper. Reuse the resulting selection and one canonical environment for the version probe and decode.

Follow-up to the release #1693 review of #1777. Source inspected and formatted; tests, builds, check reruns and real Windows Apktool execution were skipped at maintainer request.

* fix(apktool): bound lookup and retain only selected environment

Source inspection and targeted formatting only. Tests, builds, lint, typechecks and provider workloads were not run at the user's explicit request.

* fix(apktool): use supported timeout diagnostics

Retain lookup phase through AnalysisErrorOptions diagnostics while preserving the operation and timeout identity. Source inspection and targeted formatting only; tests, checks, builds and provider workloads were skipped at the user request.

---------

Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-13 22:00:47 +08:00
Kaoru0822 96d1f0f3fb
fix(cli): refuse scenario steps on passive native UI observation (#2712)
observe-native-ui and capture-native-ui-scenario were registered in one
loop with a shared option schema and description. The passive command
therefore advertised `--steps` ("Observe or run a scenario"), accepted
any value, and then dispatched observe_native_ui without it, so a
caller who selected the wrong command never learned that no scenario ran.

Register each command against its own contract. Observation declares
only the passive scope options, so `--steps` is rejected as an unknown
flag; the scenario command keeps its JSON step decoding and validation.
Each command now has its own description.

Fixes #2674

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 06:59:33 -07:00
vtx beca34f522
fix(ida): report missing tools when a compatibility profile mismatches (#2307)
A profile mismatch reached the caller as a bare AnalysisProtocolError,
which projects to `unreadable_output` with a generic message. The error
already named every missing tool, but none of that detail survived, so
the only way to identify the cause was to log the JSON-RPC traffic and
notice the exchange stopping after `tools/list`.

Throw a ProviderAdapterError instead, carrying the mode, the expected
profile and the missing tool names through the diagnostics channel that
already surfaces in `details`. Document which upstream versions each
profile accepts, since upstream `main` now serves neither.

Refs #2301

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-13 21:58:36 +08:00
morluto 48a683ac8c
feat(evm): inspect lossless Solidity terminal CBOR metadata (#2790)
feat(evm): retain lossless terminal CBOR metadata

Refs morluto/rea#2388

Co-authored-by: Matheus Breguêz <matbrgz@gmail.com>
Co-authored-by: Codex <noreply@openai.com>
2026-10-13 21:55:30 +08:00
Kaoru0822 46f51ee6cc
fix(flutter): name a missing or non-file APK selection (#2727)
* fix(flutter): name a missing or non-file APK selection

identify_flutter_build and inspect_dart_aot reported a missing path or a
directory as "The APK could not be read as a package: <path>: ENOENT ...",
which blames the package bytes for a selection mistake. Report
"Selected APK does not exist" for ENOENT/ENOTDIR and "Selected APK is not
a regular file" for a non-regular selection, matching the SQLite
inspector's wording. The issue path and invalid_format reason are
unchanged; package format failures keep their existing message.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(filesystem): classify unopenable non-regular selections at admission

A Unix socket cannot be opened at all: open() fails with ENXIO on Linux
and EOPNOTSUPP on macOS (surfaced by libuv as "Unknown system error
-102") before openRegularFile can stat the descriptor, so such a
selection escaped NonRegularFileReadError and the Flutter provider still
blamed the package bytes.

When open fails, classify the path by its own metadata (lstat when
symlinks are rejected, stat otherwise): an existing non-regular file
becomes NonRegularFileReadError. Missing paths, permission failures,
regular files, and the O_NOFOLLOW ELOOP rejection keep their original
errors. The Flutter selection test now covers a real Unix socket.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(filesystem): reclassify only unopenable file-type errors at admission

Checking the path's metadata after any open failure turned EACCES on an
unreadable directory into NonRegularFileReadError, so callers reported
invalid input instead of access_denied. Reclassify only errors that mean
the file type cannot be opened (ENXIO, EOPNOTSUPP, ENOTSUP, matched by
errno because libuv has no name for macOS EOPNOTSUPP 102); permission,
symlink-rejection and resource failures keep their original errors.

Run the Unix socket selection check in its own test, skipped on Windows
where listen() takes named pipes, and keep the missing-path and
directory checks cross-platform.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(filesystem): keep cancellation that arrives during the non-regular probe

A caller abort while the post-open metadata probe ran was replaced by
NonRegularFileReadError, so callers such as parseBinaryTarget reported an
input-format error instead of cancellation. Recheck the signal before
substituting the non-regular classification.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 21:49:23 +08:00
yasshmittal 4c79127fcb
fix(sqlite): classify a missing database path as an invalid value (#2775)
* fix(sqlite): classify a missing database path as an invalid value

The snapshot reported an absent selected database as an artifact path
failure, which the adapter projects as invalid_format alongside malformed
paths and content. The snapshot owns the absence observation, so it now
returns an invalid_value input issue on path directly, matching the
adapter's existing ENOENT/ENOTDIR classification.

Fixes #2614

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(sqlite): classify a missing database path as an invalid value

The snapshot reported an absent selected database as an artifact path
failure, which the adapter projects as invalid_format alongside malformed
paths and content. The snapshot owns the absence observation, so it now
returns an invalid_value input issue on path directly, matching the
adapter's existing ENOENT/ENOTDIR classification.

Fixes #2614

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-13 21:48:39 +08:00
jbernous fc0dbe7f9d
fix(server): mark retained partial-observation errors as target content (#2398)
Pass the tool contract's `returnsTargetContent` to
`toRecordedPartialErrorToolResult` in the shared Evidence handler, matching
the Electron call site.

The call site that records a retained partial observation was added without
the argument required by the untrusted target-content framing, so the
delivery neither marked the result nor counted the provenance marker in its
wire budget. The type gate failed on main with
`contractToolHandler.ts(69,38): error TS2554`, which also blocked every
compiled boundary test lane.
2026-10-13 21:46:14 +08:00
Yann Roberto 5d12a0b4b6
test(web): cover nullable HTTP captures through CDP and CLI (#1834)
* fix(browser): preserve unknown HTTP response comparison fields

* fix(browser): retain proven request inventory changes

* fix(javascript): preserve Electron identity and avoid quadratic property scans

Share visible Electron mutations with wrapper expansion, index static object
literal properties once, and align MCP assertions with current contracts.

* fix(javascript): track writes through symbolic Electron aliases

Resolve mutation targets through the same factories, module tables, containers,
and conditional origins as call analysis. Share mutation coverage between
direct and wrapper scans while isolating origin caches and preserving exact
property paths, local rebinding semantics, and analysis resource limits.

* fix(javascript): preserve container slots and imported mutation origins

* perf(javascript): defer container mutation replay until property reads

* fix(javascript): preserve captured object identities and write order

* fix(javascript): preserve ordered mutation origins

* fix(javascript): honor property mutation constraints

* test(web): narrow PR to HTTP and CLI comparison regressions

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-13 21:44:08 +08:00
Ysopwnable 9958754f6c
fix(process): preserve discovery ownership across cleanup retries (#2643)
Bind retained descriptors and runtime resources to their admitting operation until cleanup succeeds, then rebind newly admitted work. Verify failed retries, successful recovery, shutdown and CLI projection.

Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-13 13:43:06 +00:00
BaaRai a4b8e9ccee
feat(ghidra): admit recordless legacy MIPS32 ELFs with a pinned 32-bit language (#1898)
* feat(ghidra): admit recordless legacy MIPS32 ELFs with a pinned 32-bit language

Firmware built with pre-ABI-flags GNU toolchains declares EF_MIPS_ARCH_32
with an unspecified ABI field and no PT_MIPS_ABIFLAGS record. The lane
refused them before provider selection, and Ghidra's own header
auto-selection picks a 64-bit R6 language for exactly these files.

Admit ELF32 ET_EXEC headers with EF_MIPS_ARCH_32 or EF_MIPS_ARCH_32R2,
an unspecified ABI field, EF_MIPS_ABI2 clear and no observed ABI flags
record. o32 is recorded as an inferred analysis assumption
(mips_abi_basis), floating-point ABI semantics stay unverified, and the
existing refusals (FP64, NAN2008, ASEs, machine variants, ELF64) are
unchanged. The profile pins -processor MIPS:<LE|BE>:32:default through a
provider-pinned-v1 selection the bridge-reported language_id is checked
against after import; a caller-selected REA_GHIDRA_LANGUAGE_ID still
wins. The lane identity is versioned
elf32-exec-arch32-legacy-pinned-v1.

verify:ghidra:mips gains a recordless legacy round for both byte orders
that strips the ABI record declarations from a real mips32 fixture,
checks REA's interpretation against GNU readelf, asserts the pinned
language after import and the retained assumption limitations through a
snapshot round-trip.

Fixes #1620

* fix(ghidra): require an inspected absence for the recordless MIPS lane

Address review: undefined ABI flags means the record was not inspected,
not that none exists. Only an inspected absence (null) establishes the
recordless legacy admission; a merely unobserved record keeps its
specific refusal. Also document the legacy admission and its pinned
language in the MIPS provider guide.

* fix(ghidra): tighten the recordless MIPS admission boundaries

Address review: a recordless-looking header whose ABI-record inspection
left declaration sources unexamined (carved ELF with a partial section
table and no program-header record) no longer establishes the recordless
admission; it is refused with the inspection limitation retained. An
EF_MIPS_ARCH_32 header that declares an ABI is refused rather than
relabeled through the 32R2 declared-ABI lane.

* fix(ghidra): reject EF_MIPS_ABI_ON32 from the recordless MIPS lane

Address review: bit 0x40 declares the old n32 ABI. A recordless header
carrying it was admitted with the inferred-o32 assumption even though
the header itself declares n32; the recordless shape now requires the
bit clear and refuses it with a specific constraint.

* fix(ghidra): keep recordless relocatable MIPS objects off the legacy lane

The recordless admission now requires ET_EXEC: the lane and its
verification cover executable firmware images, and a recordless ET_REL
object must stay on the declared-ABI path instead of inheriting the
inferred-o32 assumption under an executable lane id. The ABI-record
requirement paragraph is scoped to the declared-ABI lane so it no longer
contradicts the recordless admission documented above it.

* fix(ghidra): name the ET_EXEC scope for recordless objects and probe the legacy lane

A recordless relocatable object is not an incomplete inspection, so its
refusal now names the ET_EXEC scope of the legacy admission instead of
claiming unavailable ABI headers remain unknown. The recordless legacy
verifier round reads the probe pair and applies the full assertMipsProbe
oracle like the standard round, and its report keeps the independent
GNU readelf receipt beside the fixture facts.

* fix(ghidra): retain the concrete ELF32 legacy compiler pin

* fix(ghidra): bind legacy profiles to fully admitted targets

---------

Co-authored-by: BaaRai <baarai@users.noreply.github.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-13 21:42:38 +08:00
Lluís Ariño c6503edfc4
ci: pin GitHub Actions to full commit SHAs (#1901)
* ci: pin GitHub Actions to full commit SHAs

Replace every third-party `uses: owner/repo@vN` reference in
.github/workflows with the 40-character commit SHA that the tag
currently resolves to, keeping the exact release as a trailing comment.
Each pin was checked with `git ls-remote --tags`: the floating major tag
and the commented release dereference to the same commit. Local
reusable workflows are unchanged.

Re-pin reactivecircus/android-emulator-runner from the SHA of the
annotated `v2` tag object (4c44018e) to the commit it points to
(a421e438, v2.38.0); Actions resolves both, but only the commit SHA is
an immutable reference that tooling can compare with the release.

Update the Windows Ghidra workflow trust-boundary test to require
SHA-pinned setup-node and upload-artifact references instead of the
previous floating tags.

Validation: actionlint v1.7.7 (-shellcheck= -pyflakes=, as in CI), YAML
parse of all workflows, no remaining unpinned third-party `uses:`, and
the workflow boundary/conformance tests.

* style(ci): format action identity assertion

Retain formatting edits produced before the user stopped validation.

Source inspection and git diff --check only. Tests, builds and typechecks skipped by explicit user request. GitHub review writes paused globally.

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-13 21:38:46 +08:00
Max 5dd2ce3125
fix(ida): let one-shot commands exit after retaining cleanup (#1841)
* fix(ida): let one-shot commands exit after retaining cleanup

When a headless IDA request outlives timeoutMs (for example idb_open on
a large binary still running auto-analysis), REA cannot prove the
worker stopped and correctly retains the upstream connection and
private workspace. The retained stdio child and its pipes stayed
referenced, so a one-shot CLI printed its cleanup_incomplete result and
then never exited, keeping the supervisor, worker and database alive.

Detach the retained connection's child process and pipes from the event
loop when cleanup fails. A long-lived MCP server can still retry
through the retained connection; a one-shot CLI exits with status 1,
and the supervisor observes end of input.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(ida): report an unverified upstream worker after failed cleanup

Upstream ida-pro-mcp spawns headless workers in their own session and
deliberately leaves them running when its supervisor exits, so neither
a retained connection nor REA exiting proves that a timed-out worker
stopped. When cleanup fails before the owned worker's release is
confirmed, the cleanup diagnostics now name its private session and
state that it may still be running until it finishes and reaches its
idle timeout. Failures after a confirmed release, or before any open
was attempted, do not report a worker.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(ida): name the inventory sessions that block worker release

When idb_close confirmed the requested worker gone but the follow-up
inventory still found a different peer on the private input, the
upstream_worker diagnostic named the released session and could
misdirect manual cleanup. Record the session ids of the inventory
entries that actually blocked release and report those; fall back to
the requested private session only when no inventory evidence exists
(an incomplete open or an unanswered request). The field becomes
session_ids, since more than one entry can block release.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(ida): keep blocker evidence and backend in cleanup diagnostics

The release diagnostic reset its observed blockers on every close, so a
retry whose inventory was unavailable fell back to the already-released
session; and it kept only session ids, describing a blocking GUI
session with detached-worker guidance.

Blocker evidence is now replaced only by a successful inventory, and
the diagnostic becomes upstream_sessions with each session's id and
backend, with guidance that distinguishes workers from GUI sessions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(ida): stop naming a worker after its close was confirmed

When idb_close confirmed the requested worker's release but the
following inventory failed, no blocker evidence existed yet and the
diagnostic fell back to the confirmed-absent worker. After a confirmed
close the diagnostic now reports an empty session list, meaning any
remaining same-input sessions are unknown.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(ida): group cleanup diagnostic cases in their own suite

The added cases pushed the reaped-worker describe block past the
150-line limit enforced by lint:built.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(ida): keep ownership and pre-close peers in cleanup diagnostics

Blocking sessions dropped the parsed ownership fact, so an external
unowned worker looked the same as REA's own; and recovery inventory
recorded same-input peers only when the requested worker was missing,
so a peer seen beside it was lost if the following close failed.

Each reported session now carries owned (null when no inventory has
reported it), and recovery records every same-input session until a
later successful inventory replaces that evidence.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(ida): drop a confirmed worker from retained cleanup blockers

Recovery inventory now records the requested worker beside any peers,
so once idb_close confirmed its release a failing follow-up inventory
still reported it as unreleased. Remove the confirmed session from the
retained blockers at close confirmation and keep the remaining peers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(ida): retry cleanup through a detached stdio connection

The retry coverage used a recording connection whose detach() only
counts calls, so it could not show that detaching keeps a retained
connection usable. Run a real stdio supervisor in a long-lived host,
fail the first post-close inventory, and require the retry through the
same detached connection to confirm release and remove the workspace.
The test fails if detach() destroys the pipes instead of unref-ing them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(ida): close the stdio supervisor in failed retry tests

Merge main and give its new IdaNativeProtocol connection double the
required detach() method. The real-stdio retry test now closes its
connection in an unconditional teardown, so a failing assertion cannot
leave the supervisor waiting on stdin.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(ida): share the cleanup diagnostic expectation in session tests

Repeated upstream_sessions assertions and the unrelated live peer
literal pushed repository duplication over the jscpd threshold. Build
the expected diagnostic with one helper and reuse one peer constant.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(ida): distinguish observed ownership from unreported input bindings

* fix(ida): keep requested-ID conflicts in recovery cleanup

Recovery inventory kept only same-input entries, unlike the startup and
post-close filters. After an explicitly rejected open, an entry under
the requested session ID on another input was dropped, so cleanup could
close the connection, remove the private workspace and report success
while that session stayed registered. Match the requested ID as well so
the entry is retained as a blocker and cleanup stays incomplete.

Also split the cleanup diagnostics suite under the lint:built function
length limit, and make two startup-inventory fixtures pass a defined
session id so the test file typechecks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Xingchuan Ma <xingchuan.ma@msn.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-13 21:36:52 +08:00
Danish Rafie Ekaputra 9e019ad27d
feat(clients): register Factory Droid during setup (#2309) 2026-10-13 21:34:38 +08:00
Saim Shafique 6637161e02
fix(ghidra): warn when callee/caller reads stop at a truncated function body (#2360)
procedure_callees and procedure_callers returned a bare address list, so an
inferred no-return call that truncates Ghidra's function body silently dropped
real edges (fixes #2326). Wrap both views in the function-observation envelope
with noReturnCallLimitations, matching procedure_info, procedure_assembly,
procedure_pseudo_code, read_function_instructions, and analyze_function
(precedent: 69a8b3a95). Version the boundary-observation contract to
ghidra-terminal-call-limitations-v2 so older snapshots cannot replay
unqualified results.

Validation: red->green unit test for the envelope requirement, MCP boundary
evidence test extended for both views (limitations retained through Evidence
and snapshot replay), 8 harness test files + ghidra behavior tests green,
check:fast, docs:check, verify:test-discovery green. Real Ghidra host lane
unavailable here (no Ghidra installed); Java change mirrors the existing
procedureInfo call pattern.
2026-10-13 21:26:57 +08:00
To3akaRin dea770d5d9
fix(javascript): retain getter receivers through local aliases (#2778)
* fix(javascript): retain getter receivers through local aliases

* fix(javascript): resolve projected private getter receivers

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-13 21:26:13 +08:00
Joshwong1908 48b92e1be1
fix(go): classify JVM class files instead of universal Mach-O for CAFEBABE bytes (#2458)
* test(go): pin JVM class files as unsupported Go images

The regression fails on main: readGoBinaryImage(javaClassFile()) reports
"Universal/fat Mach-O containers require selecting a thin slice" for a
JVM class file whose bytes 4..7 are minor/major version, not nfat_arch.

* fix(go): classify JVM class files instead of universal Mach-O

Route the four FAT magics through the shared readFatContainerHeader and
classifyFatContainerIdentity facts added for the same disambiguation in
the artifact and target lanes (921bb9575). Keep the thin-slice failure
only when the container identity is confirmed Mach-O; a JVM class file
now falls through to the generic only-ELF/PE/thin-Mach-O failure.

* test(go): pin universal Mach-O thin-slice failure with FAT fixtures

Cover the kept behavior with the repository's own fatImage/machoImage
builders (narrow and FAT64 tables) so the regression also proves real
universal containers keep the slice-selection failure.

* test(go): cover little-endian FAT magics in the universal container control

* fix(go): require positive universal Mach-O identity

Require positive Mach-O identity before reporting a universal thin-slice remedy; malformed FAT-shaped bytes are not proof. Add the JVM constant-pool CPU lookalike to the existing fixture control.

Source inspection and git diff --check; tests/builds/typechecks/CI reruns skipped at explicit user request.

* fix(go): retain malformed FAT header diagnostics

Preserve the owning FAT header parser reason for malformed headers while requiring positive Mach-O proof before the universal-slice remedy.

Source inspection and git diff --check only. Tests, builds and typechecks skipped by explicit user request. GitHub review writes paused globally.

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-13 21:25:32 +08:00
Luis 003707f712
fix(verification): align Linux Hopper setup lane with current contracts (#1942)
* fix(verification): align Linux Hopper setup lane with current contracts

* fix(verification): retain orphan checks on clean Linux runners

* fix(verification): detect Hopper through alternate launcher paths

* fix(verification): report identified Hopper leaks before proc errors

* fix(verification): distinguish Hopper string recognition from byte fidelity

* fix(verification): report full literal decoding coverage explicitly

* test(verification): require a clean host before orphan checks

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-13 21:24:40 +08:00
Jin dd4bfed614
fix(javascript): keep ASAR-named files without an ASAR header opaque (#2347)
Inventory expands an ASAR-named filesystem file only when its bytes are
an ASAR. JavaScript reconstruction expanded it on the suffix alone, so
a directory holding any other file named *.asar failed the whole
analysis with an invalid ASAR header.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-13 21:23:58 +08:00
xingzhou 84ec40f1af
fix(browser): distinguish SVG links from HTML XLink attributes (#2480)
* fix(browser): respect SVG desc and title HTML integration points

* fix(browser): preserve moved SVG XLink destinations

* fix(browser): bound concurrent SVG identity reads
2026-10-13 21:23:33 +08:00
Mason 5eb296649d
fix(native): refuse inspect_signature on non-Mach-O targets (#2262)
* fix(native): refuse inspect_signature on non-Mach-O targets

This provider's signature inspection covers Mach-O code signatures only.
On a xar pkg, codesign's "code object is not signed" verdict cannot see
the archive-level signature layer, so a signed or invalidly-signed package
was reported as signed:false with "Artifact is not signed." Match the
existing inspect_macho/list_architectures gate and report
capability_unavailable instead of an unsigned claim for a layer that was
never evaluated.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test(native): scope the signature-gate comment to this provider

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(native): align signature capability discovery with Mach-O support

Bind inspect_signature availability to Mach-O targets in capability discovery and align the public tool description.

Source inspection and git diff --check; tests/builds/typechecks/CI reruns skipped at explicit user request.

---------

Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-13 21:22:42 +08:00
吴佳浩Alben cae7620b77
fix(apple): report a recognized connector that cannot name its owner (#2484)
* fix(apple): report a connector that cannot name its owner as an omission

A connector is recognized by class name and then dropped by an early
`continue` when its owner cannot be resolved. Nothing recorded the drop, so
connection coverage derived `complete` with `examined: 0` and `omitted: 0`
for a connector that was present, recognized and discarded.

Both producers of that coverage contract are affected and are changed
together, because they share the facet and the reason value:

- the keyed-archive parser records the drop as `unresolvedConnections` and
  reports it through the `connections:<path>` facet, the document
  `connection_count` and the graph omission total;
- the NIBArchive projection in the artifact adapter recorded nothing at all,
  and the projected dictionary carried no trace of the dropped connector for
  a downstream consumer to find. Its count is taken where the connector is
  discarded and plumbed through the same per-document omission channel that
  already carries incomplete hierarchies, so the reason follows the cause.

An unresolved source cannot be represented as a connection at all, because
connection identity requires a non-empty source; that is unlike an unresolved
destination, which the graph already retains as an unresolved edge.
`connection_limit_reached` stays reserved for connections dropped by the hard
cap and `serialized_view_hierarchy_incomplete` for hierarchy omissions.

`connection_count` also includes the unresolved connectors. That field already
counts connectors the parser recognized but could not emit, because
connections dropped by the hard cap are counted there too, so unresolved
connectors follow the existing rule rather than a new one.

Verified with 98 focused Interface Builder and catalog tests, check:fast and
verify:test-discovery on macOS arm64, and through the public CLI: a rooted
archive holding one ownerless UIRuntimeOutletConnection reported complete with
examined 0 and omitted 0 before this change and reports partial with the reason
connection_unresolved and omitted 1 after it.

* fix(apple): count ownerless NIBArchive connectors and keep the limit reason

Greptile found two defects in the NIBArchive half of this change.

The document summary was left unchanged, so the same recognized connector
counted as one in a keyed archive and zero in a NIBArchive. The dictionary
parser only sees connectors that were projected, so the omission recorded
where the connector was dropped is added to the matching document here.

The facet reason was overwritten unconditionally, so a NIBArchive holding both
a connection dropped by the limit and an ownerless connector reported
connection_unresolved and lost the cause a higher limit could recover. The
existing reason is kept when the graph already named one, which is the
precedence the keyed-archive producer applies.

Verified with `npm run test:focused` over the bundle suite (42 passed, 1
skipped), `npm run lint` (0 errors) and `npm run check:fast` on macOS arm64.
Reverting the reason precedence alone fails only the limit case; reverting the
document count fails the count assertion in both cases.

The new case moved into its own describe block because the enclosing callback
crossed the repository's max-lines-per-function bound otherwise.

---------

Co-authored-by: 吴佳浩 <wujiahao@supremind.com>
2026-10-13 21:19:17 +08:00
The one -Niu c44d17fd3c
fix(pwntools): let callers widen the artifact input bound (#2486)
* fix(pwntools): let callers widen the artifact input bound

The pwntools adapters rejected every artifact over 32 MiB before any
analysis ran, and nothing in configuration, environment, CLI or MCP
could raise that bound, so real recorded core dumps stayed unanalyzable.

Resolve the bound from REA_PWNTOOLS_MAX_INPUT_BYTES in front of the
shipped default. An absent value keeps 32 MiB, and a value outside
1..1073741824 bytes is refused as unusable provider configuration before
the artifact is read instead of falling back silently.

* fix(pwntools): name the bound variable in its own refusal

An unusable REA_PWNTOOLS_MAX_INPUT_BYTES travelled through the shared
engine-absence helper, which always stamped configuration_key
REA_PWNTOOLS_PYTHON, so a caller following that field was pointed at the
Python executable instead of the bound it had just set. The guide also
described the refusal as an invalid request while the decoder reports
provider_unavailable.

Let the failure context carry the key under review and pass the bound's
own name at that call site, then state the code callers actually receive
in the guide. Assert the key on the projected rejection so the engine
default and the bound override each stay attributed to the right setting.

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-13 21:18:12 +08:00
FengCi 59d33a2733
fix(native): keep lipo path echoes out of FAT records (#2605)
* fix(native): keep lipo path echoes out of FAT records

Parse FAT records only after separating the exact echoed operand path. Pass the same lipo operand at all three consumers and cover multiline paths through parser, slice-reader and compiled CLI regressions.

* fix(native): use parsed lipo framing for container offsets

* test(native): use explicit FAT fixtures for CLI regressions
2026-10-13 21:16:49 +08:00
xin zhuang ece15ed6a1
fix(electron): identify each unresolved scenario path (#2279)
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-13 21:15:33 +08:00
记得吃中饭 9c14999efd
feat(ghidra): support raw NMOS 6502 analysis (#2079)
* feat(ghidra): admit raw NMOS 6502 analysis

* test(ghidra): require verified POSIX verifier cleanup

* test(ghidra): verify 6502 low-memory raw imports

* docs(skill): document raw NMOS 6502 support

* fix(ghidra): preserve requested Windows raw source paths

* docs(ghidra): include raw 6502 in Windows installation scope

* test(ghidra): verify Windows raw junction rejection through CLI and MCP

* fix(validation): make fixtures portable and preserve explicit Codex home

* fix(ghidra): attest raw mapping state and address space

* fix(ghidra): align diagnostics and regression groups

* fix(ghidra): bind raw attestation to language address space

* chore(ghidra): avoid verifier insertion conflict

* docs(ghidra): align linked raw admission guides

* fix(ghidra): retain 6502 verifier workspace on failure

* test(ghidra): isolate Windows authority doctor fixture

* fix(binary): re-admit Windows raw paths on session reopen

* test(binary): require fresh provider execution after path change

* Constrain 6502 to raw lifecycle and snapshot targets

* Bypass saved reads for unadmitted Windows paths

* Guard direct CLI snapshot replay on Windows paths

* fix(snapshot): gate Windows Ghidra replay on native admission

* fix(snapshot): constrain nested 6502 subjects to raw images

* test: make dyld slice fixtures portable
2026-10-13 21:13:01 +08:00
Aravind Rao 352c46aa75
fix(javascript): keep CommonJS require file URLs unresolved (#2077)
* fix(javascript): keep CommonJS require file URLs unresolved

require("file:///dep.cjs") was reported as a resolved dependency of
the inventoried dep.cjs although Node rejects the string with
MODULE_NOT_FOUND. The shared module-specifier resolver decoded file URLs
before the declared CommonJS loader semantics.

File-URL decoding now applies only to non-require module specifiers, so a
CommonJS file URL reports external with its declared string and source
evidence preserved. ESM file URLs and ordinary relative require paths
keep their established lookup.

* test(javascript): consolidate CommonJS file URL public workflow coverage

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-13 21:12:50 +08:00