Commit Graph
1395 Commits
Author SHA1 Message Date
Kaoru0822andClaude Opus 5.5 8a8efb8226 fix(javascript): keep unselected sources out of cancellation failures
With source_paths, the analysis loop checked cancellation before it
recognized an outside-analysis-scope file. Cancellation arriving after the
last selected source therefore recorded the next unselected file as a
cancelled analysis failure, and the completion loop skipped it as already
analyzed.

Give out-of-selection classification one owner, used by the loop, the
interruption handler and the completion loop. The cancellation is still
reported as the interruption.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 21:36:10 +00:00
9eee709f0c fix(wasm): accept unpadded WABT section rows (#1963)
* fix(wasm): accept unpadded WABT section rows

WABT 1.0.42 right-aligns section names in a nine-column field. DataCount
fills that field, so its objdump row has no leading whitespace. Accept
that legal row. Header recognition, the required field shape, and section
range checks still reject malformed output.

Fixes #1956

* fix(ci): refresh MIPS expectations and Windows test paths

Assert admitted soft-float ABI metadata and its committed storage policy through the public target resolver, retain FP64 rejection, and point the curated Windows lane at the moved filesystem reconstruction tests.

Validation: reproduced all four prior failures; 97 focused tests and check:ci pass. Native Windows and real Ghidra execution were not performed locally.

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-12 05:29:04 +08:00
morluto beb80a07ba test(cli): consolidate schema coverage and assert input refusals
Remove 30 redundant truthy-JSON schema checks. Validate advertised groups and property parity across every primary command, retain required-field checks, and assert structured malformed-input errors. Exercise JEB positional validation rather than an unknown flag.

Validation: 13 public CLI adapter tests, combined checks, and temporary-directory hygiene. Host configuration refusal coverage from main is preserved.
2026-10-12 05:24:33 +08:00
morluto 108b5f9425 fix(native): reject ambiguous otool load-command framing
Validate Mach command counts, byte totals, scalar uniqueness, section counts, and build-tool counts before claiming exhaustive evidence. Preserve raw output in typed parsing failures and distinguish dylib commands from the dynamic loader. Correct inconsistent handcrafted fixtures and label their provenance.

Validation: 38 native tests, combined checks, and temporary-directory hygiene. Multiline dylib-name ambiguity was reproduced with the host Apple otool; regression workflows use captured output and injected command runners.
2026-10-12 05:24:29 +08:00
morluto a8d4984404 fix(browser): preserve uncertainty in malformed network observations
Require observed request method and initiator metadata instead of inventing defaults. Preserve valid redirect history while excluding later events for malformed reused IDs. Keep unavailable or invalid encoded lengths unknown and retain valid zero values.

Validation: 57 CDP boundary tests plus temporary-directory hygiene and combined checks. Protocol events come from the fake CDP server; no live browser verification is claimed.
2026-10-12 05:24:24 +08:00
morluto c002b89e2d fix(snapshot): bind replayed subjects to the selected target path
Rebind display paths only for matching artifact identities in primitive and composed replay. Preserve semantic Evidence IDs, payloads, and historical snapshot provenance. Classify snapshot filesystem workflows as boundary tests.

Validation: cache, direct workflow, MCP replay, and Evidence tests; combined checks and temporary-directory hygiene. Provider interactions are simulated for replay verification.
2026-10-12 05:24:20 +08:00
morluto 2260887f20 fix(artifacts): close mounted directory resources before DMG detach
Wait for directory operations, close owned streams and traversal handles, and retain the mounted reader when cleanup fails so close can retry before detach. Consolidate stable-artifact filesystem regressions into the boundary suite.

Validation: 35 artifact tests and temporary-directory hygiene, including real hdiutil diagnostics. Directory-close and traversal races use injected faults.
2026-10-12 05:24:15 +08:00
morluto c2407689cb fix(setup): preserve skill files and report rollback failures
Track attempted writes, preserve original content and modes from one regular-file observation, and continue rollback after individual failures. Return tagged failure details and retained backup paths through setup.

Validation: setup filesystem and recovery tests, combined compile/typecheck/lint/format/metadata/architecture checks. Filesystem fault injection covers backup, ambiguous publication, and rollback failures.
2026-10-12 05:24:10 +08:00
39418ea173 fix(adb): share host configuration refusals with apktool (#1954)
The ADB provider, which the apktool provider mirrors, had the same two
defects: a relative REA_ADB_PATH escaped as UNKNOWN because selection
ran before the try that maps configuration failures, and a missing adb
binary projected generic target advice instead of its reason.

Move the configuration-failure-to-refusal mapping into one
providerConfigurationRefusal helper used by both providers, resolve the
ADB selection inside the mapped try, and share the CLI refusal assertion.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-12 05:09:13 +08:00
morluto eb97da3388 fix(artifacts): retain ASAR resources through cleanup failures
Give snapshot capture, header admission, packed members, and container streams one file-handle owner. Serialize adoption with reader shutdown, retain failed closes for retry, and remove snapshots only after descriptor cleanup succeeds.

Cover unread members, pending opens, zero-byte members, and paired format/cleanup failures. Keep intentionally unrecoverable test fixtures hygienic and strengthen managed identity and process cleanup-authority expectations.

Validation: full npm run check; 99 targeted tests and temporary-directory hygiene; exact discovery of 877 test files. No real vendor-provider verification was performed.
2026-10-12 05:05:21 +08:00
290d301ec7 feat(ghidra): admit relocatable MIPS32r2 ELF objects (#1950)
* feat(ghidra): admit soft-float MIPS32r2 ELF with integer-register float storage

Soft-float o32 executables (Linux kernel builds, bare-metal firmware) were
refused because their ABI flags record declares no CPR1 and FP ABI 3.
Ghidra's MIPS32 compiler specifications model only hard-float o32, so typed
float/double signatures (DWARF) would be bound to $f12/$f14/$f0 and the
decompiler loses the real dataflow: `return sel ? a : b` decompiled to
`return in_f0;`, and callers passed phantom FPU inputs.

Admit ELF32 ET_EXEC o32 MIPS32r2 targets whose ABI record declares soft-float
with no CPR1, and commit `mips_soft_float_storage: o32-integer-registers-v1`
in their analysis profile only (hard-float profile digests are unchanged).
ReaGhidraMipsSoftFloat.java runs after auto-analysis and, for each function
with a float/double formal type, either keeps the types with the storage
Ghidra's o32 model assigns to a same-size integer (pair alignment, stack
spill), or, for auto-parameters such as hidden struct-return pointers, swaps
float types for same-size integers under dynamic storage. No function is left
on hard-float storage. The report is written last; the provider client
requires it exactly when the profile commits the policy and refuses the
session before any operation otherwise.

Verification: real Ghidra 12.1.4 lane (verify:ghidra:mips) now builds
hard- and soft-float fixtures in both byte orders and checks exact
parameter/return storage through inspect_native_api, caller constants,
snapshot profile and Evidence outcome; test:fast, verify:package and an
installed-tarball soft-float run pass.

* fix(ghidra): model soft-float MIPS as a prototype for every typed callable

Review feedback on #1949: rewriting storage per Function left external
functions and indirect calls through typed function pointers on Ghidra's
hard-float o32 prototype, which still read $f12/$f14/$f0 while the session
reported success. A negative control confirms it: without the change,
`(*rea_mips_soft_callback)(8.5f, 9.5f, sel)` decompiles to
`(*rea_mips_soft_callback)(in_f12, in_f14, sel)`.

ReaGhidraMipsSoftFloat.java now derives a `__rea_soft_float` prototype from
the program's own default o32 model (encoded, float pentries and
float-consuming rules removed, so byte-order-specific aggregate rules and the
hidden struct-return pointer are kept), installs it as a specification
extension, and assigns it with dynamic storage to every non-thunk function,
external function and function-pointer definition whose formal types use
float or double. Thunks follow their targets. Float types are kept
everywhere, so the integer-retype fallback is removed. The script fails
without writing its report if the derived prototype or any reassigned
function still uses an FPU register.

The policy becomes `o32-soft-float-prototype-v1` with a
{functions, definitions} report. The soft-float fixture adds an indirect
call through a typed pointer; the real-Ghidra lane requires its constants
with no FPU inputs and the struct return's `float scale` in $a1.

* test(ghidra): pin ODDSPREG acceptance for soft-float MIPS ABI records

Review on #1949 suggested requiring flags1 == 0 for soft-float, since MIPS_AFL_FLAGS1_ODDSPREG names CPR1 registers. GCC 5.2 kernel modules, LLVM/Rust firmware and Clang -msoft-float objects all record flags1 = 1 with FP ABI soft-float: it is the MIPS32 o32 toolchain default and selects nothing without CPR1. Keep accepting it, say why at the check, and test that soft-float with ODDSPREG is admitted while any other general flag is refused.

* feat(ghidra): admit relocatable MIPS32r2 ELF objects

Linux MIPS kernel modules (.ko) and other ELF32 o32 MIPS32r2 ET_REL objects
were refused by the Ghidra MIPS lane. Ghidra's ELF loader already places each
allocated section and applies REL relocations; this admits ET_REL alongside
ET_EXEC (ET_DYN and PRX stay refused) under its own support lane,
`elf32-rel-o32-arch32r2-standard-v1`, so executable targets keep theirs.
Relocatable sessions carry limitations: addresses are analysis coordinates,
undefined symbols live in Ghidra's EXTERNAL block, and HI16 relocations report
PARTIAL because Ghidra applies them with their paired LO16.

Verification: new `verify:ghidra:mips-relocatable` real-Ghidra lane builds
-c -G0 objects in both byte orders plus a soft-float -mlong-calls module
variant. GNU readelf supplies sections, symbols and REL entries; every
relocation in an allocated section must encode S + A in the loaded word
(S from Ghidra placement, A from original bytes), with HI16/LO16 checked as
the effective address each LO16 forms, and coverage of a shared HI16, a LO16
carry, external code/data and R_MIPS_32 is asserted. The executable lane,
unit suites pass, and on 30 real .ko files 54,972 relocations matched (93 reference empty sections and are not checkable).

* fix(ghidra): verify every MIPS HI16 and archive-typed soft-float externals

Review feedback on #1950:

- The relocation oracle kept one pending HI16, so a second HI16 before the
  LO16 that resolves both overwrote the first, and unrelated relocations
  cleared it; the earlier site's high half and carry were never compared
  with S + A. Every HI16 now waits for the next LO16 of its symbol, which
  checks all of them; later LO16s reuse those HI16s, and a HI16 left
  unresolved at a section end fails. On 30 real soft-float kernel modules,
  24 contain several HI16s per LO16; all 54,972 placed relocations match.
- External callees with float prototypes: the relocatable fixture now calls
  powf, whose prototype Ghidra's C library archive applies by name. Every
  variant must decompile `powf(1.5,2.5)` without FPU inputs, and the
  soft-float module variant must report that __rea_soft_float covered it
  (with the external step removed it decompiles as `powf(param_1,param_2)`).
  `-fno-builtin` keeps the call from being folded.

Also updates the module variant's expected soft-float policy to
`o32-soft-float-prototype-v1`.

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-12 05:02:55 +08:00
Aurelio BernalandGitHub 5e219de441 feat(ghidra): admit soft-float MIPS32r2 ELF with integer-register float storage (#1949)
* feat(ghidra): admit soft-float MIPS32r2 ELF with integer-register float storage

Soft-float o32 executables (Linux kernel builds, bare-metal firmware) were
refused because their ABI flags record declares no CPR1 and FP ABI 3.
Ghidra's MIPS32 compiler specifications model only hard-float o32, so typed
float/double signatures (DWARF) would be bound to $f12/$f14/$f0 and the
decompiler loses the real dataflow: `return sel ? a : b` decompiled to
`return in_f0;`, and callers passed phantom FPU inputs.

Admit ELF32 ET_EXEC o32 MIPS32r2 targets whose ABI record declares soft-float
with no CPR1, and commit `mips_soft_float_storage: o32-integer-registers-v1`
in their analysis profile only (hard-float profile digests are unchanged).
ReaGhidraMipsSoftFloat.java runs after auto-analysis and, for each function
with a float/double formal type, either keeps the types with the storage
Ghidra's o32 model assigns to a same-size integer (pair alignment, stack
spill), or, for auto-parameters such as hidden struct-return pointers, swaps
float types for same-size integers under dynamic storage. No function is left
on hard-float storage. The report is written last; the provider client
requires it exactly when the profile commits the policy and refuses the
session before any operation otherwise.

Verification: real Ghidra 12.1.4 lane (verify:ghidra:mips) now builds
hard- and soft-float fixtures in both byte orders and checks exact
parameter/return storage through inspect_native_api, caller constants,
snapshot profile and Evidence outcome; test:fast, verify:package and an
installed-tarball soft-float run pass.

* fix(ghidra): model soft-float MIPS as a prototype for every typed callable

Review feedback on #1949: rewriting storage per Function left external
functions and indirect calls through typed function pointers on Ghidra's
hard-float o32 prototype, which still read $f12/$f14/$f0 while the session
reported success. A negative control confirms it: without the change,
`(*rea_mips_soft_callback)(8.5f, 9.5f, sel)` decompiles to
`(*rea_mips_soft_callback)(in_f12, in_f14, sel)`.

ReaGhidraMipsSoftFloat.java now derives a `__rea_soft_float` prototype from
the program's own default o32 model (encoded, float pentries and
float-consuming rules removed, so byte-order-specific aggregate rules and the
hidden struct-return pointer are kept), installs it as a specification
extension, and assigns it with dynamic storage to every non-thunk function,
external function and function-pointer definition whose formal types use
float or double. Thunks follow their targets. Float types are kept
everywhere, so the integer-retype fallback is removed. The script fails
without writing its report if the derived prototype or any reassigned
function still uses an FPU register.

The policy becomes `o32-soft-float-prototype-v1` with a
{functions, definitions} report. The soft-float fixture adds an indirect
call through a typed pointer; the real-Ghidra lane requires its constants
with no FPU inputs and the struct return's `float scale` in $a1.

* test(ghidra): pin ODDSPREG acceptance for soft-float MIPS ABI records

Review on #1949 suggested requiring flags1 == 0 for soft-float, since MIPS_AFL_FLAGS1_ODDSPREG names CPR1 registers. GCC 5.2 kernel modules, LLVM/Rust firmware and Clang -msoft-float objects all record flags1 = 1 with FP ABI soft-float: it is the MIPS32 o32 toolchain default and selects nothing without CPR1. Keep accepting it, say why at the check, and test that soft-float with ODDSPREG is admitted while any other general flag is refused.
2026-10-12 04:54:38 +08:00
morluto 5ba1642a7d test: strengthen archive and resource cleanup assertions
Replace duplicate path-helper checks with real ZIP inventory coverage and replace global memory sampling with bounded-chunk assertions while retaining 64 MiB digest coverage. Await artifact client cleanup, preserve Hopper lease ownership during teardown, and expose typed application failures.
2026-10-12 04:53:27 +08:00
morluto 804c287e44 test: classify filesystem application workflows as boundaries 2026-10-12 04:53:10 +08:00
morluto 918713af37 fix(artifacts): bind directory reads to captured file state
Capture exact filesystem identity and nanosecond timestamps, validate descriptor/path state before and after streaming, and enforce the captured byte count. Bound growing files to their captured size plus one byte using precise positional reads; keep unrepresentable display sizes explicitly unknown.

Reuse the captured-state comparison around Apple assetutil and retain existing reader cleanup ownership. Validation: focused reader and affected consumer suites, full static/architecture checks, and a compiled directory-read probe on Bun 1.3.14 passed. Includes same-size mutation, growth, truncation, cancellation, FIFO replacement, cleanup retry, ZIP identity forgery, ASAR and Mach-O coverage.
2026-10-12 04:45:17 +08:00
morluto a82e37c806 fix(browser): retain module resolver cleanup ownership
Serialize resolution with shutdown, retain the owned browser after close failures, and retry cleanup before another launch. Wire cleanup through the shared service and CLI/MCP lifecycles, preserving primary failures and completed native reports alongside cleanup diagnostics.

Separate the browser resolution workflow from lifecycle ownership. Validation: seven resolver source tests, eleven application tests, MCP shutdown retry, public CLI parity, and full static/architecture checks passed. Real Chromium behavior remains unverified.
2026-10-12 04:44:25 +08:00
morluto c2b56e3e1c test: classify filesystem and process workflows by boundary
Move artifact inventory, application projection, runtime reconciliation, and TODO scanner suites into their real boundary lanes. Extract Hopper process/socket cleanup cases while keeping injected session cleanup cases in composition.

Validation: all 56 focused tests passed; discovery finds all 876 test files exactly once. Test assertions and provider verification scope are unchanged.
2026-10-12 04:44:13 +08:00
morluto dc303a8ee8 test(javascript): classify artifact workflows as boundary tests
Move the six JavaScript application suites that read production artifacts or launch compiled analysis workers out of composition. Focused test planning now prepares their runtime prerequisites instead of treating them as source-only tests.

Validation: all six relocated suites and adjacent artifact/reference suites pass (70 tests across eight files); discovery finds every test exactly once.
2026-10-12 04:33:51 +08:00
morluto 3d83135987 fix(reference): verify symlink identity around target reads
Bracket symlink target observation with the identity captured during enumeration. Report replacements and disappearing links as changed, and keep cancellation and I/O mapping at one owner boundary.

Remove duplicate target-error wrappers and unreachable external-target handling. Validation: reference reader filesystem suite passes, including deterministic replacement during observation.
2026-10-12 04:33:47 +08:00
morluto c42232f566 fix(adb): share actionable provider configuration refusals
Catch binary selection failures at the adapter boundary and share the domain error projection with apktool. Missing and relative adb paths now report capability_unavailable with host configuration guidance in both message and remediation.

Validation: ADB/apktool provider suites and public CLI refusal suites pass. No connected-device behavior changed or verified. Refs #1952.
2026-10-12 04:33:34 +08:00
Minghang ChamlingGitHubfactory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>Kaoru0822
1449e8e051 fix(mcp): provide native evidence paging continuation
Supply schema-validated inspect_analysis_view arguments after completed native function Evidence is recorded and exceeds MCP delivery capacity. Preserve the full canonical result and its provenance. Verify exact source paging, export and following-call usability through real Ghidra stdio MCP.

Fixes #1849

Co-authored-by: Minghang Chamling <133689405+cold-atom@users.noreply.github.com>
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>
2026-10-12 04:26:05 +08:00
7cdb7981c3 fix(apktool): name host requirements in configuration refusals (#1946)
A missing apktool launcher projected the generic "unavailable for the
current target" message and remediation, leaving the actual reason only
in details.reason. A relative REA_APKTOOL_COMMAND escaped as UNKNOWN
because command selection ran before the try that maps configuration
failures.

Resolve the selection inside that try for both execution and
availability, and pass the refusal reason as userMessage, as JADX and
the adapters fixed in #1224 do.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 04:13:23 +08:00
0ae38e1e31 fix(ida): preserve non-x86 call edges and workflow uncertainty (#1906)
* test(ida): expect callee edges from the call graph on non-x86 targets

* fix(ida): read callee edges from the call graph on non-x86 targets

* test(ida): pin address order of call graph additions

* docs(ida): describe the call graph source for non-x86 callees

* test(ida): pin the x86 baseline, the call graph reader and its failure modes

* fix(ida): check the call graph root, scope truncation to the root and degrade without callgraph

* test(ida): expect managed PE off the x86 path, possible-truncation wording and a complete ARM64 traversal

* fix(ida): keep managed PE and x86 reads off the call graph path and qualify truncation

* test(ida): answer only expected leaf roots and assert the requested call graph roots

* test(ida): expect a call graph the producer cannot give consistently to fail the callee read

* fix(ida): fail the callee read when the call graph cannot be obtained consistently

* fix(ida): preserve call edge authority and workflow uncertainty

* fix(ida): preserve explicit root call graph caps

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-12 04:10:22 +08:00
14935e4d47 fix(javascript): preserve package and source-map boundary identity (#1939)
* fix(javascript): preserve bare package specifier suffixes

* fix(javascript): resolve ESM package self references

* fix(javascript): recover retained prefixed source maps

* test(javascript): cover suffixed ESM self references

* fix(javascript): retain legacy ESM package suffix behavior

* fix(javascript): reject legacy ESM directory and extension fallback

* refactor(javascript): consolidate package resolution and workflow coverage

* fix(javascript): report exact ESM package subpath misses

* fix(javascript): compare parsed names for ESM self references

* refactor(javascript): parse bare package requests once

* fix(javascript): derive ESM dependency lookup from package URLs

---------

Co-authored-by: hhang <169027046+xu91102@users.noreply.github.com>
2026-10-12 04:09:17 +08:00
YsopwnableGitHubfactory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>Kaoru0822
85c1d2587a feat(javascript): analyze selected application sources
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>
2026-10-12 04:07:14 +08:00
9878bb7296 feat(ghidra): apply validated analyzer overrides before analysis
Apply caller-selected analyzer opt-outs before Ghidra analysis, reject unknown or ineffective names, and commit raw/header imports to the same analyzer profile. Use supported x86 raw compiler specs and cover the real analyzer/readback and raw workflows.

Adopts the original implementation from #1800 with validated corrections. Refs #1783, #1836.

Co-authored-by: akushonkamen <74654766+akushonkamen@users.noreply.github.com>
Co-authored-by: N0zoM1z0 <161784452+N0zoM1z0@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-12 03:49:31 +08:00
e59db2f5de fix(session): verify retained client liveness on open fast path
Verify retained provider operation health before reusing the same target and profile. Retire failed Hopper clients through existing owned cleanup, preserve healthy reuse and cancellation, and start replacement children lazily on the next query.

Refs #1719. Actual headless Linux Hopper child-death/reopen recovery and 85 related tests passed against the current-main merge tree; Ghidra/IDA liveness and the historical snapshot report remain outside this verification.

Co-authored-by: sx4im <sx4im@users.noreply.github.com>
Co-authored-by: N0zoM1z0 <161784452+N0zoM1z0@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-12 03:16:13 +08:00
Lluís AriñoandGitHub d802304c54 fix(install): describe automatic setup and guard truncated downloads (#1902)
* fix(install): describe automatic setup and guard truncated downloads

The help text said the installer only installs the CLI and that
`rea setup` must be run separately, but the installer starts
`rea setup` interactively whenever a terminal is available. Describe
that behaviour and the --no-setup/--no-prompt opt-out.

Wrap the installer body in `main` and call it on the last line, so a
truncated `curl | bash` download fails to parse instead of executing a
partial script. Behaviour is otherwise unchanged.

Add an installer scenario that runs a copy truncated right after the
npm install line and requires that it prints nothing and never invokes
npm; it fails against the previous script.

Validation: bash -n, shellcheck 0.10.0, installScript boundary tests.

* fix(install): require the closing token before running main

Wrapping the installer in main() kept a truncated download from running
a partial body, but the last line was a bare `main "$@"`. If the piped
download stopped right after `main` (or `main `), bash saw a complete
command at EOF and ran main with no positional parameters. Under the
documented `curl ... | bash -s -- --dry-run` (or --version / --no-setup)
path that silently dropped the caller's flags, so a dry run could resolve
the latest release, run npm, and start setup.

The call now sits in a brace group:

  {
    main "$@"
    exit $?
  }

Bash does not run the group until it has read the closing brace, so
every truncation inside it is a syntax error and nothing executes; a
truncation before the group leaves only function definitions. A comment
in install.sh records why the bare call is not enough.

Validation: a new boundary test pipes install.sh to `bash -s --
--dry-run` truncated at every byte offset from the end of main() to EOF
and asserts that npm and the rea binary are never invoked; offsets
inside the group must exit non-zero with a bash parse error and no
stdout, offsets before it must print nothing, and the complete group
must finish the dry run. Reproduced the original bug by cutting the old
script after `main`: the dry run invoked npm install. `bash -n` and
shellcheck 0.11.0 are clean.

* fix(install): wrap the whole script in the truncation guard

The previous guard only wrapped the final `main "$@"` invocation, so the
preamble streamed on the `curl ... | bash` path before any incomplete
compound command was open. A download cut off right after the bytes
`set` reached EOF with a complete, argument-less `set`, which prints every
shell variable, so inherited tokens could reach stdout.

The brace group now opens on line 2, directly after the shebang, and
closes on the last line, enclosing `set -euo pipefail`, the constants, the
functions and the final `main "$@"` / `exit $?`. Bash must therefore read
the whole file before running anything; any earlier cut is a syntax error
at EOF. `set -euo pipefail` still applies inside the group (checked
manually for `false`, an unbound variable, and a failing function body),
and shellcheck 0.11.0 and `bash -n` are clean.

The truncation test now pipes every prefix of install.sh, from byte 0 to
EOF (about 6,100 cuts, run 16 at a time with a minimal environment that
includes a sentinel variable), into `bash -s -- --dry-run`. Before the
group opens it must exit quietly; inside the group it must fail with a
syntax error; in every case stdout stays empty and neither npm nor rea is
invoked. Only the complete script performs the dry run.
2026-10-12 02:47:31 +08:00
morlutoandGitHub b6651cb99f fix(javascript): retain completed facts through cancellation (#1934) 2026-10-12 02:39:52 +08:00
morluto 0b2aa69531 Merge remote-tracking branch 'origin/main' into codex/pr-1899-remove-duplicate-schema-test 2026-10-12 02:38:57 +08:00
morlutoandGitHub 3b490a743f test(apple): consolidate keyed archive integer verification (#1933) 2026-10-12 02:34:24 +08:00
fb43dd9716 fix(managed): honor metadata ExtraData before table decoding (#1893)
Co-authored-by: LouisChen <3361008+chqcjq@users.noreply.github.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-12 02:28:22 +08:00
YsopwnableGitHubfactory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>Kaoru0822
0485cd3bce fix(javascript): preserve graphs within parent capacity (#1921)
Reserve the next sequential static checkpoint using its protocol size and
existing retained-expansion accounting instead of 80% of the parent budget.
Preserve total/live heap protections and explain parent admission failures
with effective capacity, retention estimates and usable retained facts.

Fixes #1911

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>
2026-10-12 02:17:38 +08:00
morlutoandGitHub 601814ed0e fix(hopper): preserve observed process failures across requests (#1927)
* fix(hopper): preserve observed process failures across requests

* test(hopper): consolidate retained cleanup and recover failed helper fixtures

* docs(hopper): clarify first-use demo prompt and startup recovery
2026-10-12 02:13:53 +08:00
morluto f8513a42dc fix(javascript): keep TypeScript substitution out of runtime paths 2026-10-12 01:41:23 +08:00
a95795c6ed fix(managed): resolve member ownership through pointer tables (#1886)
Co-authored-by: LouisChen <3361008+chqcjq@users.noreply.github.com>
2026-10-12 01:40:48 +08:00
morlutoandGitHub 369cd3dfdc fix(javascript): normalize package URLs before array selection (#1916) 2026-10-12 01:36:42 +08:00
morluto 2976fac30d test(architecture): consolidate import boundary verification 2026-10-12 01:31:33 +08:00
morluto f598bab488 fix(apple): preserve ARM64E X1 architecture identity 2026-10-12 01:31:33 +08:00
morluto bb508134ef fix(setup): verify independently selected skill destinations 2026-10-12 01:31:32 +08:00
morluto 1dfb933e47 fix(javascript): share TypeScript emitted import resolution 2026-10-12 01:31:32 +08:00
morluto 486b56724c fix(browser): compare only observed HTTP response facts 2026-10-12 01:31:23 +08:00
YsopwnableGitHubfactory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>Kaoru0822morluto
9d8e42bdd6 fix(javascript): follow actual receivers in nested intrinsic calls (#1912)
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>
2026-10-12 01:22:26 +08:00
d28b41ea4e feat(javascript): resolve exact package import aliases (#1862)
* feat(javascript): resolve exact package import aliases

Resolve exact #alias specifiers against the importer's enclosing
package.json imports map using the shared condition, array, and null
target selection. Nested packages keep their own maps; missing keys,
explicit nulls, and out-of-scope aliases report a precise reason.
Wildcard, recursive, and external-package import targets remain
unresolved.

* fix(javascript): keep nested import aliases in CLI graphs

Bound nested #alias requires produce application-graph require edges
from the enclosing package. Node reports MODULE_NOT_FOUND when a nested
package.json has no imports field, without inheriting the ancestor map.

* fix(javascript): resolve literal package import keys before path admission

* fix(javascript): preserve import keys and invalid-target fallback

* fix(javascript): preserve unmatched package target arrays

* fix(javascript): retain package target refusal evidence

* test(browser): match real verifier startup budget

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-12 01:17:58 +08:00
Itoje DollarandGitHub e4ac7bbfc2 fix: order remaining outputs independently of host locale (#1867)
* fix: order remaining outputs independently of host locale

String.prototype.localeCompare without a pinned collation follows the
host's ICU default locale, so the same input could be ordered differently
on different machines. 614fb768 moved canonical domain projections to
compareUnicodeCodePoints; provider, application, catalog, and setup
orderings still used locale collation.

Order every remaining source site by Unicode code point, including Mach-O
symbols, firmware extraction paths, ASAR entries (previously pinned to
"en" collation), evidence ID sets, browser and Electron target, script,
and resource inventories, reconstruction obligations, capability and
provider listings, and setup environment details.

The current tool and prompt catalog names order identically under both
comparators, so the catalog identity digest is unchanged.

* fix(artifacts): order ASAR entries by their portable path

@electron/asar lists host-spelled paths, so code-point order over the raw
spelling still differed by host: "a\b" sorts after "a0" on Windows while
"a/b" sorts before it on POSIX. Pair each listing with its portable
archive path once, order by that path, and keep the host spelling for
@electron/asar calls and adapter keys.
2026-10-12 01:10:01 +08:00
Lluís AriñoandGitHub 0b7fc40eee fix(contracts): mark foreign execution and device mutation destructive (#1904)
MCP annotations derived destructiveHint only from mayDiscardData, so tools
that run the analysis target or a caller-selected executable
(capture_process_scenario, observe_native_calls) and tools that change an
attached Android device (install/uninstall/push/start/stop) advertised
destructiveHint: false.

Add explicit executesForeignCode and mutatesDevice effect flags, audit them
across all 170 tool effect records, and derive
destructiveHint = mayDiscardData || executesForeignCode || mutatesDevice.
readOnlyHint semantics are unchanged.

Hopper/Ghidra metadata writers (set_address_name, set_addresses_names,
set_bookmark, set_comment, set_inline_comment, annotate_native_function)
can replace or clear existing analyst names and comments, so they now
declare mayDiscardData as well.

A contract test pins the destructive set and requires every tool whose
description mentions running, launching, executing, starting, installing or
uninstalling to declare one of the new flags or carry a reasoned exception,
so wording and effects cannot silently drift. The binary_session effects
output schema carries the new flags.
2026-10-12 01:09:01 +08:00
akushonkamenandGitHub 7a0140b4aa fix(android): bound inline search Evidence with retained inventory provenance (#1890)
Focused and zero-match search_android_classes responses embedded every
examined class name: JadxSession records each raw list_classes page into
observed calls, those calls ride into Evidence raw_result on the
registration path, and the complete inline Evidence is serialized into
every tool response (issue #1850: 382,435 bytes for one match).

When the server session retains Evidence, record the complete raw-call
record first, then deliver a summary Evidence that keeps the pagination
audit (totals, offsets, page sizes, elided item counts), the unchanged
normalized matches and truthful coverage metadata, and links the
retained complete inventory by Evidence ID. Sessions without retention
keep the complete inline delivery, so complete CLI JSON output is
unchanged and no provenance is discarded.

🤖 Generated with AI assistance (disclosure voluntary per repo policy)
2026-10-12 01:07:22 +08:00
YsopwnableGitHubfactory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>Kaoru0822morluto
9b3e59804d fix(javascript): prove namespace interop before attributing Electron APIs (#1857)
* 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>
2026-10-12 01:06:33 +08:00
Dery FerdikaandGitHub 1769417001 fix(firmware): name missing extractor dependencies in partial extraction (#1879)
Unblob reports a missing external extractor as an
ExtractorDependencyNotFoundReport nested inside a chunk or multi-file
report, and normalizeUnblobReport forwarded that value verbatim into
diagnostics as { input_path, report }. A caller that reached partial
coverage therefore had to decode the raw producer report to learn which
extractor was absent and at which stage, even though the report already
names the dependencies.

Extraction diagnostics now normalize those entries: the named
dependencies are collected from the report and any nested value, the
producing handler is recorded as the stage, and the original report stays
retained for provenance. Entries without a dependency report keep their
previous shape.

Validation: FirmwareReports unit cases cover the chunk-nested and
multi-file-nested dependency reports and the retained raw report;
firmware suite passes; typecheck, oxlint and oxfmt on changed files. Real
Unblob extraction is unverified here because it needs the external
extractor stack.
2026-10-12 01:05:01 +08:00
YsopwnableGitHubfactory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>Kaoru0822
38539a2f4a fix(process): retain owned command cleanup diagnostics (#1907)
Preserve per-member verification failures and sweep uncertainty across
supervisor stop and owned-command failures. Report the observed token
mismatch with its PID coordinates instead of implying PID reuse.

Keep unresolved ownership unsignaled and retain the supervisor for a later
verified stop. Exercise cancellation, timeout and cleanup revalidation with
source-owned process fixtures and cooperative settlement.

Closes #1856

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>
2026-10-12 01:00:08 +08:00